Guaro: Unified REST + GraphQL framework with auto-migration and multi-database support
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file guaro-0.2.0.tar.gz.
File metadata
- Download URL: guaro-0.2.0.tar.gz
- Upload date:
- Size: 36.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c6a95d19678a0e0216140bb6cc8f988683bc57317cff5222c0ec0facb40e3d0
|
|
| MD5 |
2a1a0ebeed2016869a021ba20bccb56b
|
|
| BLAKE2b-256 |
8c4641feb2c4f1a750db62a9fad3fb3af172960bb051b8af5210159d6a9de839
|
File details
Details for the file guaro-0.2.0-py3-none-any.whl.
File metadata
- Download URL: guaro-0.2.0-py3-none-any.whl
- Upload date:
- Size: 46.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
972b5e41c2c08916bc0471d96166c0f773e1f32e787795cc22786fe8bbd6681e
|
|
| MD5 |
88bc188526c86cf3b26b4d53ad70f939
|
|
| BLAKE2b-256 |
14b163b52c35a5a04e54ed4b44a776c7e529dfb3f63ed7e1047a0eee0c412729
|