4.6 KiB
4.6 KiB
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
# 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:
uv add pytest
Run all tests:
pytest
Run a single test:
pytest path/to/test_file.py::TestClass::test_method
pytest -k "test_name_pattern"
Linting
No linting tool is currently configured. Recommended tools:
# Install ruff (fast linter/formatter)
uv add ruff
# Run linting
ruff check .
# Auto-fix issues
ruff check --fix .
# Format code
ruff format .
Type Checking
# 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:
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:
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
HTTPExceptionfor HTTP-level errors in FastAPI endpoints - Provide meaningful error messages
- Example:
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 deffor FastAPI endpoint handlers - Use regular functions for synchronous operations (file I/O, hashing)
- Do not mix sync and async improperly
File Operations
- Use
pathlib.Pathfor path manipulations - Use context managers (
withstatements) for file operations - Handle both directory and archive (ZIP) file sources
Documentation
- Use docstrings for public classes and functions
- Follow Google-style docstring format:
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
- Add the route handler in
main.py - Use appropriate HTTP method decorator (
@app.get,@app.post, etc.) - Add type hints and docstrings
- Handle errors with
HTTPException
Adding a New File Indexer
- Create a new class inheriting from
FileIndexer - Override the
_indexmethod to populateself.file_mapping - Implement
get_file_by_hashandget_filename_by_hash - Register in
INDEXER_MAPdictionary
Running the Server in Development
python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000