{"id":16085729,"url":"https://github.com/febus982/auth-study","last_synced_at":"2025-04-05T13:42:21.437Z","repository":{"id":225500131,"uuid":"762643720","full_name":"febus982/auth-study","owner":"febus982","description":null,"archived":false,"fork":false,"pushed_at":"2024-03-02T12:28:28.000Z","size":146,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-11T09:50:07.038Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/febus982.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-02-24T09:33:36.000Z","updated_at":"2024-03-02T12:28:10.000Z","dependencies_parsed_at":"2024-03-02T14:51:13.339Z","dependency_job_id":null,"html_url":"https://github.com/febus982/auth-study","commit_stats":null,"previous_names":["febus982/auth-study"],"tags_count":0,"template":false,"template_full_name":"febus982/bootstrap-python-fastapi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/febus982%2Fauth-study","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/febus982%2Fauth-study/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/febus982%2Fauth-study/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/febus982%2Fauth-study/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/febus982","download_url":"https://codeload.github.com/febus982/auth-study/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247345713,"owners_count":20924098,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-09T13:09:10.507Z","updated_at":"2025-04-05T13:42:21.411Z","avatar_url":"https://github.com/febus982.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bootstrap python service\n[![CI Pipeline](https://github.com/febus982/bootstrap-python-fastapi/actions/workflows/ci-pipeline.yml/badge.svg)](https://github.com/febus982/bootstrap-python-fastapi/actions/workflows/ci-pipeline.yml)\n[![Python tests](https://github.com/febus982/bootstrap-python-fastapi/actions/workflows/python-tests.yml/badge.svg?branch=main)](https://github.com/febus982/bootstrap-python-fastapi/actions/workflows/python-tests.yml)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/a2ab183e64778e21ae14/test_coverage)](https://codeclimate.com/github/febus982/bootstrap-python-fastapi/test_coverage)\n[![Maintainability](https://api.codeclimate.com/v1/badges/a2ab183e64778e21ae14/maintainability)](https://codeclimate.com/github/febus982/bootstrap-python-fastapi/maintainability)\n\n[![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json)](https://github.com/charliermarsh/ruff)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)\n\nThis is an example implementation of a python application applying\nconcepts from [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)\nand [SOLID principles](https://en.wikipedia.org/wiki/SOLID).\n\n* The repository classes are isolated behind interfaces, enforcing the [Interface Segregation principle](https://en.wikipedia.org/wiki/Interface_segregation_principle) \n  and the [Inversion of Control](https://en.wikipedia.org/wiki/Inversion_of_control) design pattern\n* The application frameworks are decoupled from the domain logic\n* The storage layer is decoupled from the domain logic\n\nThis template provides out of the box some commonly used functionalities:\n\n* API Documentation using [FastAPI](https://fastapi.tiangolo.com/)\n* Async tasks execution using [Celery](https://docs.celeryq.dev/en/stable/index.html)\n* Repository pattern for databases using [SQLAlchemy](https://www.sqlalchemy.org/) and [SQLAlchemy bind manager](https://febus982.github.io/sqlalchemy-bind-manager/stable/)\n* Database migrations using [Alembic](https://alembic.sqlalchemy.org/en/latest/) (configured supporting both sync and async SQLAlchemy engines)\n* [TODO] Producer and consumer to emit and consume events using [CloudEvents](https://cloudevents.io/) format on [Confluent Kafka](https://docs.confluent.io/kafka-clients/python/current/overview.html)\n\n## Documentation\n\nThe detailed documentation is available:\n\n* Online on [GitHub pages](https://febus982.github.io/bootstrap-python-fastapi/)\n* Offline by running `make docs` after installing dependencies with `make dev-dependencies`\n\n## How to use\n\nCreate your GitHub repository using this template (The big green `Use this template` button).\nOptionally tweak name and authors in the `pyproject.toml` file, however the metadata\nare not used when building the application, nor are referenced anywhere in the code.\n\nUsing Docker:\n\n* `make containers`: Build containers\n* `docker compose run --rm dev make migrate`: Run database migrations\n* `docker compose up dev`: Run HTTP application with hot reload\n* `docker compose up celery-worker`: Run the celery worker\n* `docker compose run --rm test`: Run test suite\n\nLocally:\n\n* `make migrate`: Run database migrations\n* `make install-dependencies`: Install requirements\n* `make dev-dependencies`: Install dev requirements\n* `make update-dependencies`: Updates requirements\n* `make migrate`: Run database migrations\n* `make dev`: Run HTTP application with hot reload\n* `make test`: Run test suite\n\n## Other commands for development\n\n* `make check`: Run tests, code style and lint checks\n* `make fix`: Run tests, code style and lint checks with automatic fixes (where possible)\n\n## Multistage dockerfile configuration\n\nPython docker image tend to become large after installing the application requirements\n(the slim base is ~150 MB uncompressed), therefore it's important to spend efforts\nto minimise the image size, even if it produces a slightly more complex multistage\nDockerfile.\n\nThe following setup makes sure the production image will keep to a minimal size (\"only\" 390MB):\n * 150MB base image\n * 165MB python installed dependencies\n * 73MB poetry + updated pip\n\nUsing the following pipeline the \"test\" image is instead ~850MB, more than 400MB that would\nend up as a cost in traffic on each image pull.\n\n![](docs/puml/docker-container.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffebus982%2Fauth-study","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffebus982%2Fauth-study","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffebus982%2Fauth-study/lists"}