Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: Bug report
about: Report a bug or unexpected behavior
title: "[BUG]"
labels: bug
assignees: ''

---

## Description

A clear and concise description of what the bug is.

## Steps to Reproduce

1. Step 1
2. Step 2
3. Step 3

## Expected Behavior

What you expected to happen.

## Actual Behavior

What actually happened.

## Environment

- **Python version:** (output of `python --version`)
- **FastAPI version:** (from `pyproject.toml`)
- **OS:** (e.g., macOS 14.0, Ubuntu 22.04, Windows 11)

## Additional Context

Add any other context about the problem here (logs, screenshots, etc.).

## Possible Solution

(Optional) Suggest a fix or workaround if you have one.
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,5 @@ Example: `feat(api): add player stats endpoint (#42)`
feat(scope): description (#issue)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
```
69 changes: 47 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,68 +86,93 @@ Proof of Concept for a RESTful API built with [Python 3](https://www.python.org/

## Architecture

Layered architecture with dependency injection via FastAPI's `Depends()` mechanism and Pydantic for request/response validation.

```mermaid
%%{init: {
"theme": "default",
"themeVariables": {
"fontFamily": "Fira Code, Consolas, monospace",
"textColor": "#555",
"lineColor": "#555",
"lineWidth": 2
"lineColor": "#555"
}
}}%%

graph BT
%% Core application packages
graph RL

tests[tests]

main[main]
routes[routes]
fastapi[FastAPI]
aiocache[aiocache]

services[services]
schemas[schemas]
databases[databases]

models[models]
pydantic[Pydantic]

%% External dependencies
fastapi[FastAPI]
schemas[schemas]

databases[databases]
sqlalchemy[SQLAlchemy]
pydantic[Pydantic]

%% Test coverage
tests[tests]
%% Strong dependencies

%% Module dependencies
routes --> main
fastapi --> main

fastapi --> routes
aiocache --> routes
services --> routes
models --> routes
databases --> routes

schemas --> services
models --> services
databases --> schemas
fastapi --> routes
sqlalchemy --> routes
sqlalchemy --> services
pydantic --> models

databases --> schemas
sqlalchemy --> schemas
sqlalchemy --> databases
pydantic --> models

%% Soft dependencies

sqlalchemy -.-> routes
main -.-> tests

%% Node styling
%% Node styling with stroke-width
classDef core fill:#b3d9ff,stroke:#6db1ff,stroke-width:2px,color:#555,font-family:monospace;
classDef deps fill:#ffcccc,stroke:#ff8f8f,stroke-width:2px,color:#555,font-family:monospace;
classDef test fill:#ccffcc,stroke:#53c45e,stroke-width:2px,color:#555,font-family:monospace;

class main,routes,services,schemas,databases,models core
class fastapi,sqlalchemy,pydantic deps
class fastapi,sqlalchemy,pydantic,aiocache deps
class tests test
```

**Arrow Semantics:** Solid arrows represent import-time module dependencies — the arrow points from the dependency to the consumer. The dotted arrow to `tests` indicates the integration tests validate the full application stack as wired by `main`.
*Simplified, conceptual view — not all components or dependencies are shown.*

### Arrow Semantics

Arrows point from a dependency toward its consumer. Solid arrows (`-->`) denote **strong (functional) dependencies**: the consumer actively invokes behavior — registering route handlers, dispatching requests, executing async queries, or managing the database session. Dotted arrows (`-.->`) denote **soft (structural) dependencies**: the consumer only references types without invoking runtime behavior. This distinction follows UML's `«use»` dependency notation and classical coupling theory (Myers, 1978): strong arrows approximate *control or stamp coupling*, while soft arrows approximate *data coupling*, where only shared data structures cross the boundary.

### Composition Root Pattern

The `main` module acts as the composition root — it creates the FastAPI application instance, configures the lifespan handler, and registers all route modules via `app.include_router()`. Rather than explicit object construction, dependency injection is provided by FastAPI's built-in `Depends()` mechanism: `routes` declare their dependencies (e.g. `AsyncSession`) as function parameters and FastAPI resolves them at request time. This pattern enables dependency injection, improves testability, and ensures no other module bears responsibility for wiring or lifecycle management.

### Layered Architecture

The codebase is organized into four conceptual layers: Initialization (`main`), HTTP (`routes`), Business (`services`), and Data (`schemas`, `databases`).

Third-party dependencies are co-resident within the layer that consumes them: `FastAPI` and `aiocache` inside HTTP, and `SQLAlchemy` inside Data. `routes` holds a soft dependency on `SQLAlchemy` — `AsyncSession` is referenced only as a type annotation in `Depends()`, without any direct SQLAlchemy method calls at the route level.

**Composition Root Pattern:** The `main` module acts as the composition root — it imports `FastAPI` and the route modules, creates the app instance, and registers all routers. This pattern enables dependency injection via `Depends()`, improves testability, and maintains clear separation of concerns.
The `models` package is a **cross-cutting type concern** — it defines Pydantic request and response models consumed across multiple layers, without containing logic or behavior of its own. Dependencies always flow from consumers toward their lower-level types: each layer depends on (consumes) the layers below it, and no layer invokes behavior in a layer above it.

**Layered Architecture:** Each layer has a specific responsibility — routes handle HTTP mapping, validation, and in-memory caching, services contain business logic, schemas define the ORM model, and databases manage the async session.
### Color Coding

**Color Coding:** Core packages (blue) implement the application logic, external dependencies (red) are third-party frameworks and ORMs, and tests (green) ensure code quality.
Core packages (blue) implement the application logic, third-party dependencies (red) are community packages, and tests (green) ensure code quality.

## API Reference

Expand Down
Loading