Observed since 20 Oct, 20:12 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
aegis-admin
Enterprise Admin Framework for FastAPI — auto-generates admin UI and JSON API for SQLAlchemy models
Aegis is an enterprise admin framework for FastAPI that auto-generates a full admin UI and JSON API for your SQLAlchemy models — with zero boilerplate.
<select> or live-search autocompletepip install aegis-admin
Also install an async database driver, e.g.
aiosqlitefor SQLite orasyncpgfor PostgreSQL.
from fastapi import FastAPI
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.ext.asyncio import create_async_engine
from aegis.core.app import Aegis
from aegis.core.auth import AllowAllAuthBackend # swap for your own in production
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String(100))
email = Column(String(200))
app = FastAPI()
engine = create_async_engine("sqlite+aiosqlite:///./app.db")
aegis = Aegis(
app=app,
engines={"default": engine},
auth_backend=AllowAllAuthBackend(), # replace with your auth backend
title="My Admin",
)
aegis.register(User)
Already have a non-async FastAPI project? Pass a regular create_engine — no async driver needed.
from fastapi import FastAPI
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import DeclarativeBase
from aegis.core.app import Aegis
from aegis.core.auth import AllowAllAuthBackend
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String(100))
email = Column(String(200))
app = FastAPI()
engine = create_engine("sqlite:///./app.db") # standard sync engine — no aiosqlite needed
aegis = Aegis(
app=app,
engines={"default": engine},
auth_backend=AllowAllAuthBackend(),
title="My Admin",
)
aegis.register(User)
Aegis detects sync vs async engines automatically — no configuration required.
Visit http://localhost:8000/admin/ui/ to see the admin panel.
Aegis does not ship with a built-in login page — it integrates with your project's existing auth system via the AuthBackend interface.
from fastapi import Request
from aegis.core.auth import AuthBackend
class MyAuthBackend(AuthBackend):
async def get_current_user(self, request: Request):
# Resolve the user from a cookie, JWT, session, etc.
token = request.cookies.get("session")
return await db.get_user_by_token(token) # your existing logic
async def is_authenticated(self, user) -> bool:
# Return True only if this user may access the admin
return user is not None and user.is_admin
Common patterns:
| Pattern | How |
|---|---|
| Cookie / session | Read request.session["user_id"] (requires SessionMiddleware) |
| JWT | Decode request.headers["Authorization"] or a cookie |
| Reuse existing dependency | Call your verify_token() / get_current_user() directly |
When a request is not authenticated, Aegis automatically redirects UI routes to login_url (default /login).
For every registered model, Aegis creates:
| Method | Path | Description |
|---|---|---|
GET | /admin/{table}/ | JSON list — paginated, searchable, filterable |
GET | /admin/ui/{table}/ | HTML list view with search + bulk delete |
GET/POST | /admin/ui/{table}/create/ | Create form |
GET/POST | /admin/ui/{table}/{pk}/edit/ | Edit form |
GET/POST | /admin/ui/{table}/{pk}/delete/ | Delete confirmation |
POST | /admin/ui/{table}/bulk-delete/ | Bulk delete confirmation |
GET | /admin/api/{table}/autocomplete/ | FK autocomplete search |
GET /admin/users/?limit=50&offset=0&search=alice&role=admin
| Param | Description |
|---|---|
limit | Max 100, default 50 |
offset | Pagination offset |
search | ILIKE search across all string columns |
<column> | Exact-match filter on any column |
aegis = Aegis(
app=app,
engines={
"default": primary_engine,
"analytics": analytics_engine,
},
auth_backend=MyAuthBackend(),
)
aegis.register(User) # uses "default"
aegis.register(Report, database="analytics")
aegis = Aegis(
app=app,
engines={"default": engine},
auth_backend=MyAuthBackend(),
base_path="/admin", # URL prefix (default: /admin)
title="My Admin", # Shown in the UI header
login_url="/login", # Redirect target when unauthenticated
)
MIT
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
fastapiEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | fastapi>=0.100.0 | runtime |
sqlalchemyEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | sqlalchemy>=2.0 | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pytest>=7.0; extra == "dev" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.23; extra == "dev" | runtime |
httpxEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.24; extra == "dev" | runtime |
aiosqliteEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | aiosqlite; extra == "dev" | runtime |
uvicornEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | uvicorn; extra == "dev" | runtime |
bdist_wheel · 24.83 KB · Python py3
sdist · 20.52 KB · Python source
Observed since 20 Oct, 20:12 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:57d8397b878dfddace7eba8a0cb2a016f559b8a55ffe474b38ce7de5d7b9949c