|
| 1 | +# python-interview / TodoAPI |
| 2 | + |
| 3 | +[](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 | + |
| 169 | + |
| 170 | +We strongly believe in giving back :rocket:. Let's work together [`Get in touch`](https://crunchloop.io/#contact). |
0 commit comments