201 lines
4.6 KiB
Markdown
201 lines
4.6 KiB
Markdown
# AGENTS.md - File Server Project
|
|
|
|
## Project Overview
|
|
|
|
This is a FastAPI-based file server that serves files from a directory or ZIP archive using hashed paths. The server indexes files and serves them via random access or by hash lookup.
|
|
|
|
## Language & Runtime
|
|
|
|
- **Language**: Python 3.13
|
|
- **Framework**: FastAPI 0.128.0+
|
|
- **Server**: Uvicorn 0.40.0+
|
|
|
|
## Build, Lint, and Test Commands
|
|
|
|
### Running the Server
|
|
|
|
```bash
|
|
# Run with a directory
|
|
python main.py /path/to/files
|
|
|
|
# Run with a ZIP archive
|
|
python main.py /path/to/archive.zip
|
|
```
|
|
|
|
### Testing
|
|
|
|
No test framework is currently configured. To add tests, install pytest:
|
|
|
|
```bash
|
|
uv add pytest
|
|
```
|
|
|
|
Run all tests:
|
|
```bash
|
|
pytest
|
|
```
|
|
|
|
Run a single test:
|
|
```bash
|
|
pytest path/to/test_file.py::TestClass::test_method
|
|
pytest -k "test_name_pattern"
|
|
```
|
|
|
|
### Linting
|
|
|
|
No linting tool is currently configured. Recommended tools:
|
|
|
|
```bash
|
|
# Install ruff (fast linter/formatter)
|
|
uv add ruff
|
|
|
|
# Run linting
|
|
ruff check .
|
|
|
|
# Auto-fix issues
|
|
ruff check --fix .
|
|
|
|
# Format code
|
|
ruff format .
|
|
```
|
|
|
|
### Type Checking
|
|
|
|
```bash
|
|
# Install mypy
|
|
uv add mypy
|
|
|
|
# Run type checking
|
|
mypy main.py
|
|
```
|
|
|
|
## Code Style Guidelines
|
|
|
|
### Imports
|
|
|
|
- Standard library imports first, then third-party, then local
|
|
- Group imports by type: stdlib, third-party, local
|
|
- Use absolute imports for local modules
|
|
- Example:
|
|
```python
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from fastapi import FastAPI, HTTPException
|
|
from fastapi.responses import FileResponse, StreamingResponse
|
|
|
|
from mymodule import MyClass
|
|
```
|
|
|
|
### Formatting
|
|
|
|
- Use 4 spaces for indentation (no tabs)
|
|
- Maximum line length: 100 characters
|
|
- Use blank lines to separate logical sections (2 blank lines between top-level definitions)
|
|
- One blank line between method definitions within a class
|
|
|
|
### Types
|
|
|
|
- Use type hints for all function arguments and return values
|
|
- Use Python 3.13+ typing features where appropriate
|
|
- Example:
|
|
```python
|
|
def process_file(path: str) -> bytes:
|
|
...
|
|
|
|
class FileIndexer:
|
|
def __init__(self, path: str) -> None:
|
|
...
|
|
```
|
|
|
|
### Naming Conventions
|
|
|
|
- **Classes**: `PascalCase` (e.g., `FileIndexer`, `ZipFileIndexer`)
|
|
- **Functions/variables**: `snake_case` (e.g., `get_file_by_hash`, `file_mapping`)
|
|
- **Constants**: `UPPER_SNAKE_CASE` (e.g., `INDEXER_MAP`)
|
|
- **Private methods/attributes**: Prefix with underscore (e.g., `_index`, `_salt`)
|
|
- Use descriptive, full words for names (avoid abbreviations except well-known ones)
|
|
|
|
### Error Handling
|
|
|
|
- Use exceptions for exceptional cases, not flow control
|
|
- Raise `HTTPException` for HTTP-level errors in FastAPI endpoints
|
|
- Provide meaningful error messages
|
|
- Example:
|
|
```python
|
|
if not indexer.file_mapping:
|
|
raise HTTPException(status_code=404, detail="No files indexed")
|
|
|
|
if file_hash not in self.file_mapping:
|
|
return None
|
|
```
|
|
|
|
### Async/Await
|
|
|
|
- Use `async def` for FastAPI endpoint handlers
|
|
- Use regular functions for synchronous operations (file I/O, hashing)
|
|
- Do not mix sync and async improperly
|
|
|
|
### File Operations
|
|
|
|
- Use `pathlib.Path` for path manipulations
|
|
- Use context managers (`with` statements) for file operations
|
|
- Handle both directory and archive (ZIP) file sources
|
|
|
|
### Documentation
|
|
|
|
- Use docstrings for public classes and functions
|
|
- Follow Google-style docstring format:
|
|
```python
|
|
def get_file_by_hash(file_hash: str) -> str | None:
|
|
"""Get filename by hash.
|
|
|
|
Args:
|
|
file_hash: The hash identifier for the file.
|
|
|
|
Returns:
|
|
The filename if found, None otherwise.
|
|
"""
|
|
```
|
|
|
|
### Best Practices
|
|
|
|
- Keep functions small and focused (single responsibility)
|
|
- Use properties for computed attributes with caching
|
|
- Avoid global state where possible; use dependency injection
|
|
- Use dataclasses or attrs for simple data containers
|
|
- Follow PEP 8 style guidelines
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
/projects/file_server/
|
|
├── main.py # Main application entry point
|
|
├── pyproject.toml # Project configuration
|
|
├── .python-version # Python version specification
|
|
└── README.md # Project documentation (currently empty)
|
|
```
|
|
|
|
## Common Tasks
|
|
|
|
### Adding a New Endpoint
|
|
|
|
1. Add the route handler in `main.py`
|
|
2. Use appropriate HTTP method decorator (`@app.get`, `@app.post`, etc.)
|
|
3. Add type hints and docstrings
|
|
4. Handle errors with `HTTPException`
|
|
|
|
### Adding a New File Indexer
|
|
|
|
1. Create a new class inheriting from `FileIndexer`
|
|
2. Override the `_index` method to populate `self.file_mapping`
|
|
3. Implement `get_file_by_hash` and `get_filename_by_hash`
|
|
4. Register in `INDEXER_MAP` dictionary
|
|
|
|
### Running the Server in Development
|
|
|
|
```bash
|
|
python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
|
```
|