Skip to content

Commit

Permalink
checkpoint-kai-1700369645
Browse files Browse the repository at this point in the history
  • Loading branch information
coilysiren committed Nov 19, 2023
1 parent 858ed0b commit 46751e8
Show file tree
Hide file tree
Showing 17 changed files with 165 additions and 35 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
.terraform
.mypy_cache
.coveragerc
.coverage

coverage_report
terraform.tfstate
terraform.tfstate.backup
venv
__pycache__
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"pylint.args": ["--rcfile=pyproject.toml"]
}
8 changes: 3 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ FROM python:3.11 as base

EXPOSE 8080

WORKDIR /usr/app
COPY ./src/* /usr/app

ENV PYTHONUNBUFFERED 1
ENV PYTHONPATH "$(pwd):$PYTHONPATH"
RUN mkdir -p /usr/app/src
WORKDIR /usr/app/src
COPY ./src /usr/app/src

EXPOSE 8080
RUN pip install -r requirements.txt
Expand Down
88 changes: 83 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,93 @@
# Kubernetes GCP Python Starter App

## Install

OSX system requirements:

- pyenv - `brew install pyenv`
- docker - `brew install --cask docker`
- httpie - `brew install httpie`

These are listed individually to avoid polluting your global installation unknowingly.

After installing the above, you can run the following command to setup your local dependencies. It sets up on a virtualenv for you.

```bash
make install
```

You should run this command every time your python dependencies change.

## Development

The project runs the application code inside of a pipenv virtualenv, but requires some amount of configuration for your global python installation.
The development workflow involves using one or two terminal windows, depending on the type of work you are doing.

All of our python commands use `inv` / `invoke` eg [`pyinvoke`](https://www.pyinvoke.org/), a makefile replacement written in python. This allows us a degree of flexibility and comfort with our dev time tooling.

For the context of this API, all of the work you do should be able to be covered by 100% unit test coverage. Also, the primary mechanism of testing development work should be [`pytest-watch`](https://pypi.org/project/pytest-watch/).

When testing via a more "hands on" approach, we use a combination of `flask run` (via invoke) and `httpie`. `httpie` is used as a UX friendly alternative to `curl`, although we do utilize `curl` to confirm that we are aligned with the project spec.

### Pytest

```bash
$ source ./venv/bin/activate
$ invoke test
```

### Pytest Watch

```bash
$ source ./venv/bin/activate
$ invoke test-watch
```

This terminal will now watch for changes, and automatically re-run the tests when it finds them.

The majority of our tests were written in this way.

### httpie

```bash
# first terminal
$ source ./venv/bin/activate
$ invoke serve
```

```bash
# second terminal
$ http :8080/api/healthcheck
> HTTP/1.1 200 OK
```

### curl

```bash
# inside ~/.zshrc, or similar
export PIPENV_VENV_IN_PROJECT=1
# first terminal
$ source ./venv/bin/activate
$ invoke serve
```

```bash
# run once, or whenever you are working on a new machine
pip install invoke pipenv pyyaml
# second terminal
$ curl http://0.0.0.0:8080/api/healthcheck
> OK
```

### Updating Dependencies

You can update dependencies via

```bash
pipenv install < some package >
make install upgrade install
```

## Deployment

This deployment command assumes you are locally authenticated to both gcloud and kubectl. Directions on how to do so are out of scope for this documentation. Please consult your team's local deployment tooling and instructions!

```bash
source ./venv/bin/activate
invoke deploy # see tasks.py for source code
```
File renamed without changes.
Binary file removed app/.coverage
Binary file not shown.
4 changes: 1 addition & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ x-app: &app
context: .
target: dev
volumes:
- ./app:/usr/app
- ./coverage_report:/usr/app/coverage_report
- ./.coveragerc:/usr/app/.coveragerc
- ./src:/usr/app/src
ports:
- '8080:8080'
environment:
Expand Down
3 changes: 3 additions & 0 deletions infrastructure/main.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/client_config
data "google_client_config" "default" {}

# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account
resource "google_service_account" "gke" {
account_id = "gke-test-1"
Expand Down
11 changes: 5 additions & 6 deletions infrastructure/state.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
terraform {
backend "gcs" {
bucket = "coilysiren-zapier-interview-tfstate-0"
bucket = "coilysiren-k8s-gpc-tfstate-0"
prefix = "terraform/state"
}
}
Expand All @@ -11,17 +11,16 @@ provider "google" {
region = "us-central1"
}

# https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/client_config
data "google_client_config" "default" {}

# https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project
data "google_project" "default" {}

# this bucket was created manually, and then imported into terraform afterwards
# `terraform import google_storage_bucket.default coilysiren-zapier-interview-tfstate-0`
#
# $ terraform import google_storage_bucket.default coilysiren-k8s-gpc-tfstate-0
#
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket
resource "google_storage_bucket" "default" {
name = "coilysiren-zapier-interview-tfstate-0"
name = "coilysiren-k8s-gpc-tfstate-0"
location = "US-CENTRAL1"
force_destroy = true
project = data.google_project.default.project_id
Expand Down
13 changes: 13 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[tool.pylint.main]
fail-under = 100
suggestion-mode = true

[tool.pylint.messages-control]
disable = [
"missing-module-docstring",
"missing-function-docstring",
"missing-class-docstring",
"broad-exception-raised",
"broad-exception-caught",
]
max-line-length = 100
13 changes: 0 additions & 13 deletions src/app/main.py

This file was deleted.

Empty file added src/main/__init__.py
Empty file.
14 changes: 14 additions & 0 deletions src/main/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import flask


blueprint = flask.Blueprint("api", __name__, url_prefix="/api")


@blueprint.route("/healthcheck")
def healthcheck():
"""used for debugging purposes"""
return flask.jsonify(
{
"status": "ok",
}
)
10 changes: 10 additions & 0 deletions src/main/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import flask
import src.main.api


def create_app():
"""Create and configure an instance of the Flask application."""
app = flask.Flask(__name__)
app.register_blueprint(src.main.api.blueprint)

return app
7 changes: 7 additions & 0 deletions src/main/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import src.main.app

app = src.main.app.create_app()

if __name__ == "__main__":
# Run a debug server.
app.run(debug=True, host="0.0.0.0")
3 changes: 0 additions & 3 deletions src/test/test.py

This file was deleted.

17 changes: 17 additions & 0 deletions src/test/test_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import src.main.app


app = src.main.app.create_app()
app.config["TESTING"] = True
client = app.test_client()


def test_true():
"""When all seems lost, the true test will always be there for you."""
assert True


def test_healthcheck():
response = client.get("/api/healthcheck")
assert response.status_code == 200
assert response.json == {"status": "ok"}

0 comments on commit 46751e8

Please sign in to comment.