Catalog PyPI
PACKAGE EXPLORERView in registry

aegis-admin

PyPI

Enterprise Admin Framework for FastAPI — auto-generates admin UI and JSON API for SQLAlchemy models

adminadmin-panelasynccrudfastapisqlalchemy
Versions collected1
Direct dependencies7From release 0.1.1
Last observed20 Oct, 20:12 UTC

README

Version 0.1.1 documentation

Aegis Admin

PyPI version Python License: MIT

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.


Features

  • Auto-generated admin UI — list, create, edit, delete for every registered model
  • Searchable list views — ILIKE search across all string columns
  • Bulk delete — select multiple records and delete in one action
  • FK dropdowns & autocomplete — foreign key fields render as <select> or live-search autocomplete
  • JSON API endpoints — paginated, filterable, searchable REST endpoints alongside the UI
  • Pluggable auth — bring your own session, JWT, OAuth2, or any custom backend
  • Multi-database support — register models against different database engines
  • Async-first — built on SQLAlchemy 2.0 async engine

Installation

pip install aegis-admin

Also install an async database driver, e.g. aiosqlite for SQLite or asyncpg for PostgreSQL.


Quick Start

Async project (SQLAlchemy async engine)

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)

Sync project (standard SQLAlchemy engine)

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.


Authentication

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:

PatternHow
Cookie / sessionRead request.session["user_id"] (requires SessionMiddleware)
JWTDecode request.headers["Authorization"] or a cookie
Reuse existing dependencyCall your verify_token() / get_current_user() directly

When a request is not authenticated, Aegis automatically redirects UI routes to login_url (default /login).


Endpoints Generated

For every registered model, Aegis creates:

MethodPathDescription
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

JSON API query parameters

GET /admin/users/?limit=50&offset=0&search=alice&role=admin
ParamDescription
limitMax 100, default 50
offsetPagination offset
searchILIKE search across all string columns
<column>Exact-match filter on any column

Multiple Databases

aegis = Aegis(
    app=app,
    engines={
        "default": primary_engine,
        "analytics": analytics_engine,
    },
    auth_backend=MyAuthBackend(),
)

aegis.register(User)                        # uses "default"
aegis.register(Report, database="analytics")

Configuration

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
)

License

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.19 Mar 20267

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
arjunpotter17/aegis

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 20:12 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:7c1a3a42a9d8d9f5f916d621ced52c6868f19956ce0d4ccf3b54f35c2bd956c9