You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Proof of Concept for a RESTful API built with [Python 3](https://www.python.org/) and [FastAPI](https://fastapi.tiangolo.com/). Manage football player data with SQLite, SQLAlchemy 2.0 (async), Pydantic validation, and in-memory caching.
Proof of Concept for a RESTful Web Service built with **FastAPI** and **Python 3.13**. This project demonstrates best practices for building a layered, testable, and maintainable API implementing CRUD operations for a Players resource (Argentina 2022 FIFA World Cup squad).
- 📚 **Interactive API exploration** - Auto-generated OpenAPI docs with FastAPI's built-in Swagger UI and `.rest` file for REST Client integration
40
-
- ⚡ **Performance optimizations** - Async SQLAlchemy, in-memory caching with aiocache (10-minute TTL), and efficient database operations
41
-
- 🧪 **High test coverage** - Pytest suite with 80% minimum coverage and automated reporting to Codecov and SonarCloud
42
-
- 📖 **Agent-optimized documentation** - Claude Code and GitHub Copilot instructions with coding guidelines, architecture rules, and agent workflows for AI-assisted development
Layered architecture with dependency injection via FastAPI's `Depends()` mechanism and Pydantic for request/response validation.
@@ -153,54 +106,29 @@ graph RL
153
106
class tests test
154
107
```
155
108
156
-
*Simplified, conceptual view — not all components or dependencies are shown.*
157
-
158
-
### Arrow Semantics
159
-
160
-
Arrows follow the injection direction: `A --> B` means A is injected into B. Solid arrows (`-->`) represent active dependencies — components wired via FastAPI's `Depends()` mechanism and invoked at runtime. Dotted arrows (`-.->`) represent structural dependencies — the consumer references types without invoking runtime behavior.
161
-
162
-
### Composition Root Pattern
163
-
164
-
`main` is the composition root: it creates the FastAPI application instance, configures the lifespan handler, and registers all route modules via `app.include_router()`. Dependencies are resolved at request time via FastAPI's `Depends()` mechanism.
165
-
166
-
### Layered Architecture
167
-
168
-
Four layers: Initialization (`main`), HTTP (`routes`), Business (`services`), and Data (`schemas`, `databases`).
169
-
170
-
Third-party packages are placed inside the subgraph of the layer that uses them — `FastAPI` and `aiocache` in HTTP, `SQLAlchemy` in Data. The soft dependency from `routes` to `SQLAlchemy` reflects `AsyncSession` appearing only as a type annotation in `Depends()`, with no direct SQLAlchemy calls at the route level.
171
-
172
-
`models` is a cross-cutting type concern — Pydantic request/response models consumed across all layers, with no logic of its own.
173
-
174
-
### Color Coding
175
-
176
-
Blue = core application packages, red = third-party libraries, green = tests.
109
+
> *Arrows follow the injection direction (A → B means A is injected into B). Solid = runtime dependency, dotted = structural. Blue = core domain, red = third-party, green = tests.*
177
110
178
-
## Architecture Decisions
179
-
180
-
Key architectural decisions are documented as ADRs in [`docs/adr/`](docs/adr/README.md).
111
+
Significant architectural decisions are documented in [`docs/adr/`](docs/adr/).
181
112
182
113
## API Reference
183
114
184
115
Interactive API documentation is available via Swagger UI at `http://localhost:9000/docs` when the server is running.
185
116
186
-
**Quick Reference:**
187
-
188
-
-`GET /players/` — List all players
189
-
-`GET /players/{player_id}` — Get player by UUID (surrogate key)
190
-
-`GET /players/squadnumber/{squad_number}` — Get player by squad number (natural key)
191
-
-`POST /players/` — Create a new player
192
-
-`PUT /players/squadnumber/{squad_number}` — Update an existing player
193
-
-`DELETE /players/squadnumber/{squad_number}` — Remove a player
194
-
-`GET /health` — Health check
195
-
196
-
### HTTP Requests
117
+
| Method | Endpoint | Description | Status |
118
+
| ------ | -------- | ----------- | ------ |
119
+
|`GET`|`/players/`| List all players |`200 OK`|
120
+
|`GET`|`/players/{player_id}`| Get player by ID |`200 OK`|
121
+
|`GET`|`/players/squadnumber/{squad_number}`| Get player by squad number |`200 OK`|
122
+
|`POST`|`/players/`| Create new player |`201 Created`|
123
+
|`PUT`|`/players/squadnumber/{squad_number}`| Update player by squad number |`204 No Content`|
124
+
|`DELETE`|`/players/squadnumber/{squad_number}`| Remove player by squad number |`204 No Content`|
125
+
|`GET`|`/health`| Health check |`200 OK`|
197
126
198
-
A ready-to-use HTTP request file is available at [`rest/players.rest`](rest/players.rest). It covers all CRUD operations and can be run directly from your editor without leaving the development environment:
127
+
Error codes: `400 Bad Request` (squad number mismatch on `PUT`) · `404 Not Found` (player not found) · `409 Conflict` (duplicate squad number on `POST`) · `422 Unprocessable Entity` (schema validation failed)
199
128
200
-
-**VS Code** — install the [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) extension (`humao.rest-client`), open `rest/players.rest`, and click **Send Request** above any entry.
201
-
-**JetBrains IDEs** (IntelliJ IDEA, PyCharm, WebStorm) — the built-in HTTP Client supports `.rest` files natively; no plugin required.
129
+
For complete endpoint documentation with request/response schemas, explore the [interactive Swagger UI](http://localhost:9000/docs).
202
130
203
-
The file targets `http://localhost:9000` by default.
131
+
Alternatively, use [`rest/players.rest`](rest/players.rest) with the [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) extension for VS Code, or the built-in HTTP Client in JetBrains IDEs (IntelliJ IDEA, PyCharm, WebStorm).
204
132
205
133
## Prerequisites
206
134
@@ -212,14 +140,14 @@ Before you begin, ensure you have the following installed:
Tests are located in the `tests/` directory and use `httpx` for async integration testing. Coverage reports are generated for routes, services, and databases.
275
-
276
-
**Coverage target:** 80% minimum.
181
+
-**API Server**: `http://localhost:9000`
182
+
-**Swagger UI**: `http://localhost:9000/docs`
183
+
-**Health Check**: `http://localhost:9000/health`
277
184
278
185
## Containers
279
186
280
-
This project includes full Docker support with Docker Compose for easy deployment.
281
-
282
-
### Build the Docker image
283
-
284
-
```bash
285
-
docker compose build
286
-
```
287
-
288
-
### Start the application
187
+
### Build and Start
289
188
290
189
```bash
291
190
docker compose up
292
191
```
293
192
294
-
> 💡 On first run, the container copies a pre-seeded SQLite database into a persistent volume. On subsequent runs, that volume is reused and the data is preserved.
193
+
> 💡 **Note:**On first run, the container copies a pre-seeded SQLite database into a persistent volume. On subsequent runs, that volume is reused and the data is preserved.
295
194
296
-
### Stop the application
195
+
### Stop
297
196
298
197
```bash
299
198
docker compose down
300
199
```
301
200
302
-
### Reset the database
201
+
### Reset Database
303
202
304
203
To remove the volume and reinitialize the database from the built-in seed file:
305
204
306
205
```bash
307
206
docker compose down -v
308
207
```
309
208
310
-
The containerized application runs on port 9000 and includes health checks that monitor the `/health` endpoint.
311
-
312
-
## Releases
313
-
314
-
This project uses famous football coaches as release codenames ♟️, following an A-Z naming pattern.
315
-
316
-
### Release Naming Convention
317
-
318
-
Releases follow the pattern: `v{SEMVER}-{COACH}` (e.g., `v1.0.0-ancelotti`)
319
-
320
-
-**Semantic Version**: Standard versioning (MAJOR.MINOR.PATCH)
321
-
-**Coach Name**: Alphabetically ordered codename from the [famous coach list](CHANGELOG.md)
322
-
323
-
### Create a Release
324
-
325
-
To create a new release, follow this workflow:
326
-
327
-
#### 1. Create a Release Branch
328
-
329
-
```bash
330
-
git checkout -b release/v1.0.0-ancelotti
331
-
```
332
-
333
-
#### 2. Update CHANGELOG.md
334
-
335
-
Document your changes in [CHANGELOG.md](CHANGELOG.md):
336
-
337
-
```bash
338
-
# Move items from [Unreleased] to new release section
- Follow [Conventional Commits](https://www.conventionalcommits.org/) for commit messages
246
+
- Ensure all tests pass (`uv run pytest`)
247
+
- Run `uv run black .` before committing
248
+
- Keep changes small and focused
249
+
- Review `.github/copilot-instructions.md` for architectural patterns
250
+
251
+
**Testing:**
252
+
253
+
Run the test suite with pytest:
254
+
255
+
```bash
256
+
# Run all tests
257
+
uv run pytest
258
+
259
+
# Run tests with coverage report
260
+
uv run pytest --cov=./ --cov-report=term
261
+
```
262
+
395
263
## Command Summary
396
264
397
265
| Command | Description |
398
266
| ------- | ----------- |
399
267
|`uv run uvicorn main:app --reload --port 9000`| Start development server |
400
268
|`uv pip install --group dev`| Install all dependencies |
401
269
|`uv run pytest`| Run all tests |
402
-
|`uv run pytest -v`| Run tests with verbose output |
403
270
|`uv run pytest --cov=./ --cov-report=term`| Run tests with coverage |
404
271
|`uv run flake8 .`| Lint code |
405
272
|`uv run black --check .`| Check formatting |
@@ -408,17 +275,9 @@ PYTHONUNBUFFERED=1
408
275
|`docker compose up`| Start Docker container |
409
276
|`docker compose down`| Stop Docker container |
410
277
|`docker compose down -v`| Stop and remove Docker volume |
411
-
412
-
## Contributing
413
-
414
-
Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the code of conduct and the process for submitting pull requests.
415
-
416
-
**Key guidelines:**
417
-
418
-
- Follow [Conventional Commits](https://www.conventionalcommits.org/) for commit messages
419
-
- Ensure all tests pass (`uv run pytest`)
420
-
- Run `uv run black .` before committing
421
-
- Keep changes small and focused
278
+
|**AI Commands**||
279
+
|`/pre-commit`| Runs linting, tests, and quality checks before committing |
0 commit comments