Skip to content

Latest commit

 

History

History
54 lines (42 loc) · 4.95 KB

ARCHITECTURE.md

File metadata and controls

54 lines (42 loc) · 4.95 KB

Architecture

codecov

This document is less about software architecture per-se, but rather about technical details deemed out-of-scope for the README.

Features

  • fully async using aiohttp and gidgethub

  • based around the fantastic rich library for terminal output

  • structural pattern matching, introduced in Python 3.10:

    • initially used for fun, but not because any use cases were substantially easier using it,
    • then dropped on 2022-07-16 since Python 3.10 is unsupported by AWS lambda,
    • but since switched to Google Cloud Run, which is based on regular OCI containers (see Dockerfile), hence resolving the hell that is dependency management in serverless environments.

    Fully serverless is still interesting since it's such a fitting use-case. The best solution seems to vendor all dependencies, instead of trying our luck with the serverless provider reading and correctly installing the dependencies for us (which often requires a requirements.txt instead of a poetry.lock or similar).

    However, since this project treats self-hosting as a first-class citizen, going full serverless and abandoning providing Docker images entirely isn't an option anyway. Hosting serverlessly would be a split, required maintenance of two hosting options instead of just building one image and calling it a day.

  • fully typed using Python type hints, verified through mypy --strict (with additional, even stricter settings)

  • structural logging with a JSON event stream output

  • pydantic for fully typed data validation (e.g., for APIs), facilitated by automatic pydantic model generation from e.g. OpenAPI specs like GitHub's or JSON Resume's, allowing full support from mypy and the IDE when using said validated data

  • 12 Factor App conformance:

    1. Codebase: GitHub-hosted repo
    2. Dependencies: taken care of by uv
    3. Config: the app is configured using environment variables. Although problematic, this approach was chosen for its simplicity
    4. Backing Services: not applicable for this very simple app
    5. Build, release, run: handled through GitHub releases via git tags and release-please
    6. Processes: this simple app is stateless in and of itself
    7. Port binding: the aiohttp server part of the app acts as a standalone web server, exposing a port. That port can then be serviced by any arbitrary reverse proxy
    8. Concurrency: covered by async functionality (in a single process and thread). This being a stateless app, horizontal scaling through additional processes is trivial (e.g. via serverless hosting), although vertical scaling will likely suffice indefinitely
    9. Disposability: aiohttp handles SIGTERM gracefully
    10. Dev/prod parity: trivial to do for this simple app. If running on Windows, mind this issue. If running on Linux, no special precautions are necessary
    11. Logs: structured JSON logs are written directly to stdout
    12. Admin processes: not applicable either

Similar solutions

Very hard to find any, and even hard to google. For example, bash curl curriculum vitae will prompt Google to interpret curriculum vitae == resume, which isn't wrong but curl resume is an entirely unrelated query (concerned with resuming halted downloads and such).

Similar projects:

Related, but 'fake' hits: