crudadmin Documentation

repository·main·Indexed 19 days ago

https://github.com/benavlabs/crudadmin

A FastAPI-based admin interface generator for managing SQLAlchemy models. Version 0.5.0 provides a production-ready dashboard featuring built-in authentication, event tracking, and CRUD operations. Key components include the CRUDAdmin and AdminSite classes for interface management, ModelView for defining model representations, and a SessionManager supporting multiple backends including Redis, Memcached, and Database storage. It includes an event system for audit logging and security monitoring using HTMX for the user interface.

Tokens
25.8K
Snippets
61
Records
82
Agent score
66%

What's inside crudadmin

  1. Overview of CRUDAdmin Session Backends

    main

    CRUDAdmin supports five session backend types, allowing you to choose between performance, scalability, and persistence based on your environment:

    BackendPerformanceScalabilityPersistenceAdmin VisibilityDependenciesUse Case
    MemoryExcellentSingle nodeNoNoNoneDevelopment, testing
    RedisExcellentHorizontalYes*NoRedis serverProduction, high traffic
    MemcachedExcellentHorizontalNoNoMemcached serverHigh performance caching
    DatabaseGoodVerticalYesYesNoneAudit requirements
    HybridExcellentHorizontalYesYesRedis/Memcached + DBProduction with audit

    *Redis persistence depends on your Redis configuration.

  2. Simulate Role-Based Access Control (RBAC) with multiple admin instances

    main

    CRUDAdmin does not currently have native built-in role-based access control. To simulate different access levels (e.g., Super Admin, Content Editor, Customer Service), you must create separate CRUDAdmin instances, each with its own mount_path, secret_key, and specific model views configured with varying permissions.

    Key strategies for simulating roles:

    • Super Admin: Full CRUD access to all models.
    • Limited Access (e.g., Editor): Set create_schema=None to prevent creation, or use specific update_schema models to restrict which fields can be modified.
    • Read-Only Access: Set create_schema=None, update_schema=None, and delete_permission=False.

    Trade-offs:

    • Pros: Simple implementation; complete separation of concerns; unique URLs for different roles.
    • Cons: Requires maintaining multiple instances; no shared sessions across different admin interfaces; users need separate credentials for each area.
    # Content Editor - Limited access
    content_admin = CRUDAdmin(
        session_backend="redis",
        secret_key="content-editor-secret", 
        title="Content Editor",
        mount_path="/content"
    )
    
    # Posts - Full access
    content_admin.add_view(
        model=Post,
        create_schema=PostCreate,
        update_schema=PostUpdate,
        read_schema=PostRead
    )
    
    # Comments - Read and moderate only
    content_admin.add_view(
        model=Comment,
        create_schema=None,  # No creation
        update_schema=CommentModerationUpdate,  # Limited updates
        read_schema=CommentRead,
        delete_permission=True  # Can delete inappropriate comments
    )
  3. Choose the right Session Storage Backend

    main

    Select a backend based on your performance, scalability, and visibility requirements:

    BackendPerformanceScalabilityPersistenceAdmin VisibilityUse Case
    MemoryExcellentSingle nodeNoNoDevelopment, testing
    RedisExcellentHorizontalYes*NoProduction, high traffic
    MemcachedExcellentHorizontalNoNoHigh performance caching
    DatabaseGoodVerticalYesYesAudit requirements
    HybridExcellentHorizontalYesYesBest of all worlds

    *Redis persistence depends on configuration.

  4. How admin user permissions and superuser status work

    main

    In CRUDAdmin, all AdminUser accounts are granted superuser privileges by default.

    Superuser capabilities include:

    • Full access to all admin interface features.
    • Ability to view, create, update, and delete all records (subject to model allowed_actions configuration).
    • Access to management features like health checks and event logs.
    • Ability to manage other admin users.

    Note: Deletion of an AdminUser is disabled within the interface to prevent accidental lockouts.

  5. Understand SessionData and Device Tracking

    main

    When a session is validated, it returns a SessionData object containing:

    • user_id: ID of the authenticated user.
    • session_id: Unique identifier.
    • ip_address: IP address at creation.
    • user_agent: Raw user agent string.
    • device_info: A dictionary containing parsed information:
      • browser (e.g., "Chrome")
      • browser_version (e.g., "120.0.0.0")
      • os (e.g., "Windows")
      • device (e.g., "PC")
      • is_mobile (bool)
      • is_tablet (bool)
      • is_pc (bool)
    • created_at / last_activity: Timestamps.
    • is_active: Boolean status.
    • metadata: Dictionary for custom session data.
  6. Understand Auto-Generated Forms from Pydantic Schemas

    main

    CRUDAdmin automatically generates UI forms based on your Pydantic schema definitions. The field types in the UI correspond to the types and constraints defined in your code.

    Field Mapping Examples

    Text Input Fields Defined with min_length or max_length constraints.

    username: str = Field(..., min_length=3, max_length=50)

    Generates: A required text input field.

    Email Fields Defined using EmailStr.

    email: EmailStr

    Generates: An email input field with built-in validation.

    Select Dropdowns Defined using regex patterns or specific choices.

    role: str = Field(..., pattern="^(admin|user|moderator)$")

    Generates: A dropdown menu with the specified options.

    Boolean Checkboxes Defined as boolean types.

    is_active: bool = True

    Generates: A checkbox, checked by default if the default value is True.

    Form Validation

    • Required Fields: Marked with an asterisk (*).
    • Error Feedback: Field-level errors appear directly below the problematic field. Form-level errors appear at the top of the form. The interface automatically focuses on the first error field found.
    # Schema definition examples
    username: str = Field(..., min_length=3, max_length=50)
    email: EmailStr
    role: str = Field(..., pattern="^(admin|user|moderator)$")
    is_active: bool = True
  7. Implement a Blog System with Multi-Model Relationships

    main

    To manage complex content like a blog, you can use a multi-model pattern involving Users, Categories, Tags, Posts, and Comments. This pattern utilizes SQLAlchemy for database modeling and Pydantic for data validation.

    Key Components:

    • Many-to-Many Relationships: Use a Table object as an association table (e.g., post_tags) to link models like Post and Tag via the secondary argument in SQLAlchemy's relationship().
    • One-to-Many Relationships: Use ForeignKey and relationship() with back_populates to link models like User to Post or Category to Post.
    • Pydantic Schemas: Define separate schemas for Create, Update, and Read operations for each model to ensure strict validation and proper data exposure (using from_attributes = True in the Config class).
    # Example SQLAlchemy Many-to-Many setup
    post_tags = Table('post_tags', Base.metadata,
        Column('post_id', Integer, ForeignKey('posts.id')),
        Column('tag_id', Integer, ForeignKey('tags.id'))
    )
    
    # In the Post model
    tags = relationship("Tag", secondary=post_tags, back_populates="posts")
  8. Use select_schema to handle problematic or sensitive fields

    main

    The select_schema parameter allows you to define a specific Pydantic schema for read operations (list and detail views). This is critical for:

    • Preventing Errors: Avoiding NotImplementedError caused by database types like PostgreSQL TSVector.
    • Performance: Excluding large binary or text fields (e.g., LargeBinary, Text) that slow down list views.
    • Security: Hiding sensitive fields (e.g., hashed_password, reset_token) from the admin interface while still allowing them to be managed via create_schema or update_schema.
    • UX: Using lightweight fields (like an excerpt) instead of heavy content fields for list views.

    Best Practices:

    1. Always include the primary key (id) in the select_schema.
    2. Include display-friendly fields (names, titles, dates).
    3. Keep create and update schemas separate from select_schema to maintain full field access for writes.
    # Example: Excluding a problematic TSVector field
    class DocumentSelect(BaseModel):
        id: int
        title: str
        content: str
        created_at: datetime
        # search_vector field is intentionally excluded!
    
    admin.add_view(
        model=Document,
        create_schema=DocumentCreate,
        update_schema=DocumentUpdate,
        select_schema=DocumentSelect,  # ✅ TSVector excluded from reads
        allowed_actions={"view", "create", "update", "delete"}
    )
  9. Understand the core components of CRUDAdmin

    main

    CRUDAdmin is built around five primary components that work together to provide a complete admin interface for FastAPI applications:

    1. CRUDAdmin Class: The central entry point. Use this to create the admin application, register models, and configure authentication and security.
    2. ModelView Class: Manages CRUD operations for specific SQLAlchemy models. It provides the UI for filtering, pagination, and bulk operations.
    3. AdminSite Class: The structural foundation. It manages routing, template rendering, and coordinates multiple ModelView instances.
    4. Session Management System: Handles secure authentication, CSRF protection, and session tracking. It supports multiple backends: Memory, Redis, Memcached, Database, and Hybrid.
    5. Event System: An audit trail system that logs admin actions, authentication events, and security activities.
  10. How hybrid sessions work

    main

    Hybrid mode combines the performance of a cache (Redis or Memcached) with the audit capabilities of a database.

    1. Active sessions are stored in Redis/Memcached for fast access.
    2. Session metadata is stored in the database for admin visibility.
    3. Session operations update both stores.
    4. Admin dashboard displays all sessions retrieved from the database.
    5. Performance is maintained via a cache-first approach.

    Use this mode in production environments that require both high performance and compliance/audit capabilities.

    from crudadmin import CRUDAdmin, RedisConfig
    
    # Redis for performance + Database for audit trail
    redis_config = RedisConfig(
        host="localhost",
        port=6379,
        db=0,
        password="redis-password"
    )
    
    admin = CRUDAdmin(
        session=get_session,
        SECRET_KEY="your-secret-key",
        session_backend="redis",
        redis_config=redis_config,
        track_sessions_in_db=True  # Enables hybrid mode
    )
  11. Control available actions for models

    main

    You can restrict what users can do with a specific model by passing a set of strings to the allowed_actions parameter in add_view(). This is useful for creating read-only views or preventing deletions.

    Available Actions

    • "view": Enables reading and listing records. Generates GET /admin/{model}/ and GET /admin/{model}/{id}.
    • "create": Enables record creation. Generates GET /admin/{model}/create and POST /admin/{model}/create.
    • "update": Enables editing records. Generates GET /admin/{model}/update/{id} and POST /admin/{model}/update/{id}.
    • "delete": Enables record deletion. Generates POST /admin/{model}/delete/{id}.

    Examples

    Read-only (View only):

    admin.add_view(
        model=AuditLog,
        create_schema=AuditLogSchema,
        update_schema=AuditLogSchema,
        allowed_actions={"view"}
    )

    No deletion allowed:

    admin.add_view(
        model=Order,
        create_schema=OrderCreate,
        update_schema=OrderUpdate,
        allowed_actions={"view", "create", "update"}
    )
  12. How CRUDAdmin architecture is organized

    main

    CRUDAdmin uses a layered modular architecture to separate concerns:

    Core Layer

    Handles the heavy lifting of security and data:

    • Authentication & Authorization: Role-based access control.
    • Session Management: Secure multi-backend storage.
    • Rate Limiting: Protection against brute force attacks.
    • Database Integration: Connects via SQLAlchemy and a FastCRUD backend.

    Interface Layer

    Handles the user-facing presentation:

    • Admin Site: Coordinates routing and the main interface.
    • Model Views: Provides the specific CRUD interfaces for models.
    • Template System: Uses HTMX for a responsive, modern UI.
    • Static Assets: Manages CSS, JS, and images.

    Event Layer

    Handles observability and security auditing:

    • Event Logging: Maintains an audit trail of all admin actions.
    • Security Events: Tracks authentication and authorization attempts.
    • Audit Integration: Supports automated logging via decorators.