{"id":18597593,"url":"https://github.com/lealre/madr-fastapi","last_synced_at":"2025-07-17T08:38:55.774Z","repository":{"id":253539750,"uuid":"837995213","full_name":"lealre/madr-fastapi","owner":"lealre","description":"Backend API developed using FastAPI for a simplified version of a digital book collection.","archived":false,"fork":false,"pushed_at":"2024-09-17T15:29:21.000Z","size":7521,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T03:38:00.241Z","etag":null,"topics":["alembic","ci","dokcer-compose","fastapi","pydantic","pytest","sqlalchemy"],"latest_commit_sha":null,"homepage":"","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/lealre.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,"publiccode":null,"codemeta":null}},"created_at":"2024-08-04T16:34:41.000Z","updated_at":"2025-01-19T13:11:42.000Z","dependencies_parsed_at":"2024-09-17T19:06:32.554Z","dependency_job_id":"f47f49aa-81eb-4138-be17-9a27d8b0f316","html_url":"https://github.com/lealre/madr-fastapi","commit_stats":null,"previous_names":["lealre/madr-fastapi"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lealre/madr-fastapi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lealre%2Fmadr-fastapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lealre%2Fmadr-fastapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lealre%2Fmadr-fastapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lealre%2Fmadr-fastapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lealre","download_url":"https://codeload.github.com/lealre/madr-fastapi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lealre%2Fmadr-fastapi/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265586019,"owners_count":23792835,"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":["alembic","ci","dokcer-compose","fastapi","pydantic","pytest","sqlalchemy"],"created_at":"2024-11-07T01:28:43.044Z","updated_at":"2025-07-17T08:38:55.750Z","avatar_url":"https://github.com/lealre.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MADR Backend API\n\nThis project consists of a backend API developed using [FastAPI](https://fastapi.tiangolo.com/) for a simplified version of a digital book collection.\n\nIt's called MADR (Mader), a Portuguese acronym for \"Meu Acervo Digital de Romances\" (My Digital Collection of Romances), and it allows user registration and all CRUD operations for both authors and books.\n\nIt is built using the FastAPI framework, with [Pydantic](https://docs.pydantic.dev/latest/) responsible for data validation. It uses a PostgreSQL database, and [SQLAlchemy](https://www.sqlalchemy.org/) is used for ORM, with [Alembic](https://alembic.sqlalchemy.org/en/latest/) handling database migrations during the development process.\n\nJWT (JSON Web Token) is used as a Bearer token for authorization and authentication in API operations, such as creating, updating, and deleting records. The JWT is included in the Authorization header of HTTP requests as a Bearer token.\n\nThe tests have 100% coverage in the `src` folder using [pytest](https://docs.pytest.org/en/stable/) and [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/). It also uses [factory-boy](https://factoryboy.readthedocs.io/en/stable/) to handle massive creation of models, [freezegun](https://github.com/spulec/freezegun) to test token expiration, and [testcontainers](https://testcontainers.com/guides/getting-started-with-testcontainers-for-python/) to build a PostgreSQL instance during tests.\n\nIt is possible to run it locally using Docker Compose, which creates all the tables in PostgreSQL. A CI routine was also implemented using GitHub Actions.\n\n![](media/madr.gif)\n\n\n## Table of Contents\n\n- [How it works](#how-it-works)\n  - [Project Folder Structure](#project-folder-structure)\n- [How to run this project](#how-to-run-this-project)\n- [Further Improvements](#further-improvements)\n\n\n## How it works\n\nThe API has 4 main routes:\n\nThe `/auth` route is used for user login and generates the access token responsible for authorizing and authenticating some of the CRUD operations. It is also possible to refresh the token, which is set to last 60 minutes by default.\n\nThe `/user` route is used to create a user and manage the account. It is possible to delete and update the account, as it verifies if the user has the authorization. \n\nThe `/book` route is responsible for the CRUD operations related to books. To register a book, it requires the `title`, the `year`, and the `author_id`, as it is only possible to register a book with an existing author. For every input, Pydantic coerces the title string by removing trailing spaces, converting all characters to lowercase, and removing duplicate spaces between words to sanitize the inputs in the database. Creating, updating, and deleting books is only possible with authentication.\n\nThe `/author` route is responsible for the CRUD operations related to authors. To register an author, it requires just the `name`, and, as in the book route, Pydantic automatically coerces it by removing trailing spaces, converting all characters to lowercase, and removing duplicate spaces between words to sanitize the inputs in the database. Creating, updating, and deleting authors is only possible with authentication.\n\n\n### Project Folder Structure\n```\n.\n├── Dockerfile\n├── README.md\n├── alembic.ini\n├── docker-compose.yaml\n├── entrypoint.sh\n├── migrations\n│   ├── README\n│   ├── env.py\n│   ├── script.py.mako\n│   └── versions\n│       ├── 5f80c5793a3a_create_users_table.py\n│       ├── 7e20a64d10d4_create_authors_and_book_tables.py\n├── poetry.lock\n├── pyproject.toml\n├── src\n│   ├── app.py\n│   ├── database.py\n│   ├── models.py\n│   ├── routers\n│   │   ├── auth.py\n│   │   ├── author.py\n│   │   ├── books.py\n│   │   └── users.py\n│   ├── schemas\n│   │   ├── authors.py\n│   │   ├── base.py\n│   │   ├── books.py\n│   │   ├── token.py\n│   │   └── users.py\n│   ├── security.py\n│   └── settings.py\n└── tests\n    ├── conftest.py\n    ├── test_app.py\n    ├── test_auth.py\n    ├── test_author.py\n    ├── test_book.py\n    ├── test_security.py\n    └── test_users.py\n```\n## How to run this project\n\nAll the steps here were intended to a `bash` terminal.\n\nThis section shows how to run the project both with Docker or locally. Regardless of the method, start with the following steps:\n\n1 - Clone the repo locally:\n```bash\ngit clone https://github.com/lealre/madr-fastapi.git\n```\n\n2 - Access the project directory:\n```bash\ncd madr-fastapi\n```\n\n### Using Docker\n\n[How to install Docker Compose](https://docs.docker.com/compose/install/)\n\nTo run this project using Docker, it's first necessary to set the environment variables in the `.env` file. An example of what this project uses can be found in the [.env-example](.env-example) file:\n```\nDATABASE_URL=\"postgresql+psycopg://app_user:app_password@madr_database:5432/app_db\"\n\nSECRET_KEY= 'your-secret-key'\nALGORITHM= 'HS256'\nACCESS_TOKEN_EXPIRE_MINUTES= 60\n```\n\nCopy these variables as they are and place them in your `.env` file and this will be enough to configure the project.\n\nOnce the variables in the `.env` file are defined, the following command will build and start the Docker containers with both PostgreSQL and the API running on localhost:\n```bash\ndocker compose up --build -d\n```\n\n`--build` tells Docker Compose to build the images for the services defined in the docker-compose.yml file before starting the containers. If the images already exist and have not changed, Docker Compose will use the existing images. However, if there are changes in the Dockerfiles or in the context of the build (e.g., updated application code), this flag ensures that the images are rebuilt.\n\n`-d` flag stands for \"detached\" mode, which means that Docker Compose will run the containers in the background. This allows you to continue using your terminal for other tasks while the containers run in the background.\n\nYou can access the Swagger documentation by navigating to the `/docs` endpoint in your browser:\n```bash\nhttp://localhost:8000/docs\n```\n\nThis will open the interactive API documentation provided by Swagger.\n\n### Locally\n\nTo run the project locally, the `.env` file is not strictly necessary, as it uses SQLite3 by default. All environment variables are configured to use standard values if the `.env` file is not set.\n\n```python\n# src/settings.py\nclass Settings(BaseSettings):\n    model_config = SettingsConfigDict(\n        env_file='.env', env_file_encoding='utf-8'\n    )\n\n    DATABASE_URL: str = 'sqlite:///database.db'\n    SECRET_KEY: str = 'your-secret-key'\n    ALGORITHM: str = 'HS256'\n    ACCESS_TOKEN_EXPIRE_MINUTES: int = 60\n```\n\nThe project setup uses [`pyenv`](https://github.com/pyenv/pyenv) and [`poetry`](https://python-poetry.org/).\n\nAfter completing steps 1 and 2:\n\n3 - Set the Python version with `pyenv`:\n```bash\npyenv local 3.12.2\n```\n\n4 - Create the virtual environment:\n```bash\npoetry env use 3.12.2\n```\n\n5 - Activate the virtual environment:\n```bash\npoetry shell\n```\n\n6 - Install dependencies:\n```bash\npoetry install\n```\n\n7 - Create the SQLite3 database locally:\n```bash\nalembic upgrade head\n```\n\n8 - Run the server:\n```bash\ntask run\n```\n\nAfter these steps, you can access the Swagger documentation by navigating to the `/docs` endpoint in your browser:\n```bash\nhttp://localhost:8000/docs\n```\n\nThis will open the interactive API documentation provided by Swagger.\n\n**NOTES**\n\nTo run the tests, it is necessary to have Docker installed, as `testcontainers` builds a PostgreSQL instance for use.\n```bash\ntask test\n```\n\nBefore starting the tests, [Ruff](https://docs.astral.sh/ruff/) will detect format errors based on the points below:\n\n- Import-related checks\n- Flake8 style checks\n- Error-related checks\n- Warning-related checks\n- Pylint-related checks\n- Type-related checks, similar to Pylint\n\nTo automatically format the project based on these criteria, use:\n```bash\ntask format\n```\n\nAfter running the tests, the coverage report is generated as an HTML file in `htmlcov/index.html`.\n\n## Further Improvements\n\n- Change the API to operate asynchronously.\n- Create a simple front-end for user interaction.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flealre%2Fmadr-fastapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flealre%2Fmadr-fastapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flealre%2Fmadr-fastapi/lists"}