Project Structure¶
Understand the Apiary codebase architecture and organization.
Overview¶
Apiary follows a modular architecture with clear separation of concerns:
config/- Configuration management and validationcore/- Reusable utilities and base functionalitymodels/- Data models and schemasrouters/- HTTP endpoint handlersservices/- Business logic implementationsstatic/&templates/- Web assetstests/- Test suite
Directory Layout¶
apiary/
├── app.py # FastAPI application factory
├── cli.py # Command-line interface
├── __version__.py # Version information
│
├── config/ # Configuration Management
│ ├── __init__.py
│ ├── settings.py # Settings model (Pydantic)
│ ├── endpoint_config.py # Endpoint configuration model
│ ├── settings_template.json # Default settings template
│ ├── endpoints_template.json # Default endpoints template
│ ├── settings.json # Your settings (gitignored)
│ └── endpoints.json # Your endpoints (gitignored)
│
├── core/ # Core Framework
│ ├── auth/ # Authentication & Authorization
│ │ ├── authentication.py # API key verification
│ │ └── authorization.py # Dependency injection for auth
│ ├── services/ # Service Base Classes
│ │ └── base.py # BaseService interface
│ ├── api_key_manager.py # Key loading & hot-reloading
│ ├── api_key_validator.py # Configuration validation
│ ├── cache.py # Response caching utilities
│ ├── dependencies.py # FastAPI dependencies
│ ├── exceptions.py # Custom exception classes
│ ├── logging_config.py # Logging configuration
│ ├── metrics.py # Metrics collection
│ ├── middleware.py # Request/response middleware
│ ├── rate_limiter.py # Rate limiting logic
│ ├── request_validation.py # Request validation
│ └── router_factory.py # Dynamic router generation
│
├── models/ # Data Models
│ ├── requests.py # Request models (Pydantic)
│ └── responses.py # Response models (Pydantic)
│
├── routers/ # Built-in Routers
│ ├── auth.py # /auth endpoints
│ ├── endpoints.py # /endpoints discovery
│ ├── health.py # /health checks
│ ├── home.py # / landing page
│ └── metrics.py # /metrics endpoint
│
├── services/ # Built-in Services
│ ├── crypto.py # Crypto helper functions
│ ├── crypto_service.py # Crypto price service
│ └── hello_service.py # Hello world demo service
│
├── routers_custom/ # Custom Routers (gitignored)
│ └── __init__.py # Your custom routers here
│
├── services_custom/ # Custom Services (gitignored)
│ └── __init__.py # Your custom services here
│
├── static/ # Static Assets
│ ├── css/ # Stylesheets
│ │ ├── docs.css
│ │ └── theme.css
│ └── img/ # Images & icons
│
├── templates/ # Jinja2 Templates
│ ├── home/ # Landing page templates
│ └── shared/ # Shared layouts
│
├── tests/ # Test Suite
│ ├── conftest.py # Pytest configuration
│ ├── unit/ # Unit tests
│ └── integration/ # Integration tests
│
├── docs/ # Documentation (MkDocs)
│ ├── getting-started/
│ ├── guide/
│ ├── deployment/
│ ├── reference/
│ └── about/
│
├── pyproject.toml # Project metadata & dependencies
├── uv.lock # Dependency lock file
├── pytest.ini # Pytest configuration
├── mkdocs.yml # Documentation configuration
└── README.md # Project overview
Configuration Files
Files like config/settings.json, config/endpoints.json, services_custom/, and routers_custom/ are gitignored. Run uv run apiary init to create them from templates.
Core Components¶
Application Entry Point¶
Main application factory that creates and configures the FastAPI application.
Key responsibilities:
- Initialize FastAPI app with configuration
- Load settings and endpoint configurations
- Register routers (built-in and custom)
- Configure middleware and exception handlers
- Set up CORS, rate limiting, and logging
Usage:
Command-line interface for maintenance and development tasks.
Available commands:
serve- Start the development serverinit- Initialize configuration filesvalidate-config- Validate API keystest- Test configuration and importsbackup- Backup configurationclean- Clean generated files
See CLI Reference for full documentation.
Configuration Layer¶
Pydantic Settings model for type-safe configuration.
Features:
- Environment variable support
- JSON file loading
- Type validation
- Default values
Endpoint configuration model with validation.
Features:
- Pydantic validation
- Duplicate detection
- Path validation
- HTTP method enum
Default configuration templates:
settings_template.json- Default application settingsendpoints_template.json- Example endpoint configurations
These are copied to settings.json and endpoints.json by uv run apiary init.
Core Framework¶
core/auth/ - Authentication and authorization system
Files:
authentication.py- API key verification logicauthorization.py- FastAPI dependencies for protecting endpoints
core/services/base.py - Abstract base class for all services
Features:
- HTTP client management
- Async support
- Lifecycle management (cleanup)
core/api_key_manager.py - API key loading and hot-reloading
Features:
- Load keys from strings or files
- Automatic file change detection
- In-memory caching
- Thread-safe operations
core/api_key_validator.py - Configuration validation
Validates:
- API key file existence
- Key format and strength
- Configuration consistency
Core utilities:
cache.py- Response caching headersdependencies.py- Dependency injectionexceptions.py- Custom exceptionslogging_config.py- Structured loggingmetrics.py- Application metricsmiddleware.py- Request/response processingrate_limiter.py- Rate limiting logicrequest_validation.py- Request validationrouter_factory.py- Dynamic router creation
Routers & Services¶
routers/ - HTTP endpoint handlers
| Router | Path | Purpose |
|---|---|---|
home.py |
/ |
Landing page |
health.py |
/health |
Health checks |
metrics.py |
/metrics |
Application metrics |
auth.py |
/auth |
Authentication info |
endpoints.py |
/endpoints |
Endpoint discovery |
Routers can be enabled/disabled in settings.json:
services/ - Business logic implementations
| Service | Purpose | Reference |
|---|---|---|
hello_service.py |
Demo service | HelloService |
crypto_service.py |
Crypto prices | CryptoService |
All services inherit from BaseService:
Update-safe directories for your code:
services_custom/ - Your custom services (gitignored)
- Add your service files here
- Register in
services_custom/__init__.py
routers_custom/ - Your custom routers (gitignored)
- Add your router files here
- Each must export a
routervariable - Enable in
settings.json→enabled_routers
Created by uv run apiary init --custom-dirs
Data Models¶
Response models using Pydantic.
Base classes:
BaseResponse- Includes automatic timestamp
Request models and query parameters.
Request Flow¶
Understanding how a request flows through Apiary:
graph TB
A[Client Request] --> B[Middleware]
B --> C{Rate Limit?}
C -->|Exceeded| D[429 Too Many Requests]
C -->|OK| E{Auth Required?}
E -->|Yes| F{Valid API Key?}
F -->|No| G[401 Unauthorized]
F -->|Yes| H[Router Handler]
E -->|No| H
H --> I{Dynamic Endpoint?}
I -->|Yes| J[Router Factory]
I -->|No| K[Static Router]
J --> L[Service Call]
K --> M[Direct Handler]
L --> N[Response Model]
M --> N
N --> O[Middleware]
O --> P[Client Response]
- Middleware - Logs request, adds request ID, applies CORS
- Rate Limiting - Checks request rate (if enabled)
- Authentication - Validates API key (if required)
- Routing - Matches request to handler (static or dynamic)
- Service - Executes business logic
- Response - Returns validated Pydantic model
- Middleware - Adds response headers, logs response
Adding New Components¶
Adding a Service¶
-
Create service file in
services_custom/: -
Register in
services_custom/__init__.py: -
Add to
config/endpoints.json:
Adding a Router¶
-
Create router file in
routers_custom/: -
Enable in
config/settings.json:
Adding a Model¶
-
Add to
models/responses.pyormodels/requests.py: -
Use in router:
Configuration Files¶
Tracked in Git¶
These files are part of the repository:
pyproject.toml- Dependencies and project metadatamkdocs.yml- Documentation configurationpytest.ini- Test configurationconfig/*_template.json- Configuration templates- All
.pyfiles inconfig/,core/,models/,routers/,services/
Not Tracked (Gitignored)¶
These are created locally and not committed:
config/settings.json- Your settingsconfig/endpoints.json- Your endpointsconfig/*_keys.txt- Your API keysservices_custom/- Your custom servicesrouters_custom/- Your custom routersbackups/- Configuration backupssite/- Built documentation__pycache__/,*.pyc- Python cache files
This allows you to safely git pull updates without conflicts!
Development Workflow¶
Initial Setup¶
# Clone and install
git clone <repository>
cd apiary
uv sync
# Initialize configuration
uv run apiary init
# Edit configuration
edit config/settings.json
edit config/endpoints.json
# Validate and test
uv run apiary validate-config
uv run apiary test
# Start server
uv run apiary serve --reload
Adding Features¶
# Create custom service
mkdir -p services_custom
edit services_custom/my_service.py
# Configure endpoint
edit config/endpoints.json
# Test changes
uv run apiary test
# Start with auto-reload
uv run apiary serve --reload
Updating from Upstream¶
# Backup your config
uv run apiary backup --include-custom
# Pull updates
git pull origin main
uv sync
# Check for new config options
diff config/settings_template.json config/settings.json
# Test before deploying
uv run apiary test
Next Steps¶
- Quick Start Guide - Get started quickly
- Configuration Guide - Configure your instance
- Adding Endpoints - Create custom endpoints
- Creating Services - Build service classes
- CLI Reference - Command-line tools