diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..42e3583 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,2 @@ +#!/bin/bash +fdr_app app run diff --git a/k8s/base/deployment.yaml b/k8s/base/deployment.yaml index ad8248c..842b1d8 100644 --- a/k8s/base/deployment.yaml +++ b/k8s/base/deployment.yaml @@ -10,6 +10,8 @@ metadata: name: fastapi-dynamic-response namespace: fastapi-dynamic-response spec: + selector: + app: fastapi-dynamic-response ports: - name: "8000" port: 8000 @@ -20,6 +22,12 @@ kind: Deployment metadata: name: fastapi-dynamic-response namespace: fastapi-dynamic-response + labels: + app: fastapi-dynamic-response + version: "0.0.3" + owner: "waylonwalker" + annotations: + email: "fastapi-dynamic-response@fastapi-dynamic-response.com" spec: replicas: 3 selector: @@ -35,17 +43,16 @@ spec: labels: app: fastapi-dynamic-response spec: - # affinity: - # podAntiAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # - labelSelector: - # matchLabels: - # app: fastapi-dynamic-response - # topologyKey: "kubernetes.io/hostname" + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app: fastapi-dynamic-response + topologyKey: "kubernetes.io/hostname" containers: - image: docker.io/waylonwalker/fastapi-dynamic-response:0.0.2 name: fastapi-dynamic-response - args: ["./.venv/bin/uvicorn", "src.fastapi_dynamic_response.main:app", "--host", "0.0.0.0", "--port", "8000"] ports: - containerPort: 8000 protocol: TCP @@ -90,8 +97,9 @@ metadata: name: fastapi-dynamic-response namespace: fastapi-dynamic-response spec: + ingressClassName: nginx rules: - - host: app.fokais.com + - host: fastapi-dynamic-response.waylonwalker.com http: paths: - backend: diff --git a/kind-config.yaml b/kind-config.yaml new file mode 100644 index 0000000..cc3f43d --- /dev/null +++ b/kind-config.yaml @@ -0,0 +1,12 @@ +# kind-config.yaml +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + extraPortMappings: + - containerPort: 30080 + hostPort: 30080 + protocol: TCP + extraMounts: + - hostPath: ./sqlite-data + containerPath: /sqlite-data diff --git a/kube-linter b/kube-linter new file mode 100644 index 0000000..fefe9a2 Binary files /dev/null and b/kube-linter differ diff --git a/kube-score b/kube-score new file mode 100644 index 0000000..91aa883 Binary files /dev/null and b/kube-score differ diff --git a/otel-collector-config.yaml b/otel-collector-config.yaml new file mode 100644 index 0000000..098628d --- /dev/null +++ b/otel-collector-config.yaml @@ -0,0 +1,18 @@ +receivers: + otlp: + protocols: + grpc: + http: +exporters: + otlp: + endpoint: "0.0.0.0:14250" + tls: + insecure: true +processors: + batch: +service: + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [otlp] diff --git a/pyproject.toml b/pyproject.toml index d34cc34..ad5b93e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ dependencies = [ "rich>=13.9.2", "selenium>=4.25.0", "structlog>=24.4.0", + "typer>=0.12.5", "uvicorn>=0.31.1", "weasyprint>=61.2", ] @@ -46,6 +47,9 @@ Documentation = "https://github.com/U.N. Owen/fastapi-dynamic-response#readme" Issues = "https://github.com/U.N. Owen/fastapi-dynamic-response/issues" Source = "https://github.com/U.N. Owen/fastapi-dynamic-response" +[project.scripts] +fdr_app = "fastapi_dynamic_response.cli.cli:app" + [tool.hatch.version] path = "src/fastapi_dynamic_response/__about__.py" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2b01b01 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,131 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o requirements.txt +annotated-types==0.7.0 + # via pydantic +anyio==4.6.2.post1 + # via starlette +attrs==24.2.0 + # via + # outcome + # trio +brotli==1.1.0 + # via fonttools +certifi==2024.8.30 + # via selenium +cffi==1.17.1 + # via weasyprint +click==8.1.7 + # via uvicorn +cssselect2==0.7.0 + # via weasyprint +fastapi==0.115.3 + # via fastapi-dynamic-response (pyproject.toml) +fonttools==4.54.1 + # via weasyprint +h11==0.14.0 + # via + # uvicorn + # wsproto +html2text==2024.2.26 + # via fastapi-dynamic-response (pyproject.toml) +html5lib==1.1 + # via weasyprint +idna==3.10 + # via + # anyio + # trio +itsdangerous==2.2.0 + # via fastapi-dynamic-response (pyproject.toml) +jinja2==3.1.4 + # via fastapi-dynamic-response (pyproject.toml) +levenshtein==0.26.0 + # via python-levenshtein +markdown==3.7 + # via fastapi-dynamic-response (pyproject.toml) +markdown-it-py==3.0.0 + # via rich +markupsafe==3.0.2 + # via jinja2 +mdurl==0.1.2 + # via markdown-it-py +outcome==1.3.0.post0 + # via trio +pillow==11.0.0 + # via + # fastapi-dynamic-response (pyproject.toml) + # weasyprint +pycparser==2.22 + # via cffi +pydantic==2.9.2 + # via + # fastapi + # pydantic-settings +pydantic-core==2.23.4 + # via pydantic +pydantic-settings==2.6.0 + # via fastapi-dynamic-response (pyproject.toml) +pydyf==0.8.0 + # via + # fastapi-dynamic-response (pyproject.toml) + # weasyprint +pygments==2.18.0 + # via rich +pyphen==0.16.0 + # via weasyprint +pysocks==1.7.1 + # via urllib3 +python-dotenv==1.0.1 + # via pydantic-settings +python-levenshtein==0.26.0 + # via fastapi-dynamic-response (pyproject.toml) +rapidfuzz==3.10.0 + # via levenshtein +rich==13.9.3 + # via fastapi-dynamic-response (pyproject.toml) +selenium==4.25.0 + # via fastapi-dynamic-response (pyproject.toml) +six==1.16.0 + # via html5lib +sniffio==1.3.1 + # via + # anyio + # trio +sortedcontainers==2.4.0 + # via trio +starlette==0.41.0 + # via fastapi +structlog==24.4.0 + # via fastapi-dynamic-response (pyproject.toml) +tinycss2==1.3.0 + # via + # cssselect2 + # weasyprint +trio==0.27.0 + # via + # selenium + # trio-websocket +trio-websocket==0.11.1 + # via selenium +typing-extensions==4.12.2 + # via + # fastapi + # pydantic + # pydantic-core + # selenium +urllib3==2.2.3 + # via selenium +uvicorn==0.32.0 + # via fastapi-dynamic-response (pyproject.toml) +weasyprint==61.2 + # via fastapi-dynamic-response (pyproject.toml) +webencodings==0.5.1 + # via + # cssselect2 + # html5lib + # tinycss2 +websocket-client==1.8.0 + # via selenium +wsproto==1.2.0 + # via trio-websocket +zopfli==0.2.3.post1 + # via fonttools diff --git a/sitemap.html b/sitemap.html new file mode 100644 index 0000000..189bbf6 --- /dev/null +++ b/sitemap.html @@ -0,0 +1,612 @@ + + + + + + Sitemap + + + + + +
+
+ FastAPI Dynamic Response + +
+
+ +
+ +

