{"id":26878048,"url":"https://github.com/martinp95/flask_api_chinook","last_synced_at":"2026-04-28T08:33:16.176Z","repository":{"id":284830623,"uuid":"956199671","full_name":"martinp95/flask_api_chinook","owner":"martinp95","description":"A production-ready RESTful API built with Flask, SQLAlchemy, and Marshmallow, based on the classic Chinook database. It exposes endpoints to browse artists, albums with support for pagination, nested resources, summaries, and OpenAPI documentation","archived":false,"fork":false,"pushed_at":"2025-03-27T22:21:54.000Z","size":347,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T22:33:27.460Z","etag":null,"topics":["flask","flask-restful","flask-sqlalchemy","marshmallow","sqlalchemy","sqlite3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martinp95.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2025-03-27T21:26:44.000Z","updated_at":"2025-03-27T22:21:57.000Z","dependencies_parsed_at":"2025-03-27T22:33:29.917Z","dependency_job_id":"2e9b078f-5148-405b-845d-3da2f68e6ccd","html_url":"https://github.com/martinp95/flask_api_chinook","commit_stats":null,"previous_names":["martinp95/flask_api_chinook"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinp95%2Fflask_api_chinook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinp95%2Fflask_api_chinook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinp95%2Fflask_api_chinook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinp95%2Fflask_api_chinook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martinp95","download_url":"https://codeload.github.com/martinp95/flask_api_chinook/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246465257,"owners_count":20781919,"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":["flask","flask-restful","flask-sqlalchemy","marshmallow","sqlalchemy","sqlite3"],"created_at":"2025-03-31T12:18:59.180Z","updated_at":"2026-04-28T08:33:11.147Z","avatar_url":"https://github.com/martinp95.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎵 Chinook REST API\n\n![Tests](https://github.com/martinp95/flask_api_chinook/actions/workflows/ci.yml/badge.svg)\n[![codecov](https://codecov.io/gh/martinp95/flask_api_chinook/graph/badge.svg?token=ZF2FMOBITA)](https://codecov.io/gh/martinp95/flask_api_chinook)\n![Python](https://img.shields.io/badge/python-3.12-blue.svg)\n[![License](https://img.shields.io/github/license/martinp95/flask_api_chinook.svg)](https://github.com/martinp95/flask_api_chinook/blob/main/LICENSE)\n\nA production-ready RESTful API built with **Flask**, **SQLAlchemy**, and **Marshmallow**, based on the classic Chinook database. It exposes endpoints to browse artists, albums, and tracks with support for pagination, nested resources, summaries, and OpenAPI documentation.\n\n---\n\n## 🚀 Features\n\n- ✅ RESTful endpoints (artists, albums, tracks)\n- ✅ SQLAlchemy ORM with SQLite (Chinook schema)\n- ✅ Marshmallow for schema validation and serialization\n- ✅ Swagger UI (via Flasgger) available at `/apidocs/`\n- ✅ Centralized error handling (404, 500, etc.)\n- ✅ Clean service-oriented architecture\n- ✅ Auto-formatted with `black`\n- ✅ 100% unit test coverage with `pytest`\n- ✅ Configurable via environment (`FLASK_CONFIG`)\n- ✅ Dockerized and compatible with `Makefile`\n\n---\n\n## 📁 Project Structure\n\n```\nflask_api_chinook/\n├── app/\n│   ├── __init__.py            # Application factory\n│   ├── run.py                 # Entrypoint for running the app\n│   ├── common/\n│   │   ├── config.py          # Configuration classes\n│   │   ├── logging_config.py  # Logging setup\n│   │   └── errors.py          # Centralized error handling\n│   ├── models/                # SQLAlchemy models\n│   │   └── models.py\n│   ├── schemas/               # Marshmallow schemas\n│   │   ├── albums_schema.py\n│   │   ├── albums_summary_schema.py\n│   │   ├── artists_schema.py\n│   │   └── tracks_schema.py\n│   ├── services/              # Business logic layer\n│   │   └── services.py\n│   └── routes/                # Flask blueprints\n│       ├── __init__.py\n│       ├── artists.py\n│       └── albums.py\n├── instance/\n│   └── chinook.db             # SQLite database (preloaded)\n├── tests/                     # Pytest-based tests\n│   ├── test_albums.py\n│   ├── test_artists.py\n│   ├── test_errors.py\n│   └── conftest.py\n├── docker-compose.yml\n├── Dockerfile\n├── Makefile\n├── requirements.txt\n├── requirements-dev.txt\n├── pytest.ini\n└── README.md\n```\n\n---\n\n## 🔧 Setup \u0026 Usage\n\n### 🔸 1. Clone the repository\n\n```bash\ngit clone https://github.com/martinp95/flask_api_chinook.git\ncd flask_api_chinook\n```\n\n### 🔸 2. Start the application with Docker\n\n```bash\nmake up\n```\n\nThis will build and run the app using `docker-compose`.  \nWhen it's running:\n\n- ✅ API Base: [http://localhost:5000/artists](http://localhost:5000/artists)\n- ✅ Swagger UI: [http://localhost:5000/apidocs](http://localhost:5000/apidocs)\n\n---\n\n## 📌 Environment Configuration\n\nSet the Flask configuration using the `FLASK_CONFIG` env var:\n\n| Mode         | Config Path                              |\n|--------------|------------------------------------------|\n| Development  | `app.common.config.DevelopmentConfig`    |\n| Testing      | `app.common.config.TestingConfig`        |\n| Production   | `app.common.config.ProductionConfig`     |\n\nDefault is Development if not set.\n\n---\n\n## 📚 API Endpoints (Sample)\n\n### 🎤 GET `/artists?page=1\u0026per_page=2`\n\nReturns paginated list of artists:\n\n```json\n{\n  \"artists\": [\n    { \"ArtistId\": 1, \"Name\": \"AC/DC\" },\n    { \"ArtistId\": 2, \"Name\": \"Accept\" }\n  ],\n  \"page\": 1,\n  \"per_page\": 2,\n  \"total\": 275\n}\n```\n\n---\n\n### 💿 GET `/artists/\u003cartist_id\u003e/albums`\n\nReturns albums by artist:\n\n```json\n[\n  { \"AlbumId\": 1, \"Title\": \"For Those About To Rock We Salute You\" },\n  { \"AlbumId\": 4, \"Title\": \"Let There Be Rock\" }\n]\n```\n\n---\n\n### 📀 GET `/albums?page=1\u0026per_page=1`\n\nReturns albums and their tracks:\n\n```json\n{\n  \"albums\": [\n    {\n      \"AlbumId\": 1,\n      \"Title\": \"For Those About To Rock We Salute You\",\n      \"tracks\": [\n        { \"TrackId\": 1, \"Name\": \"Track A\" },\n        { \"TrackId\": 2, \"Name\": \"Track B\" }\n      ]\n    }\n  ],\n  \"page\": 1,\n  \"per_page\": 1,\n  \"total\": 347\n}\n```\n\n---\n\n### 🎶 GET `/albums/\u003calbum_id\u003e/tracks`\n\nReturns all tracks from an album:\n\n```json\n{\n  \"album_id\": 1,\n  \"tracks\": [\n    { \"TrackId\": 1, \"Name\": \"Track A\" },\n    { \"TrackId\": 2, \"Name\": \"Track B\" }\n  ]\n}\n```\n\n---\n\n### 📊 GET `/albums/summary`\n\nReturns album summaries with artist and track count:\n\n```json\n[\n  {\n    \"AlbumId\": 1,\n    \"AlbumTitle\": \"For Those About To Rock\",\n    \"ArtistName\": \"AC/DC\",\n    \"TrackCount\": 10\n  }\n]\n```\n\n---\n\n## 🧪 Running Tests\n\n### 🔹 Run all tests\n\n```bash\nmake test\n```\n\n### 🔹 Run coverage\n\n```bash\nmake coverage\n```\n\nCoverage report is also available in `htmlcov/index.html`.\n\n---\n\n## 🛠 Makefile Commands\n\n```bash\nmake run         # Run the Flask app locally\nmake test        # Run all tests with pytest\nmake coverage    # Run coverage report\nmake format      # Format code with black\nmake clean       # Clean pyc/__pycache__\nmake up          # Start docker container\nmake down        # Stop docker container\n```\n\n---\n\n## 🐍 Dependencies\n\nInstall with:\n\n```bash\npip install -r requirements.txt\npip install -r requirements-dev.txt  # For testing \u0026 development\n```\n\n---\n\n## 🔍 Swagger API Docs\n\nAccessible without authentication at:\n\n```\nhttp://localhost:5000/apidocs/\n```\n\nFully autogenerated via Flasgger.\n\n---\n\n### ✅ Project Highlights\n\nThis repository demonstrates a complete, production-ready Flask REST API with:\n\n- Modular and scalable architecture\n- Full Docker support for reproducible environments\n- High test coverage with `pytest` and GitHub Actions\n- Swagger UI documentation at `/apidocs/`\n- Error handling and logging centralized\n- Clean and readable codebase with auto-formatting via `make format`\n\nAll core functionality is covered by unit tests, with automated CI validating each push and pull request. This project serves as a solid foundation or reference for building robust backend services in Flask.\n\n---\n\n## 🧑‍💻 Author\n\nDeveloped by **Martín Peláez Díaz**  \nGitHub: [@martinp95](https://github.com/martinp95)\n\n---\n\n## 📄 License\n\nLicensed under the [MIT License](LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinp95%2Fflask_api_chinook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartinp95%2Fflask_api_chinook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinp95%2Fflask_api_chinook/lists"}