Guaro - Modern Python Backend Framework
A powerful, async-first Python framework for building REST & GraphQL APIs with automatic schema management, dependency injection, and type-safe data validation.
Features
- Async-first: Built on Starlette for high-performance async request handling
- Multi-protocol: REST and GraphQL support out of the box
- Database-agnostic: SQLite, PostgreSQL, MySQL, and MongoDB support with schema management
- Auto-migrate: Schema updates that preserve existing data
- Relations: Support for complex relationships and nested queries
- Dependency injection: Dependency resolution for handlers and middleware
- Type-safe: Full type hints for improved IDE support and developer experience
- Auto documentation: Automatic OpenAPI/Swagger generation
- Middleware and authentication: Built-in middleware support for authentication and permissions
Quick Start
Installation
Install the latest version from PyPI:
# Basic installation with SQLite support
pip install guaro
# With specific database support
pip install "guaro[postgres]" # PostgreSQL
pip install "guaro[mysql]" # MySQL
pip install "guaro[mongodb]" # MongoDB
pip install "guaro[all-databases]" # All databases
# Development version from source
git clone https://github.com/Alazar42/Guaro.git
cd Guaro
pip install -e ".[all-databases,dev]"
See Installation & Setup Guide for detailed setup instructions and environment configuration.
Basic Example
from guaro import API, Model, Router, DatabaseEngine
# Define your models
class User(Model):
id: int
name: str
email: str
class Post(Model):
id: int
title: str
body: str
author: "User"
# Configure API
api = API(database={
"engine": DatabaseEngine.POSTGRESQL,
"url": "postgresql+asyncpg://user:pass@localhost/dbname",
"auto_migrate": True, # Automatic schema creation
})
# Register models
api.register_model(User)
api.register_model(Post)
# Create routes
router = Router(prefix="/users")
@router.get("/")
async def list_users() -> list[User]:
return await User.all()
@router.get("/{id}")
async def get_user(id: int) -> User | None:
return await User.find(id)
api.register_router(router)
# Run
if __name__ == "__main__":
api.run(mode="hybrid") # REST + GraphQL
Documentation
Full documentation available at docs/README.md with learning paths and guides:
Getting Started
- Installation & Setup - Installation methods (pip, clone, Poetry)
- Quick Start Tutorial - Build your first API in 5 minutes
Core Concepts
- Models & Data - Define models with relationships
- REST Routing - Create REST endpoints
- Database Configuration - All supported databases
- GraphQL - GraphQL schema and queries
Advanced Topics
- Middleware & Authentication - Security and authorization
- Dependency Injection - Service management
- Developer Guide - Architecture and testing
Contributing & Deployment
- Contributing Guide - How to contribute to Guaro
- Development Setup - Local development environment
- Publishing Guide - Deploying to PyPI
- Changelog - Version history and roadmap
To Get Started
- Users: Follow the Installation & Setup guide
- Developers: See Development Setup for cloning and local setup
- Contributors: Read Contributing Guide and Developer Guide/ ├── middleware/ └── guaro/
## Quick start
```bash
python -m pip install -e .
python app.py
Example usage
from guaro import API, Model, Router, permission, require_auth
class User(Model):
id: int
name: str
email: str
router = Router(prefix="/users")
@router.get("/")
@require_auth
def get_users():
return User.all()
api = API()
api.register_model(User)
api.register_router(router)
api.run(mode="hybrid")
Database Configuration
Guaro supports fully externalized, environment-driven database configuration. Configuration is decoupled from application code and can be environment-specific (dev/staging/prod).
Configuration Patterns
Pattern 1: Default Configuration (Automatic SQLite)
Works out of the box with zero configuration:
from guaro import API
api = API() # Automatically uses sqlite+aiosqlite:///guaro.db
api.run()
Pattern 2: Inline Configuration
Convenient for quick prototypes and testing:
from guaro import API, DatabaseEngine
api = API(
database={
"url": "sqlite+aiosqlite:///local.db",
"engine": DatabaseEngine.SQLITE,
"auto_migrate": True,
"pool_size": 2,
"echo": True,
}
)
api.run()
Pattern 3: External Configuration (Recommended)
Production-grade pattern — configuration is isolated from application code:
config.py:
from guaro import DatabaseEngine
# Development
dev_config = {
"url": "sqlite+aiosqlite:///guaro_dev.db",
"engine": DatabaseEngine.SQLITE,
"auto_migrate": True,
}
# Staging
staging_config = {
"url": "postgresql+asyncpg://user:pass@db-staging.internal/guaro_staging",
"engine": DatabaseEngine.POSTGRESQL,
"auto_migrate": True,
"pool_size": 10,
}
# Production
prod_config = {
"url": "postgresql+asyncpg://user:pass@db-prod.internal/guaro_prod",
"engine": DatabaseEngine.POSTGRESQL,
"auto_migrate": False, # Migrations run separately
"pool_size": 20,
}
# Load based on environment
import os
environment = os.getenv("ENVIRONMENT", "dev")
database_config = locals()[f"{environment}_config"]
app.py:
from guaro import API
from config import database_config
api = API(database=database_config)
api.run()
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
url |
str | "sqlite+aiosqlite:///guaro.db" |
Database connection URL |
engine |
DatabaseEngine | inferred from URL or SQLITE | Database engine type |
auto_migrate |
bool | True |
Run migrations automatically on startup |
pool_size |
int | 5 |
Connection pool size |
pool_pre_ping |
bool | True |
Test connections before use |
echo |
bool | False |
Log all SQL statements |
timeout |
int | 30 |
Connection timeout in seconds |
extra |
dict | {} |
Engine-specific options |
Supported Engines
from guaro import DatabaseEngine
DatabaseEngine.SQLITE # SQLite (default)
DatabaseEngine.POSTGRESQL # PostgreSQL
DatabaseEngine.MYSQL # MySQL
DatabaseEngine.MONGODB # MongoDB
DatabaseEngine.MEMORY # In-memory cache
URL Format
Guaro normalizes URLs into transport strings that are passed to adapters. The engine determines how the URL is interpreted:
- SQLite:
sqlite+aiosqlite:///path/to/db.db - PostgreSQL:
postgresql+asyncpg://user:pass@host:port/dbname - MySQL:
mysql+aiomysql://user:pass@host:port/dbname - MongoDB:
mongodb://user:pass@host:port/dbname - Custom:
https://db.api.company.com/api(engine must be specified)
Environment-Based Configuration
For multi-environment deployments:
# Development (automatic SQLite)
python app.py
# Staging environment
export ENVIRONMENT=staging
python app.py
# Production environment
export ENVIRONMENT=prod
python app.py
In config.py:
import os
environment = os.getenv("ENVIRONMENT", "dev")
database_config = locals()[f"{environment}_config"]
Advanced Configuration
With extra options for engine-specific settings:
database_config = {
"url": "postgresql+asyncpg://user@localhost/guaro",
"engine": DatabaseEngine.POSTGRESQL,
"pool_size": 15,
"pool_pre_ping": True,
"echo": False,
"timeout": 45,
"extra": {
"ssl": "require",
"application_name": "guaro_api",
"statement_cache_size": 100,
},
}
This repository contains a production-oriented MVP architecture, not a finished distributed system. The implementation focuses on:
- unified metadata registration
- shared execution and planning
- automatic REST and GraphQL generation
- request-scoped batching and caching hooks
Startup modes
restserves only REST routesgraphqlserves only GraphQLhybridserves both simultaneously
Metadata
Release files for guaro 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| guaro-0.2.0.tar.gz | 36.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| guaro-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.8 kB
Release files / guaro-0.2.0.tar.gz
| Download URL | guaro-0.2.0.tar.gz |
|---|---|
| Size | 36.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6c6a95d19678a0e0216140bb6cc8f988683bc57317cff5222c0ec0facb40e3d0
|
|
BLAKE2b-256 checksum How to use checksums |
8c4641feb2c4f1a750db62a9fad3fb3af172960bb051b8af5210159d6a9de839
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.8
|
Release files / guaro-0.2.0-py3-none-any.whl
| Download URL | guaro-0.2.0-py3-none-any.whl |
|---|---|
| Size | 46.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
972b5e41c2c08916bc0471d96166c0f773e1f32e787795cc22786fe8bbd6681e
|
|
BLAKE2b-256 checksum How to use checksums |
14b163b52c35a5a04e54ed4b44a776c7e529dfb3f63ed7e1047a0eee0c412729
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.8
|
Security for guaro 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.