Skip to content

Commit e640c2e

Browse files
cguarinosuclaude
andcommitted
feat: Initialize Python FastAPI project with Poetry
Set up a modern Python project structure using FastAPI framework for building a Todo List API. This replaces the previous NestJS implementation with a Python-based solution. Key additions: - Poetry for dependency management (pyproject.toml) - Ruff for fast linting and formatting (.ruff.toml) - mypy for strict type checking (mypy.ini) - Python-specific .gitignore - Comprehensive README with setup instructions Dependencies: - FastAPI ^0.115.0 - Modern, fast web framework - Uvicorn - ASGI server with hot reload - Pydantic v2 - Data validation using type hints - pytest - Testing framework - httpx - HTTP client for testing Development tools: - Ruff - Extremely fast linter/formatter (Rust-based) - mypy - Static type checker with strict mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
0 parents  commit e640c2e

File tree

5 files changed

+374
-0
lines changed

5 files changed

+374
-0
lines changed

.gitignore

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
MANIFEST
23+
24+
# Virtual environments
25+
venv/
26+
env/
27+
ENV/
28+
env.bak/
29+
venv.bak/
30+
.venv/
31+
32+
# Poetry
33+
poetry.lock
34+
35+
# Testing
36+
.pytest_cache/
37+
.coverage
38+
htmlcov/
39+
.tox/
40+
.hypothesis/
41+
*.cover
42+
/coverage
43+
/.nyc_output
44+
45+
# Type checking
46+
.mypy_cache/
47+
.dmypy.json
48+
dmypy.json
49+
.pyre/
50+
.pytype/
51+
52+
# Logs
53+
logs
54+
*.log
55+
56+
# OS
57+
.DS_Store
58+
59+
# IDEs and editors
60+
/.idea
61+
.project
62+
.classpath
63+
.c9/
64+
*.launch
65+
.settings/
66+
*.sublime-workspace
67+
*.swp
68+
*.swo
69+
*~
70+
71+
# IDE - VSCode
72+
.vscode/*
73+
!.vscode/settings.json
74+
!.vscode/tasks.json
75+
!.vscode/launch.json
76+
!.vscode/extensions.json
77+
78+
# Environment variables
79+
.env
80+
.env.local
81+
.env.*.local

.ruff.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Ruff configuration
2+
# Ruff is an extremely fast Python linter and formatter, written in Rust
3+
4+
line-length = 100
5+
target-version = "py39"
6+
7+
[lint]
8+
select = [
9+
"E", # pycodestyle errors
10+
"W", # pycodestyle warnings
11+
"F", # pyflakes
12+
"I", # isort
13+
"B", # flake8-bugbear
14+
"C4", # flake8-comprehensions
15+
"UP", # pyupgrade
16+
"ARG", # flake8-unused-arguments
17+
"SIM", # flake8-simplify
18+
]
19+
ignore = []
20+
21+
# Allow autofix for all enabled rules
22+
fixable = ["ALL"]
23+
unfixable = []
24+
25+
[format]
26+
quote-style = "double"
27+
indent-style = "space"
28+
skip-magic-trailing-comma = false
29+
line-ending = "auto"

README.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# python-interview / TodoAPI
2+
3+
[![Open in Coder](https://dev.crunchloop.io/open-in-coder.svg)](https://dev.crunchloop.io/templates/fly-containers/workspace?param.Git%20Repository=git@github.com:crunchloop/python-interview.git)
4+
5+
This is a simple Todo List API built with FastAPI and Python 3.13+. This project is currently being used for Python full-stack candidates.
6+
7+
## Features
8+
9+
- **FastAPI** - Modern, fast web framework for building APIs
10+
- **Python 3.13+** - Latest Python with full type hints
11+
- **Pydantic v2** - Data validation using Python type annotations
12+
- **In-memory storage** - Simple data persistence (resets on restart)
13+
- **Poetry** - Modern dependency management
14+
- **pytest** - Comprehensive unit tests with mocking
15+
- **Ruff** - Extremely fast Python linter and formatter
16+
- **mypy** - Static type checker with strict mode
17+
- **DevContainer** - VS Code development container support
18+
19+
## Prerequisites
20+
21+
- Python 3.13+ or Docker with VS Code DevContainer support
22+
- Poetry (if running locally without Docker)
23+
24+
## Installation
25+
26+
### Using Poetry (Local)
27+
28+
```bash
29+
# Install Poetry if you haven't already
30+
curl -sSL https://install.python-poetry.org | python3 -
31+
32+
# Install dependencies
33+
poetry install
34+
35+
# Activate virtual environment
36+
poetry shell
37+
```
38+
39+
### Using DevContainer (Recommended)
40+
41+
1. Open the project in VS Code
42+
2. Install the "Dev Containers" extension
43+
3. Press `F1` and select "Dev Containers: Reopen in Container"
44+
4. Dependencies will be installed automatically
45+
46+
## Running the app
47+
48+
### Development mode with hot reload
49+
50+
```bash
51+
# Using Poetry
52+
poetry run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
53+
54+
# Or if inside poetry shell
55+
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
56+
```
57+
58+
### Production mode
59+
60+
```bash
61+
poetry run uvicorn app.main:app --host 0.0.0.0 --port 8000
62+
```
63+
64+
The API will be available at:
65+
- **API**: http://localhost:8000
66+
- **Interactive API docs (Swagger)**: http://localhost:8000/docs
67+
- **Alternative API docs (ReDoc)**: http://localhost:8000/redoc
68+
69+
## API Endpoints
70+
71+
All endpoints are prefixed with `/api/todolists`:
72+
73+
| Method | Endpoint | Description |
74+
|--------|----------|-------------|
75+
| GET | `/api/todolists` | Get all todo lists |
76+
| GET | `/api/todolists/{id}` | Get a specific todo list |
77+
| POST | `/api/todolists` | Create a new todo list |
78+
| PUT | `/api/todolists/{id}` | Update an existing todo list |
79+
| DELETE | `/api/todolists/{id}` | Delete a todo list |
80+
81+
## Testing
82+
83+
```bash
84+
# Run all tests
85+
poetry run pytest
86+
87+
# Run tests with coverage
88+
poetry run pytest --cov=app --cov-report=html
89+
90+
# Run tests in watch mode
91+
poetry run pytest-watch
92+
93+
# Run tests with verbose output
94+
poetry run pytest -v
95+
```
96+
97+
## Code Quality
98+
99+
### Linting and Formatting with Ruff
100+
101+
```bash
102+
# Check for linting errors
103+
poetry run ruff check .
104+
105+
# Fix linting errors automatically
106+
poetry run ruff check --fix .
107+
108+
# Format code
109+
poetry run ruff format .
110+
```
111+
112+
### Type Checking with mypy
113+
114+
```bash
115+
# Run type checker
116+
poetry run mypy app/
117+
118+
# Run type checker on all files
119+
poetry run mypy .
120+
```
121+
122+
## Project Structure
123+
124+
```
125+
.
126+
├── app/
127+
│ ├── __init__.py
128+
│ ├── main.py # FastAPI application entry point
129+
│ ├── models.py # Pydantic models (schemas)
130+
│ ├── routers/
131+
│ │ ├── __init__.py
132+
│ │ └── todo_lists.py # TodoList API endpoints
133+
│ └── services/
134+
│ ├── __init__.py
135+
│ └── todo_lists.py # Business logic and in-memory storage
136+
├── tests/
137+
│ ├── __init__.py
138+
│ └── test_todo_lists.py # Unit tests for all endpoints
139+
├── .devcontainer/ # VS Code DevContainer configuration
140+
├── pyproject.toml # Poetry dependencies and tool configs
141+
├── .ruff.toml # Ruff linter/formatter configuration
142+
├── mypy.ini # mypy type checker configuration
143+
└── README.md
144+
```
145+
146+
## Development Tools
147+
148+
This project uses modern Python development tools:
149+
150+
- **Poetry**: Dependency management and packaging
151+
- **Ruff**: Extremely fast linter and formatter (replaces Black, isort, flake8)
152+
- **mypy**: Static type checker with strict mode enabled
153+
- **pytest**: Testing framework with async support
154+
- **httpx**: HTTP client for testing FastAPI endpoints
155+
156+
## In-Memory Storage
157+
158+
This application uses in-memory storage (Python lists/dicts). Data will be lost when the application restarts. This is intentional for simplicity and is suitable for interview/demo purposes.
159+
160+
Check integration tests at: https://github.com/crunchloop/interview-tests
161+
162+
## Contact
163+
164+
- Martín Fernández (mfernandez@crunchloop.io)
165+
166+
## About Crunchloop
167+
168+
![crunchloop](https://s3.amazonaws.com/crunchloop.io/logo-blue.png)
169+
170+
We strongly believe in giving back :rocket:. Let's work together [`Get in touch`](https://crunchloop.io/#contact).

mypy.ini

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[mypy]
2+
python_version = 3.9
3+
strict = True
4+
warn_return_any = True
5+
warn_unused_configs = True
6+
disallow_untyped_defs = True
7+
disallow_any_unimported = False
8+
no_implicit_optional = True
9+
warn_redundant_casts = True
10+
warn_unused_ignores = True
11+
warn_no_return = True
12+
check_untyped_defs = True
13+
strict_equality = True
14+
show_error_codes = True
15+
show_column_numbers = True
16+
pretty = True
17+
18+
# Ignore missing imports for third-party libraries without stubs
19+
[mypy-tests.*]
20+
disallow_untyped_defs = False

pyproject.toml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
[tool.poetry]
2+
name = "fastapi-todo"
3+
version = "1.0.0"
4+
description = "A simple Todo List API for Python/FastAPI candidates"
5+
authors = ["Your Name <your.email@example.com>"]
6+
readme = "README.md"
7+
packages = [{include = "app"}]
8+
9+
[tool.poetry.dependencies]
10+
python = "^3.9"
11+
fastapi = "^0.115.0"
12+
uvicorn = {extras = ["standard"], version = "^0.32.0"}
13+
pydantic = "^2.9.0"
14+
pydantic-settings = "^2.6.0"
15+
16+
[tool.poetry.group.dev.dependencies]
17+
pytest = "^8.3.0"
18+
pytest-asyncio = "^0.24.0"
19+
httpx = "^0.27.0"
20+
ruff = "^0.7.0"
21+
mypy = "^1.13.0"
22+
23+
[build-system]
24+
requires = ["poetry-core"]
25+
build-backend = "poetry.core.masonry.api"
26+
27+
[tool.ruff]
28+
line-length = 100
29+
target-version = "py39"
30+
31+
[tool.ruff.lint]
32+
select = [
33+
"E", # pycodestyle errors
34+
"W", # pycodestyle warnings
35+
"F", # pyflakes
36+
"I", # isort
37+
"B", # flake8-bugbear
38+
"C4", # flake8-comprehensions
39+
"UP", # pyupgrade
40+
"ARG", # flake8-unused-arguments
41+
"SIM", # flake8-simplify
42+
]
43+
ignore = []
44+
45+
[tool.ruff.format]
46+
quote-style = "double"
47+
indent-style = "space"
48+
skip-magic-trailing-comma = false
49+
50+
[tool.mypy]
51+
python_version = "3.9"
52+
strict = true
53+
warn_return_any = true
54+
warn_unused_configs = true
55+
disallow_untyped_defs = true
56+
disallow_any_unimported = false
57+
no_implicit_optional = true
58+
warn_redundant_casts = true
59+
warn_unused_ignores = true
60+
warn_no_return = true
61+
check_untyped_defs = true
62+
strict_equality = true
63+
64+
[tool.pytest.ini_options]
65+
asyncio_mode = "auto"
66+
testpaths = ["tests"]
67+
python_files = ["test_*.py"]
68+
python_classes = ["Test*"]
69+
python_functions = ["test_*"]
70+
addopts = [
71+
"--strict-markers",
72+
"--strict-config",
73+
"-ra",
74+
]

0 commit comments

Comments
 (0)