Sitemap

+ + +
  • /livez
  • + +
  • /readyz
  • + +
  • /healthz
  • + +
  • /example
  • + +
  • /another-example
  • + +
  • /message
  • + +
  • /static
  • + +
  • /sitemap
  • + + +
    + + + + diff --git a/sitemap.pdf b/sitemap.pdf new file mode 100644 index 0000000..e69de29 diff --git a/sitemap.png b/sitemap.png new file mode 100644 index 0000000..cc770d5 Binary files /dev/null and b/sitemap.png differ diff --git a/src/fastapi_dynamic_response/cli/.null-ls_858127_app.py b/src/fastapi_dynamic_response/cli/.null-ls_858127_app.py new file mode 100644 index 0000000..71e9e28 --- /dev/null +++ b/src/fastapi_dynamic_response/cli/.null-ls_858127_app.py @@ -0,0 +1,26 @@ +import typer +import uvicorn + +from fastapi_dynamic_response import settings + + +app_app = typer.Typer() + + +@app_app.callback() +def app(): + "model cli" + + +@app_app.command() +def run( + env: str = typer.Option( + "local", + help="the environment to use", + ), +): + uvicorn.run(**settings.api_server.dict()) + + +if __name__ == "__main__": + app_app() diff --git a/src/fastapi_dynamic_response/cli/app.py b/src/fastapi_dynamic_response/cli/app.py new file mode 100644 index 0000000..417d622 --- /dev/null +++ b/src/fastapi_dynamic_response/cli/app.py @@ -0,0 +1,26 @@ +import typer +import uvicorn + +from fastapi_dynamic_response.settings import settings + + +app_app = typer.Typer() + + +@app_app.callback() +def app(): + "model cli" + + +@app_app.command() +def run( + env: str = typer.Option( + "local", + help="the environment to use", + ), +): + uvicorn.run(**settings.api_server.dict()) + + +if __name__ == "__main__": + app_app() diff --git a/src/fastapi_dynamic_response/cli/cli.py b/src/fastapi_dynamic_response/cli/cli.py new file mode 100644 index 0000000..27be712 --- /dev/null +++ b/src/fastapi_dynamic_response/cli/cli.py @@ -0,0 +1,7 @@ +import typer + +from fastapi_dynamic_response.cli.app import app_app + +app = typer.Typer() + +app.add_typer(app_app, name="app") diff --git a/src/fastapi_dynamic_response/settings.py b/src/fastapi_dynamic_response/settings.py index 93d8680..ff41d04 100644 --- a/src/fastapi_dynamic_response/settings.py +++ b/src/fastapi_dynamic_response/settings.py @@ -1,10 +1,22 @@ -from pydantic import model_validator +from pydantic import BaseModel, model_validator from pydantic_settings import BaseSettings +class ApiServer(BaseModel): + app: str = "fastapi_dynamic_response.main:app" + port: int = 8000 + reload: bool = True + log_level: str = "info" + host: str = "0.0.0.0" + workers: int = 1 + forwarded_allow_ips: str = "*" + proxy_headers: bool = True + + class Settings(BaseSettings): ENV: str = "local" DEBUG: bool = False + api_server: ApiServer = ApiServer() class Config: env_file = "config.env" diff --git a/uv.lock b/uv.lock index c2c3fa8..11c4369 100644 --- a/uv.lock +++ b/uv.lock @@ -335,6 +335,7 @@ dependencies = [ { name = "rich" }, { name = "selenium" }, { name = "structlog" }, + { name = "typer" }, { name = "uvicorn" }, { name = "weasyprint" }, ] @@ -353,6 +354,7 @@ requires-dist = [ { name = "rich", specifier = ">=13.9.2" }, { name = "selenium", specifier = ">=4.25.0" }, { name = "structlog", specifier = ">=24.4.0" }, + { name = "typer", specifier = ">=0.12.5" }, { name = "uvicorn", specifier = ">=0.31.1" }, { name = "weasyprint", specifier = ">=61.2" }, ] @@ -1117,6 +1119,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/aa/85/fa44f23dd5d5066a72f7c4304cce4b5ff9a6e7fd92431a48b2c63fbf63ec/selenium-4.25.0-py3-none-any.whl", hash = "sha256:3798d2d12b4a570bc5790163ba57fef10b2afee958bf1d80f2a3cf07c4141f33", size = 9693127 }, ] +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, +] + [[package]] name = "six" version = "1.16.0" @@ -1210,6 +1221,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/48/be/a9ae5f50cad5b6f85bd2574c2c923730098530096e170c1ce7452394d7aa/trio_websocket-0.11.1-py3-none-any.whl", hash = "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638", size = 17408 }, ] +[[package]] +name = "typer" +version = "0.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c5/58/a79003b91ac2c6890fc5d90145c662fd5771c6f11447f116b63300436bc9/typer-0.12.5.tar.gz", hash = "sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722", size = 98953 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/2b/886d13e742e514f704c33c4caa7df0f3b89e5a25ef8db02aa9ca3d9535d5/typer-0.12.5-py3-none-any.whl", hash = "sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b", size = 47288 }, +] + [[package]] name = "typing-extensions" version = "4.12.2"