Supero Python SDK
The AI-native backend platform. Build complete APIs in minutes, not months.
Supero transforms your data schemas into a full-featured backend with REST APIs, CRUD operations, queries, aggregations, relationships, multi-tenancy, and AI agents — all without writing backend code.
✨ The Magic of Supero
┌─────────────────────────────────────────────────────────────────┐
│ │
│ UPLOAD YOUR JSON SCHEMAS │
│ ↓ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ SUPERO GENERATES: │ │
│ │ │ │
│ │ ✓ REST APIs ✓ Database Tables │ │
│ │ ✓ Authentication ✓ Authorization │ │
│ │ ✓ Multi-Tenancy ✓ Data Isolation │ │
│ │ ✓ AI Agents ✓ Natural Language │ │
│ │ ✓ Vector Search ✓ Conversation Memory │ │
│ │ ✓ Python SDK ✓ Type Safety │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ↓ │
│ │
│ YOUR SAAS PLATFORM IS READY! │
│ │
│ In minutes, not months. No backend team required. │
│ │
└─────────────────────────────────────────────────────────────────┘
Table of Contents
- Installation
- Quick Start
- Authentication
- Schema Definition
- CRUD Operations
- Query Builder
- Aggregations
- References (Relationships)
- Parent-Child Hierarchies
- Bulk Operations
- Convenience Methods
- Error Handling
- Typed SDK
- AI Features
- RBAC & API Keys
- Multi-Tenant Architecture
- Complete API Reference
- Examples
Installation
From PyPI
pip install supero
Domain-Specific Wheel (For Production)
Once you've set up your domain, you can generate a typed SDK wheel:
org.install_sdk() # Generates supero_acme-1.0.0-py3-none-any.whl
Then distribute and install the wheel:
pip install supero_acme-1.0.0-py3-none-any.whl
What's Inside the Domain Wheel?
| Build Type | Wheel Name | Contents |
|---|---|---|
| Platform | supero-1.0.0-py3-none-any.whl |
Base SDK for setup |
| Domain | supero_<domain>-1.0.0-py3-none-any.whl |
Typed models + API client |
Benefits of domain wheels:
- ✅ Full IDE auto-completion for your schemas
- ✅ Type safety and editor warnings
- ✅ Single file deployment
- ✅ Multiple domains can coexist
Quick Start
The Flow
1. Register Domain → 2. Create Project → 3. Upload Schemas → 4. CRUD
1. Register Domain (First Time)
from supero import register_domain
org = register_domain(
domain_name="acme",
admin_email="admin@acme.com",
admin_password="SecurePass123!"
)
This creates your organization with the necessary infrastructure.
2. Create Your Project
project = org.Project.create(name="ecommerce", description="E-commerce Platform")
org = org.switch_project(project_name="ecommerce")
3. Upload Schemas
Create schemas/task.json:
{
"name": "task",
"fields": {
"title": {"type": "string", "required": true},
"done": {"type": "boolean", "default": false},
"priority": {"type": "string", "enum": ["low", "medium", "high"]}
}
}
Upload:
org.upload_schemas("schemas/")
That's it. You now have a full REST API for tasks.
4. Use Your API
# Create
task = org.crud.create("task", name="task-1", title="Learn Supero", priority="high")
# Read
task = org.crud.get("task", task["uuid"])
# Update
org.crud.update("task", task["uuid"], done=True)
# Delete
org.crud.delete("task", task["uuid"])
Returning Users - Login
from supero import login
# Single-tenant app
org = login("acme", "user@acme.com", "password", project="ecommerce")
# Multi-tenant app
org = login("acme", "user@acme.com", "password", project="hr-system", tenant="sales")
Authentication
Register New Domain
from supero import register_domain
org = register_domain(
domain_name="acme",
admin_email="admin@acme.com",
admin_password="SecurePass123!"
)
# Create your application project
project = org.Project.create(name="myapp")
org = org.switch_project(project_name="myapp")
Login with Credentials
from supero import login
# Single-tenant (tenant is auto-created)
org = login("acme", "user@acme.com", "password", project="myapp")
# Multi-tenant (specify tenant)
org = login("acme", "user@acme.com", "password", project="saas-app", tenant="customer-a")
Token-Based Authentication (Production)
For frontends, microservices, or APIs, use token-based auth:
from supero import login, quickstart
# Step 1: Login to get a token
org = login("acme", "user@acme.com", "password", project="myapp")
token = org.jwt_token # Save this (e.g., localStorage, config, env var)
# Step 2: Later, reconnect without credentials
org = quickstart("acme", "myapp", jwt_token=token)
# Multi-tenant
org = quickstart("acme", "saas-app", jwt_token=token, tenant="customer-a")
Get JWT via REST API
curl -X POST https://api.supero.dev/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"domain": "acme",
"project": "myapp",
"email": "user@acme.com",
"password": "your-password"
}'
# Response: {"token": "eyJhbGc...", "expires_in": 86400}
Login with API Key
from supero import quickstart
org = quickstart("acme", "myapp", api_key="ak_prod_123")
Schema Definition
Schemas define your data models. Place JSON files in a schemas/ directory.
Basic Schema
{
"name": "customer",
"fields": {
"email": {"type": "string", "required": true, "unique": true},
"company": {"type": "string"},
"tier": {"type": "string", "enum": ["free", "pro", "enterprise"], "default": "free"},
"active": {"type": "boolean", "default": true}
}
}
Field Types
| Type | JSON Example | Python Example | Notes |
|---|---|---|---|
string |
"hello" |
"hello" |
Text |
number |
42, 3.14 |
42, 3.14 |
Integer or float |
boolean |
true, false |
True, False |
|
array |
["a", "b"] |
["a", "b"] |
List of values |
object |
{"key": "val"} |
{"key": "val"} |
Nested object |
datetime |
"2024-01-15T10:30:00Z" |
"2024-01-15T10:30:00Z" |
ISO 8601 format |
Field Options
| Option | Type | Description |
|---|---|---|
type |
string | Field type (required) |
required |
boolean | Field must be provided |
default |
any | Default value if not provided |
unique |
boolean | Value must be unique across all objects |
enum |
array | Allowed values |
Schema with References
{
"name": "order",
"fields": {
"total": {"type": "number", "required": true},
"status": {"type": "string", "enum": ["pending", "shipped", "delivered"], "default": "pending"}
},
"refs": {
"customer": {"type": "customer"},
"products": {"type": "product", "many": true}
}
}
Upload Schemas
# Upload all schemas from directory
org.upload_schemas("schemas/")
# Upload single schema
org.upload_schema("schemas/task.json")
CRUD Operations
All CRUD operations are available via org.crud.
Create
task = org.crud.create("task",
name="task-001",
title="Learn Supero",
priority="high"
)
# Returns: {"uuid": "...", "name": "task-001", "title": "Learn Supero", ...}
Read
# Get by UUID
task = org.crud.get("task", "uuid-here")
# Get by name
task = org.crud.get_by_name("task", "task-001")
# Get by fully qualified name
task = org.crud.get_by_fq_name("task", ["my-app", "task-001"])
# List all
tasks = org.crud.list("task")
# List with pagination
tasks = org.crud.list("task", limit=10, offset=20)
Update
task = org.crud.update("task", "uuid-here", done=True, priority="low")
Delete
success = org.crud.delete("task", "uuid-here")
# Returns: True if deleted, False if failed
Query Builder
For complex queries, use the fluent query builder.
Basic Query
tasks = org.crud.query("task").all()
Filtering
# Single filter
tasks = org.crud.query("task").filter(done=False).all()
# Multiple filters (AND)
tasks = org.crud.query("task").filter(done=False, priority="high").all()
# Chained filters
tasks = org.crud.query("task") \
.filter(done=False) \
.filter(priority="high") \
.all()
Ordering
# Ascending
tasks = org.crud.query("task").order_by("created_at").all()
# Descending (prefix with -)
tasks = org.crud.query("task").order_by("-created_at").all()
# Multiple fields
tasks = org.crud.query("task").order_by("-priority", "created_at").all()
Pagination
# Limit and offset
tasks = org.crud.query("task").limit(10).offset(20).all()
# Page-based
tasks = org.crud.query("task").paginate(page=3, per_page=25).all()
Other Query Methods
# Get first match
task = org.crud.query("task").filter(priority="high").first()
# Check existence
exists = org.crud.query("task").filter(priority="high").exists()
# Count
count = org.crud.query("task").filter(done=False).count()
# Delete all matching
deleted = org.crud.query("task").filter(done=True).delete_all()
Shorthand: find()
tasks = org.crud.find("task", done=False, priority="high")
Aggregations
# Count
total = org.crud.count("task")
active = org.crud.count("task", done=False)
# Sum, Average, Min, Max
revenue = org.crud.sum("order", "amount")
avg_price = org.crud.avg("product", "price")
cheapest = org.crud.min("product", "price")
highest = org.crud.max("order", "amount")
# Distinct values
statuses = org.crud.distinct("order", "status")
# → ["pending", "shipped", "delivered"]
# Group by (count)
by_priority = org.crud.count_by("task", "priority")
# → {"low": 10, "medium": 25, "high": 5}
# Full stats
stats = org.crud.stats("order", "amount")
# → {"count": 100, "sum": 15000, "avg": 150.0, "min": 10, "max": 500}
References (Relationships)
Define References in Schema
{
"name": "order",
"fields": { "total": {"type": "number"} },
"refs": {
"customer": {"type": "customer"},
"products": {"type": "product", "many": true}
}
}
Use References
# Create objects
customer = org.crud.create("customer", name="cust-1", email="john@example.com")
order = org.crud.create("order", name="order-1", total=99.99)
# Link them
org.crud.set_ref("order", order["uuid"], "customer", customer["uuid"])
# With metadata
org.crud.set_ref("order", order["uuid"], "customer", customer["uuid"],
role="billing", notes="Primary contact")
# Get reference
ref = org.crud.get_ref("order", order["uuid"], "customer")
customer = ref["target"]
role = ref["link_data"]["role"]
# Remove reference
org.crud.remove_ref("order", order["uuid"], "customer")
Parent-Child Hierarchies
# Create parent
customer = org.crud.create("customer", name="acme-corp", email="contact@acme.com")
# Create child with parent reference
order = org.crud.create("order",
parent=customer,
name="order-001",
total=199.99
)
# fq_name will be: ["my-app", "acme-corp", "order-001"]
Bulk Operations
# Create many
tasks = org.crud.bulk_create("task", [
{"name": "task-1", "title": "First task", "priority": "high"},
{"name": "task-2", "title": "Second task", "priority": "medium"},
])
# Get many
tasks = org.crud.bulk_get("task", ["uuid-1", "uuid-2"])
# Update many
org.crud.bulk_update("task", [
{"uuid": "uuid-1", "done": True},
{"uuid": "uuid-2", "done": True},
])
# Delete many
org.crud.bulk_delete("task", ["uuid-1", "uuid-2"])
Convenience Methods
# Check existence
if org.crud.exists("user", email="admin@example.com"):
print("User exists")
# Get or create (idempotent)
task, created = org.crud.get_or_create("task", "task-001",
title="Default Title",
priority="medium"
)
# Update or create
task, created = org.crud.update_or_create("task", "task-001",
title="Updated Title",
done=True
)
Error Handling
# Safe get (returns None if not found)
task = org.crud.get("task", "invalid-uuid")
if task is None:
print("Not found")
# Safe delete (returns False if failed)
if not org.crud.delete("task", "invalid-uuid"):
print("Delete failed")
# Try/except
try:
task = org.crud.create("task", name="task-1", title="Test")
except Exception as e:
print(f"Create failed: {e}")
Typed SDK
Generate a typed SDK for full IDE auto-completion.
org.install_sdk()
Typed Usage
# Instead of string-based:
task = org.crud.create("task", name="t1", title="Learn Supero")
# Use typed access:
task = org.Task.create(name="t1", title="Learn Supero")
# Full examples
task = org.Task.get(uuid)
tasks = org.Task.find(done=False)
org.Task.update(uuid, done=True)
org.Task.delete(uuid)
# Query
tasks = org.Task.query().filter(done=False).order_by("-priority").all()
Comparison
| Feature | org.crud |
org.Task (Typed) |
|---|---|---|
| Auto-completion | ❌ | ✅ |
| Type hints | ❌ | ✅ |
| Typo detection | Runtime | Editor |
AI Features
Simple Chat
response = org.ai.chat("What projects do we have?")
print(response.content)
Quick Question
answer = org.ask("How many active projects are there?")
# → "You have 5 active projects."
Streaming
for chunk in org.ai.chat_stream("Explain our architecture"):
print(chunk, end="", flush=True)
Multi-Turn Conversations
session = org.ai.sessions.create()
org.ai.chat("List all projects", session_id=session.id)
org.ai.chat("Create a task for the first one", session_id=session.id)
org.ai.chat("Call it 'Setup CI/CD'", session_id=session.id)
Vector Search (RAG)
# Index
org.ai.vectors.index(
content="Project Alpha is our flagship e-commerce platform...",
metadata={"type": "project_doc"}
)
# Search
results = org.ai.vectors.search("how does authentication work?", limit=5)
Configure AI
org.ai.configure(
model="claude-sonnet-4-20250514",
max_tokens=8000,
temperature=0.5
)
RBAC & API Keys
# Pass api_key to CRUD operations
task = org.crud.create("task", name="t1", title="Test", api_key="user-key")
# Or with query builder
tasks = org.crud.query("task") \
.with_api_key("user-key") \
.filter(done=False) \
.all()
Multi-Tenant Architecture
Hierarchy
Domain ──→ Project ──→ Tenant ──→ User Account
│ │
│ └──→ Schemas (linked to project)
│
└──→ default-project / default-tenant (auto-created)
| Level | Description | Required? |
|---|---|---|
| Domain | Top-level organization | ✅ Yes |
| Project | Your application | ✅ Yes |
| Tenant | Isolated environment | Optional* |
| User | Individual account | ✅ Yes |
*Single-tenant apps: tenant is auto-created and abstracted away
*Multi-tenant apps: create and specify tenants explicitly
Single-Tenant vs Multi-Tenant
| Type | Tenant Handling | Login Example |
|---|---|---|
| Single-Tenant | Auto (abstracted) | login("acme", email, pwd, project="ecommerce") |
| Multi-Tenant | Explicit | login("acme", email, pwd, project="hr", tenant="sales") |
Multi-Tenant Setup
from supero import register_domain, login
# Setup (as admin)
org = register_domain("acme", "admin@acme.com", "SecurePass123!")
org.Project.create(name="hr-system")
org = org.switch_project(project_name="hr-system")
# Create tenants
org.Tenant.create(name="sales")
org.Tenant.create(name="payroll")
org.upload_schemas("schemas/")
# Usage: Each tenant has isolated data
sales = login("acme", "sales@acme.com", "password", project="hr-system", tenant="sales")
payroll = login("acme", "payroll@acme.com", "password", project="hr-system", tenant="payroll")
sales.crud.create("employee", name="alice", department="Sales")
payroll.crud.create("payslip", name="pay-001", amount=5000)
# Data is isolated!
sales.crud.list("employee") # Only sales data
payroll.crud.list("payslip") # Only payroll data
Domain Wheel Distribution
SDK is generated at the domain level. Project/tenant are specified at login:
pip install supero_acme-1.0.0-py3-none-any.whl
from supero import login, quickstart
# Same wheel, different project/tenant
ecom = login("acme", "user@acme.com", "pass", project="ecommerce")
sales = login("acme", "user@acme.com", "pass", project="hr-system", tenant="sales")
# Or with tokens (after obtaining from login)
ecom_token = ecom.token
ecom = quickstart("acme", "ecommerce", jwt_token=ecom_token)
Complete API Reference
Setup Methods
| Method | Description |
|---|---|
register_domain(domain_name, admin_email, admin_password) |
Create new domain |
org.Project.create(name, description=) |
Create project |
org.Tenant.create(name, description=) |
Create tenant |
org.switch_project(project_name=, tenant_name=) |
Switch context |
login(domain, email, password, project=, tenant=) |
Login with credentials |
quickstart(domain, project, *, jwt_token=, tenant=) |
Connect with token |
org.upload_schemas(path) |
Upload schemas |
org.install_sdk() |
Generate typed SDK |
CRUD Methods
| Method | Returns | Description |
|---|---|---|
create(type, name=, **fields) |
dict |
Create object |
get(type, uuid) |
dict | None |
Get by UUID |
get_by_name(type, name) |
dict | None |
Get by name |
list(type, limit=, offset=) |
list |
List all |
update(type, uuid, **fields) |
dict |
Update object |
delete(type, uuid) |
bool |
Delete object |
Query Methods
| Method | Returns | Description |
|---|---|---|
query(type) |
QueryBuilder |
Start query |
find(type, **filters) |
list |
Shorthand filter |
.filter(**conditions) |
QueryBuilder |
Add filters |
.order_by(*fields) |
QueryBuilder |
Set ordering |
.limit(n) / .offset(n) |
QueryBuilder |
Pagination |
.all() |
list |
Execute query |
.first() |
dict | None |
Get first |
.count() |
int |
Count matches |
.exists() |
bool |
Check existence |
Aggregation Methods
| Method | Returns | Description |
|---|---|---|
count(type, **filters) |
int |
Count objects |
sum(type, field, **filters) |
number |
Sum field |
avg(type, field, **filters) |
number |
Average field |
min/max(type, field) |
number |
Min/max value |
distinct(type, field) |
list |
Unique values |
count_by(type, field) |
dict |
Group counts |
stats(type, field) |
dict |
Full statistics |
Reference Methods
| Method | Returns | Description |
|---|---|---|
set_ref(type, uuid, ref_field, ref_uuid, **link_data) |
dict |
Create link |
get_ref(type, uuid, ref_field) |
dict | None |
Get link |
remove_ref(type, uuid, ref_field) |
bool |
Remove link |
Bulk Methods
| Method | Returns | Description |
|---|---|---|
bulk_create(type, items) |
list |
Create multiple |
bulk_get(type, uuids) |
list |
Get multiple |
bulk_update(type, updates) |
list |
Update multiple |
bulk_delete(type, uuids) |
int |
Delete multiple |
AI Methods
| Method | Returns | Description |
|---|---|---|
org.ai.chat(message, session_id=) |
Response |
Chat with AI |
org.ai.chat_stream(message) |
Iterator |
Streaming chat |
org.ask(question) |
str |
Quick Q&A |
org.ai.sessions.create() |
Session |
Create session |
org.ai.vectors.index(content, metadata=) |
str |
Index document |
org.ai.vectors.search(query, limit=) |
list |
Semantic search |
Examples
E-Commerce App (Single-Tenant)
from supero import register_domain, login
# Setup
org = register_domain("acme", "admin@acme.com", "SecurePass123!")
org.Project.create(name="ecommerce")
org = org.switch_project(project_name="ecommerce")
org.upload_schemas("schemas/")
# Usage
org = login("acme", "user@acme.com", "password", project="ecommerce")
customer = org.crud.create("customer", name="john", email="john@example.com")
order = org.crud.create("order", parent=customer, name="order-001", total=99.99)
org.crud.set_ref("order", order["uuid"], "customer", customer["uuid"])
revenue = org.crud.sum("order", "total", status="completed")
print(f"Revenue: ${revenue}")
HR System (Multi-Tenant)
from supero import register_domain, login
# Setup
org = register_domain("acme", "admin@acme.com", "SecurePass123!")
org.Project.create(name="hr-system")
org = org.switch_project(project_name="hr-system")
org.Tenant.create(name="sales")
org.Tenant.create(name="payroll")
org.upload_schemas("schemas/")
# Usage - isolated data per tenant
sales = login("acme", "sales@acme.com", "pass", project="hr-system", tenant="sales")
payroll = login("acme", "payroll@acme.com", "pass", project="hr-system", tenant="payroll")
sales.crud.create("employee", name="alice", department="Sales")
payroll.crud.create("payslip", name="pay-001", amount=5000)
AI-Powered App
from supero import login
org = login("acme", "admin@acme.com", "pass", project="myapp")
session = org.ai.sessions.create()
org.ai.chat("List all projects", session_id=session.id)
org.ai.chat("Create a task for the first one", session_id=session.id)
for chunk in org.ai.chat_stream("Generate a status report"):
print(chunk, end="", flush=True)
Best Practices
- Use meaningful names —
name="acme-corp-2024"notname="customer1" - Use get_or_create for idempotency — Safe to call multiple times
- Use bulk operations — One API call instead of many
- Handle None returns —
get()returnsNoneif not found - Use Typed SDK in production — Full IDE support and type safety
Troubleshooting
"name field is required"
# Wrong
org.crud.create("task", title="My Task")
# Correct
org.crud.create("task", name="task-001", title="My Task")
"parent must have uuid and object_type"
# Wrong
org.crud.create("order", parent={"name": "cust-1"}, ...)
# Correct
customer = org.crud.get("customer", uuid)
org.crud.create("order", parent=customer, ...)
🚀 Build the Future of SaaS with Supero
Upload your schemas → Get a complete backend with AI in minutes, not months.
Documentation • GitHub • Support
Built with ❤️ by the Supero Team
Metadata
Release files for supero 3.7.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| supero-3.7.2-py3-none-any.whl | Python 3 | none | any | Details |
Release files / supero-3.7.2-py3-none-any.whl
| Download URL | supero-3.7.2-py3-none-any.whl |
|---|---|
| Size | 4.3 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4041ec0da8b9cbc858e98aac79041c821c2de98788c6c1fed37bb4b56c13aa85
|
|
BLAKE2b-256 checksum How to use checksums |
039baa96454d79e7d048e9de6ae9f3e5d845c53ff32c10c6172e3cc0b59a5a33
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|