image_server/AGENTS.md
2026-03-09 08:23:34 +00:00

207 lines
4.7 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
pip install 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)
pip install ruff
# Run linting
ruff check .
# Auto-fix issues
ruff check --fix .
# Format code
ruff format .
```
Alternatively, using pylint:
```bash
pip install pylint
pylint main.py
```
### Type Checking
```bash
# Install mypy
pip install 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
```