Skip to main content

A FastAPI package for MongoDB admin operations with generic CRUD endpoints and admin UI

Project description

FastAPI Mongo Admin

A powerful FastAPI package that provides generic CRUD operations and a built-in admin UI for MongoDB collections. Perfect for rapid prototyping, database administration, and building admin interfaces for your MongoDB databases.

Description

FastAPI Mongo Admin is a comprehensive solution for managing MongoDB databases through a beautiful web interface. It automatically generates REST APIs and provides a full-featured admin panel with the following features:

Screenshots

List View

List View

Detail View

  • Full CRUD Operations: Create, read, update, and delete documents through REST endpoints or the web UI
  • Intelligent Schema Inference: Automatically detects collection schemas from existing documents, Pydantic models, or OpenAPI schemas
  • Modern Admin UI: React-based interface with dark mode, responsive design, and multi-language support (8 languages)
  • Advanced Data Management: Search, filter, sort, paginate, and bulk operations on documents
  • Analytics Dashboard: Generate charts and visualizations from your data with customizable aggregations
  • Data Import/Export: Export collections to JSON, CSV, HTML, XML, YAML, TOML formats or import data from files
  • Type Safety: Full type hints, async/await support, and Pydantic v2 integration
  • Zero Configuration: Works out of the box with minimal setup - just connect to your MongoDB database

Analytics Dashboard

Analytics Dashboard

Core Features

  • Generic CRUD Operations - Create, Read, Update, Delete operations for any MongoDB collection through REST endpoints or the web UI
  • Intelligent Schema Inference - Automatically analyze and infer collection schemas from existing documents, Pydantic models, or OpenAPI schemas
  • Pydantic Model Support - Infer schemas from Pydantic models when collections are empty
    • Flexible model input formats: list, dict, or auto-discovery
    • Smart model matching with plural/singular conversion
    • Explicit control with dict format or automatic with list format
  • OpenAPI Schema Discovery - Automatically discover and use Pydantic models from your FastAPI app's OpenAPI/Swagger documentation
  • Convenience Setup - mount_admin_app() function to set up router and UI in one call

Admin UI Features

  • Built-in Admin UI - Beautiful React-based web interface for database management with Tailwind CSS and reactive state management
  • Dark Mode Support - Toggle between light and dark themes with persistent preference and CSS file switching (no flicker on page reload)
  • Internationalization (i18n) - Multi-language support with 8 languages (English, French, Russian, Spanish, Portuguese, Chinese, Italian, German)
    • Automatic browser language detection on first visit
    • Language preference persistence in localStorage
    • Seamless language switching with instant UI updates
    • Comprehensive translations for all UI components
  • Advanced Filtering & Search - Server-side filtering with case-insensitive text search, enum matching, and date filtering
  • Sortable Tables - Click column headers to sort data ascending/descending
  • Paginated Forms - Forms automatically paginated with 5 fields per page for better UX
  • Analytics Dashboard - Generate charts and visualizations from your data with customizable aggregations (count, sum, average, min, max)
  • Data Import/Export - Export collections to JSON, CSV, HTML, XML, YAML, TOML formats or import data from files
  • Bulk Operations - Select and delete multiple documents at once
  • Field Selection - Choose which fields to display in the document table
  • Responsive Design - Works seamlessly on desktop and mobile devices

Technical Features

  • Automatic ObjectId Serialization - Seamless JSON serialization of MongoDB ObjectIds
  • Type Hints & Async Support - Full type hints and async/await support throughout
  • Error Handling - Comprehensive error handling and validation
  • FastAPI Integration - Seamlessly integrates with FastAPI applications
  • Zero Configuration - Works out of the box with minimal setup - just connect to your MongoDB database

Setup Instructions

Prerequisites

Before installing FastAPI Mongo Admin, ensure you have:

  • Python 3.9+ (Python 3.10+ recommended for full type support)
  • MongoDB installed and running (local or remote)
  • pip or Poetry for package management

Step 1: Install FastAPI Mongo Admin

Option A: Using pip

# Basic installation
pip install fastapi-mongo-admin

# With export functionality (for YAML, TOML, and other export formats)
pip install fastapi-mongo-admin[export]

# For development (includes dev dependencies)
pip install fastapi-mongo-admin[dev]

Option B: Using Poetry

# Basic installation
poetry add fastapi-mongo-admin

# With export functionality
poetry add fastapi-mongo-admin[export]

# For development
poetry add fastapi-mongo-admin[dev] --group dev

Step 2: Create Your FastAPI Application

Create a new file main.py:

from fastapi import FastAPI
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
from fastapi_mongo_admin import mount_admin_app

# Initialize FastAPI app
app = FastAPI(title="My MongoDB Admin App")

# Set up MongoDB connection
client = AsyncIOMotorClient("mongodb://localhost:27017")
database = client["my_database"]

# Create database dependency function
async def get_database() -> AsyncIOMotorDatabase:
    """Get database instance."""
    return database

# Mount admin app (router + UI) in one call
mount_admin_app(
    app,
    get_database,
    router_prefix="/admin",
    ui_mount_path="/admin-ui"
)

Step 3: Run the Application

# Install uvicorn if not already installed
pip install uvicorn

# Run the application
uvicorn main:app --reload

The application will start on http://localhost:8000 by default.

Step 4: Access the Admin Interface

Once the application is running:

  1. API Documentation (Swagger UI): http://localhost:8000/docs
  2. Admin UI: http://localhost:8000/admin-ui/admin.html

Step 5: Verify Setup

  1. Open the Admin UI in your browser
  2. You should see a sidebar with your MongoDB collections
  3. Click on a collection to browse documents
  4. Try creating a new document using the "Create Document" button

Configuration Options

Environment Variables

For production, use environment variables:

import os
from motor.motor_asyncio import AsyncIOMotorClient

# Get connection string from environment
mongodb_url = os.getenv("MONGODB_URL", "mongodb://localhost:27017")
db_name = os.getenv("MONGODB_DB_NAME", "my_database")

client = AsyncIOMotorClient(mongodb_url)
database = client[db_name]

Create a .env file:

MONGODB_URL=mongodb://localhost:27017
MONGODB_DB_NAME=my_database

MongoDB Connection with Authentication

from motor.motor_asyncio import AsyncIOMotorClient

client = AsyncIOMotorClient(
    "mongodb://username:password@localhost:27017",
    authSource="admin"
)
database = client["my_database"]

Requirements

  • Python: 3.9+ (3.10+ recommended)
  • FastAPI: 0.68.0+
  • Motor: 2.5.0+ (async MongoDB driver)
  • PyMongo: 4.0.0+
  • Pydantic: 2.0.0+ (v2 only, <3.0.0)

Note: The codebase uses Python 3.10+ type union syntax (|). For full Python 3.9 compatibility, you may need to use typing.Union or typing.Optional instead.

Quick Start

After completing the setup instructions above, you're ready to use FastAPI Mongo Admin! Here's a quick reference:

Minimal Example

from fastapi import FastAPI
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
from fastapi_mongo_admin import mount_admin_app

app = FastAPI(title="My MongoDB Admin App")
client = AsyncIOMotorClient("mongodb://localhost:27017")
database = client["my_database"]

async def get_database() -> AsyncIOMotorDatabase:
    return database

mount_admin_app(app, get_database, router_prefix="/admin", ui_mount_path="/admin-ui")

Running the Application

uvicorn main:app --reload

Then access:

Detailed Usage Guide

1. Setting Up MongoDB Connection

Basic Connection

from motor.motor_asyncio import AsyncIOMotorClient

client = AsyncIOMotorClient("mongodb://localhost:27017")
database = client["my_database"]

Connection with Authentication

from motor.motor_asyncio import AsyncIOMotorClient

client = AsyncIOMotorClient(
    "mongodb://username:password@localhost:27017",
    authSource="admin"
)
database = client["my_database"]

Connection with Environment Variables

import os
from motor.motor_asyncio import AsyncIOMotorClient

mongodb_url = os.getenv("MONGODB_URL", "mongodb://localhost:27017")
db_name = os.getenv("MONGODB_DB_NAME", "my_database")

client = AsyncIOMotorClient(mongodb_url)
database = client[db_name]

2. Creating the Admin Router

The create_router function accepts a database dependency function and optional configuration:

from fastapi_mongo_admin import create_router

# Basic usage
admin_router = create_router(get_database)

# With custom prefix
admin_router = create_router(
    get_database,
    prefix="/api/v1/admin"
)

# With custom prefix and tags
admin_router = create_router(
    get_database,
    prefix="/admin",
    tags=["admin", "database", "management"]
)

# With Pydantic models for schema inference
from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float
    description: str | None = None

# Dict format: exact matching (case-insensitive fallback)
pydantic_models = {"products": Product}  # Matches 'products' collection
# OR (exact key match, no auto-conversion)
pydantic_models = {"Product": Product}  # Matches 'Product' collection (not 'products')

# List format: auto-detects and converts
pydantic_models = [Product]  # Auto-converts to 'products' from model name

admin_router = create_router(
    get_database,
    pydantic_models=pydantic_models
)

# With automatic OpenAPI schema discovery
admin_router = create_router(
    get_database,
    app=app,  # Pass FastAPI app for auto-discovery
    # Optional: map collection names to schema names
    openapi_schema_map={"products": "Product"}
)

3. Mounting the Admin UI

The admin UI provides a web interface for managing your MongoDB collections:

Option 1: Using mount_admin_ui (Manual Setup)

from fastapi_mongo_admin import create_router, mount_admin_ui

# Create router
admin_router = create_router(
    get_database,
    prefix="/admin",
    ui_mount_path="/admin-ui"  # Optional: include admin UI URL in API docs
)
app.include_router(admin_router)

# Mount UI separately - api_prefix should match router prefix
mount_admin_ui(app, mount_path="/admin-ui", api_prefix="/admin")

Option 2: Using mount_admin_app (Convenience Function)

The mount_admin_app function combines router creation and UI mounting in one call:

from fastapi_mongo_admin import mount_admin_app

# Mount everything at once (router + UI)
admin_router = mount_admin_app(
    app,
    get_database,
    router_prefix="/admin",
    ui_mount_path="/admin-ui",
    mount_ui=True  # Set to False to skip UI mounting
)

# With Pydantic models (flexible matching supported)
from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float

# Dict format: exact matching
admin_router = mount_admin_app(
    app,
    get_database,
    pydantic_models={"products": Product}  # Matches 'products' collection exactly
)
# OR (exact key match)
admin_router = mount_admin_app(
    app,
    get_database,
    pydantic_models={"Product": Product}  # Matches 'Product' collection (not 'products')
)

# List format: auto-detects and converts
admin_router = mount_admin_app(
    app,
    get_database,
    pydantic_models=[Product]  # Auto-converts to 'products' collection
)

# With explicit model mapping
admin_router = mount_admin_app(
    app,
    get_database,
    pydantic_models={"my_products": Product}
)

4. Complete Example

Here's a complete example with error handling and logging:

from contextlib import asynccontextmanager
from fastapi import FastAPI
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
from fastapi_mongo_admin import create_router, mount_admin_ui
import logging

logger = logging.getLogger(__name__)

# MongoDB connection
client = AsyncIOMotorClient("mongodb://localhost:27017")
database = client["my_database"]

async def get_database() -> AsyncIOMotorDatabase:
    """Get database instance."""
    return database

@asynccontextmanager
async def lifespan(app: FastAPI):
    """Application lifespan manager."""
    # Startup
    logger.info("Starting application...")
    yield
    # Shutdown
    logger.info("Shutting down application...")
    client.close()

app = FastAPI(
    title="MongoDB Admin API",
    description="Admin interface for MongoDB",
    version="1.0.0",
    lifespan=lifespan
)

# Create and include admin router
admin_router = create_router(
    get_database,
    prefix="/admin",
    tags=["admin"]
)
app.include_router(admin_router)

# Mount admin UI
if mount_admin_ui(app, mount_path="/admin-ui", api_prefix="/admin"):
    logger.info("Admin UI available at /admin-ui/admin.html")

API Reference

Admin Information Endpoint

Get Admin Router Information

GET /admin/

Response:

{
  "prefix": "/admin",
  "collections_endpoint": "/admin/collections",
  "status": "ok",
  "admin_ui_url": "/admin-ui/admin.html"
}

Note: The admin_ui_url field is only included if the admin UI is mounted and the ui_mount_path parameter is provided when creating the router.

Collections Endpoints

List All Collections

GET /admin/collections

Response:

{
  "collections": ["users", "products", "orders"]
}

Get Collection Schema

GET /admin/collections/{collection_name}/schema?sample_size=10

Parameters:

  • collection_name (path): Name of the collection
  • sample_size (query, optional): Number of documents to sample (default: 10, max: 100)

Schema Inference Priority:

The system uses intelligent model matching:

  • Always: Exact collection name matches and case-insensitive matching
  • Only for list format: Singular/plural variations and automatic model name to collection name conversion
  • For dict format: Exact key matching only (no auto-conversion) - gives you explicit control

Schema Inference Priority:

  1. Existing documents in the collection (if any)
  2. Registered Pydantic models (if provided via pydantic_models parameter)
  3. OpenAPI/Swagger schemas (if app parameter is provided)
  4. Empty schema (fallback)

Response:

{
  "fields": {
    "name": {
      "type": "str",
      "types": ["str"],
      "example": "John Doe",
      "nullable": false
    },
    "age": {
      "type": "int",
      "types": ["int"],
      "example": 30,
      "nullable": false
    }
  },
  "sample_count": 10,
  "source": "documents"
}

Response (from Pydantic model):

{
  "fields": {
    "name": {
      "type": "str",
      "types": ["str"],
      "example": "",
      "nullable": false
    },
    "price": {
      "type": "float",
      "types": ["float"],
      "example": 0.0,
      "nullable": false
    }
  },
  "sample_count": 0,
  "source": "pydantic_model"
}

Response (from OpenAPI):

{
  "fields": {
    "name": {
      "type": "str",
      "types": ["str"],
      "example": "",
      "nullable": false
    }
  },
  "sample_count": 0,
  "source": "openapi_schema"
}

Documents Endpoints

List Documents

GET /admin/collections/{collection_name}/documents?skip=0&limit=50&sort_field=name&sort_order=asc

Parameters:

  • collection_name (path): Name of the collection
  • skip (query, optional): Number of documents to skip (default: 0)
  • limit (query, optional): Maximum number of documents to return (default: 50, max: 1000)
  • sort_field (query, optional): Field name to sort by
  • sort_order (query, optional): Sort order - 'asc' or 'desc' (default: 'asc')

Response:

{
  "documents": [
    {
      "_id": "507f1f77bcf86cd799439011",
      "name": "John Doe",
      "age": 30
    }
  ],
  "total": 100,
  "skip": 0,
  "limit": 50
}

Search Documents

POST /admin/collections/{collection_name}/documents/search?skip=0&limit=50&sort_field=name&sort_order=asc
Content-Type: application/json

{
  "name": {"$regex": "John", "$options": "i"},
  "age": {"$gte": 18}
}

Parameters:

  • collection_name (path): Name of the collection
  • skip (query, optional): Number of documents to skip (default: 0)
  • limit (query, optional): Maximum number of documents to return (default: 50, max: 1000)
  • sort_field (query, optional): Field name to sort by
  • sort_order (query, optional): Sort order - 'asc' or 'desc' (default: 'asc')

Request Body:

  • MongoDB query object (JSON)

Response:

{
  "documents": [
    {
      "_id": "507f1f77bcf86cd799439011",
      "name": "John Doe",
      "age": 30
    }
  ],
  "total": 25,
  "skip": 0,
  "limit": 50
}

Get Single Document

GET /admin/collections/{collection_name}/documents/{document_id}

Response:

{
  "_id": "507f1f77bcf86cd799439011",
  "name": "John Doe",
  "age": 30,
  "email": "john@example.com"
}

Create Document

POST /admin/collections/{collection_name}/documents
Content-Type: application/json

{
  "name": "Jane Doe",
  "age": 25,
  "email": "jane@example.com"
}

Response:

{
  "_id": "507f1f77bcf86cd799439012",
  "name": "Jane Doe",
  "age": 25,
  "email": "jane@example.com"
}

Update Document

PUT /admin/collections/{collection_name}/documents/{document_id}
Content-Type: application/json

{
  "age": 26,
  "email": "jane.updated@example.com"
}

Response:

{
  "_id": "507f1f77bcf86cd799439012",
  "name": "Jane Doe",
  "age": 26,
  "email": "jane.updated@example.com"
}

Delete Document

DELETE /admin/collections/{collection_name}/documents/{document_id}

Response:

{
  "message": "Document deleted successfully",
  "id": "507f1f77bcf86cd799439012"
}

Advanced Usage

Using Pydantic Models for Schema Inference

When your collections are empty, you can use Pydantic models to define the schema. The system provides flexible model matching that handles various naming conventions:

Model Matching Features:

  • Exact match: Direct collection name to model key matching (always tried first)
  • Case-insensitive: Handles 'Users' vs 'users' automatically (always tried)
  • Singular/Plural variations: Only when models are passed as a list - automatically matches 'User' ↔ 'users', 'Product' ↔ 'products'
  • Automatic conversion: When using list format, model names like 'User' are automatically converted to 'users' collection name

Important: When passing a dictionary, the keys are matched exactly (with case-insensitive fallback). No automatic plural/singular conversion is performed. This allows you to have explicit control over the mapping.

from fastapi import FastAPI
from pydantic import BaseModel, Field
from fastapi_mongo_admin import create_router

# Define your Pydantic models
class Product(BaseModel):
    name: str = Field(..., description="Product name")
    price: float = Field(..., gt=0, description="Product price")
    description: str | None = Field(None, description="Product description")
    in_stock: bool = Field(default=True, description="In stock status")
    tags: list[str] = Field(default_factory=list)

class User(BaseModel):
    email: str = Field(..., description="User email")
    name: str = Field(..., description="User name")
    age: int | None = Field(None, ge=0, le=150)

app = FastAPI()

# Option 1: Explicit mapping (recommended for clarity and exact control)
# Keys are matched exactly (case-insensitive fallback only)
pydantic_models = {
    "products": Product,  # Matches 'products' collection exactly
    "users": User,        # Matches 'users' collection exactly
}

# Option 2: Use model names as keys - matches exactly, no auto-conversion
# If you use "User" as key, it will match "User" collection, NOT "users"
pydantic_models = {
    "User": User,        # Matches 'User' collection (exact match)
    "Product": Product,  # Matches 'Product' collection (exact match)
}

# Option 3: Pass as list - auto-detects and converts collection names
# This is the only format that does automatic plural/singular conversion
pydantic_models = [User, Product]  # Auto-converts to {"users": User, "products": Product}

# Create router with Pydantic models
admin_router = create_router(
    get_database,
    prefix="/admin",
    pydantic_models=pydantic_models
)

Note:

  • Option 1 and 3 will match 'users' and 'products' collections
  • Option 2 will match 'User' and 'Product' collections (exact key matching)
  • Use list format (Option 3) if you want automatic plural/singular conversion
  • Use dict format (Options 1 or 2) if you want explicit, exact control over the mapping

Automatic OpenAPI Schema Discovery

The package can automatically discover Pydantic models from your FastAPI application's OpenAPI/Swagger schema:

from fastapi import FastAPI
from pydantic import BaseModel
from fastapi_mongo_admin import create_router

# Define your models anywhere in your code
class Product(BaseModel):
    name: str
    price: float
    description: str | None = None

class User(BaseModel):
    email: str
    name: str
    age: int | None = None

app = FastAPI()

# Just pass the app - models are auto-discovered!
admin_router = create_router(
    get_database,
    prefix="/admin",
    app=app,  # Enables automatic model discovery
)

app.include_router(admin_router)

How it works:

  • The system automatically scans your OpenAPI schema for Pydantic models
  • Collection names are matched to model names (case-insensitive)
  • Handles singular/plural variations (e.g., "products" → "Product")
  • Falls back gracefully if no matching model is found

Manual Schema Mapping:

If your collection name doesn't match the model name, provide explicit mapping:

admin_router = create_router(
    get_database,
    app=app,
    openapi_schema_map={
        "my_products": "Product",  # Collection → Model
        "customers": "User",       # Different names
    }
)

Using Schema Utilities

The package provides utilities for schema introspection and ObjectId serialization:

from fastapi_mongo_admin import (
    infer_schema,
    infer_schema_from_pydantic,
    infer_schema_from_openapi,
    serialize_object_id
)
from motor.motor_asyncio import AsyncIOMotorCollection
from pydantic import BaseModel
from bson import ObjectId

# Infer schema from a collection
async def analyze_collection(collection: AsyncIOMotorCollection):
    schema = await infer_schema(collection, sample_size=20)
    print(f"Collection has {len(schema['fields'])} fields")
    for field_name, field_info in schema['fields'].items():
        print(f"{field_name}: {field_info['type']}")

# Infer schema from Pydantic model
class Product(BaseModel):
    name: str
    price: float

schema = infer_schema_from_pydantic(Product)
print(schema)  # {'fields': {...}, 'sample_count': 0, 'source': 'pydantic_model'}

# Infer schema from OpenAPI
from fastapi import FastAPI
app = FastAPI()
schema = infer_schema_from_openapi(app, "products", schema_name="Product")

# Serialize ObjectIds in documents
document = {
    "_id": ObjectId(),
    "user_id": ObjectId(),
    "tags": [ObjectId(), ObjectId()],
    "metadata": {
        "created_by": ObjectId()
    }
}

serialized = serialize_object_id(document)
# All ObjectIds are now strings

Custom Database Dependency with Error Handling

from fastapi import HTTPException
from motor.motor_asyncio import AsyncIOMotorDatabase

async def get_database() -> AsyncIOMotorDatabase:
    """Get database with error handling."""
    try:
        # Check if database is accessible
        await database.client.admin.command("ping")
        return database
    except Exception as e:
        raise HTTPException(
            status_code=503,
            detail=f"Database connection failed: {str(e)}"
        )

Integration with FastAPI Dependencies

from fastapi import Depends
from fastapi_mongo_admin import create_router

# Use FastAPI's dependency injection
async def get_database() -> AsyncIOMotorDatabase:
    return database

# The router will use this dependency
admin_router = create_router(get_database)
app.include_router(admin_router)

Multiple Database Support

from fastapi import FastAPI
from motor.motor_asyncio import AsyncIOMotorClient
from fastapi_mongo_admin import create_router

app = FastAPI()

# Connect to multiple databases
client = AsyncIOMotorClient("mongodb://localhost:27017")
db1 = client["database1"]
db2 = client["database2"]

async def get_db1():
    return db1

async def get_db2():
    return db2

# Create separate routers for each database
admin_router_1 = create_router(get_db1, prefix="/admin/db1")
admin_router_2 = create_router(get_db2, prefix="/admin/db2")

app.include_router(admin_router_1)
app.include_router(admin_router_2)

Using the Admin UI

The admin UI provides a web-based interface for managing your MongoDB collections:

  1. Access the UI: Navigate to http://localhost:8000/admin-ui/admin.html
  2. Select Language: Use the language selector in the header to switch between 8 supported languages (English, French, Russian, Spanish, Portuguese, Chinese, Italian, German). Your preference is automatically saved and the UI detects your browser language on first visit.
  3. Toggle Dark Mode: Click the theme toggle button to switch between light and dark themes (preference is saved, no flicker on page reload)
  4. Select Collection: Choose a collection from the sidebar
  5. View Documents: Browse documents with pagination and search
  6. Sort Data: Click any column header to sort ascending/descending
  7. Filter Documents: Use filters for enum, boolean, and date fields
  8. Search: Search across text fields with case-insensitive matching
  9. Create Documents: Use paginated forms (5 fields per page) to create new documents
  10. Edit Documents: Click on a document to edit it with paginated form
  11. View Document Details: Click on _id to view full document details
  12. Delete Documents: Delete documents with confirmation modal
  13. View Schema: See the inferred schema for each collection
  14. Navigate ObjectIds: Click on ObjectId fields to navigate to referenced documents

Features:

  • Responsive Design: Built with Tailwind CSS
  • Internationalization: Support for 8 languages with automatic browser language detection
  • Dark Mode: Toggle between light and dark themes with persistent preference (no flicker on reload)
  • Reactive UI: Custom reactive state management with Store pattern
  • Type Preservation: Maintains data types when creating/editing documents
  • Smart Forms: Form fields automatically generated based on schema types with pagination
  • Sortable Tables: Click headers to sort by any column
  • Advanced Filtering: Server-side filtering with enum, boolean, date, and text field support
  • Collapsible Sidebar: Toggle sidebar visibility
  • Modal Dialogs: Centered modals for viewing and editing

Error Handling

The package includes comprehensive error handling:

  • 404 Not Found: When a document or collection doesn't exist
  • 500 Internal Server Error: For database connection issues
  • Validation Errors: For invalid query parameters

Example error response:

{
  "detail": "Document not found"
}

Best Practices

1. Environment Variables

Always use environment variables for sensitive configuration:

import os
from motor.motor_asyncio import AsyncIOMotorClient

mongodb_url = os.getenv("MONGODB_URL")
client = AsyncIOMotorClient(mongodb_url)

2. Connection Pooling

Motor handles connection pooling automatically, but you can configure it:

client = AsyncIOMotorClient(
    "mongodb://localhost:27017",
    maxPoolSize=50,
    minPoolSize=10
)

3. Security Considerations

Important: The admin endpoints provide full access to your database. In production:

  • Add authentication/authorization middleware
  • Restrict access to admin endpoints
  • Use HTTPS
  • Limit access by IP address
  • Consider using environment-specific configurations

Example with authentication:

from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials

security = HTTPBearer()

async def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
    if credentials.credentials != "your-secret-token":
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials"
        )
    return credentials.credentials

# Protect admin router
admin_router = create_router(get_database, prefix="/admin")
app.include_router(admin_router, dependencies=[Depends(verify_token)])

4. Logging

Enable logging for debugging:

import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Log database operations
logger.info(f"Connected to database: {database.name}")

Troubleshooting

Common Issues

1. Connection Refused

Error: [Errno 61] Connection refused

Solution: Ensure MongoDB is running and the connection string is correct.

2. Authentication Failed

Error: Authentication failed

Solution: Check your MongoDB credentials and authSource.

3. Admin UI Not Loading

Solution: Ensure the static files are properly mounted:

# Check if mount was successful
if mount_admin_ui(app, mount_path="/admin-ui"):
    print("Admin UI mounted successfully")
else:
    print("Failed to mount - check static files")

4. ObjectId Serialization Issues

If you encounter serialization errors, ensure you're using the provided utility:

from fastapi_mongo_admin import serialize_object_id

# Serialize before returning
return serialize_object_id(document)

Development

Setting Up Development Environment

# Clone the repository
git clone https://github.com/tushortz/fastapi-mongo-admin.git
cd fastapi-mongo-admin

# Install in editable mode with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black fastapi_mongo_admin/

# Lint code
ruff check fastapi_mongo_admin/

Examples

Basic Example

See the example_usage.py file in the package for a complete working example.

Example with Pydantic Models

from fastapi import FastAPI
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
from pydantic import BaseModel, Field
from fastapi_mongo_admin import create_router, mount_admin_ui

# Define your Pydantic models
class Product(BaseModel):
    name: str = Field(..., description="Product name")
    price: float = Field(..., gt=0)
    description: str | None = None
    in_stock: bool = Field(default=True)

class User(BaseModel):
    email: str
    name: str
    age: int | None = None

app = FastAPI(title="MongoDB Admin with Models")

client = AsyncIOMotorClient("mongodb://localhost:27017")
database = client["my_database"]

async def get_database() -> AsyncIOMotorDatabase:
    return database

# Option 1: Explicit Pydantic models
pydantic_models = {
    "products": Product,
    "users": User,
}
admin_router = create_router(
    get_database,
    prefix="/admin",
    pydantic_models=pydantic_models
)

# Option 2: Automatic discovery from OpenAPI
admin_router = create_router(
    get_database,
    prefix="/admin",
    app=app,  # Auto-discovers Product and User models
)

app.include_router(admin_router)
mount_admin_ui(app, mount_path="/admin-ui", api_prefix="/admin")

Example with Automatic Schema Discovery

from fastapi import FastAPI
from pydantic import BaseModel
from fastapi_mongo_admin import create_router, mount_admin_ui

# Define models - they'll be auto-discovered!
class Product(BaseModel):
    name: str
    price: float
    description: str | None = None

app = FastAPI()

# Create router with app for auto-discovery
admin_router = create_router(
    get_database,
    app=app,  # Enables automatic model discovery
)

app.include_router(admin_router)
mount_admin_ui(app, mount_path="/admin-ui", api_prefix="/admin")

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see LICENSE file for details.

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_mongo_admin-0.1.2.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_mongo_admin-0.1.2-py3-none-any.whl (1.1 MB view details)

Uploaded Python 3

File details

Details for the file fastapi_mongo_admin-0.1.2.tar.gz.

File metadata

  • Download URL: fastapi_mongo_admin-0.1.2.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for fastapi_mongo_admin-0.1.2.tar.gz
Algorithm Hash digest
SHA256 874336e3fd59bf85155bfdc8b6eb0db9681c91d120fcac2e5631f6196f57f376
MD5 2304f104b259a8d18fd36d251d077504
BLAKE2b-256 728f5415496e733f389f0579e79809c584d9c90da328e9b65b99f8e5d6fb10bb

See more details on using hashes here.

File details

Details for the file fastapi_mongo_admin-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_mongo_admin-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 dd01fa82dd22f9c53c53c9eeb923e8b7e231aa6a78c805b7b928c560f01f4061
MD5 b77ae5c830e8bf6e3c061fb8824a894c
BLAKE2b-256 22ee1e1d50716437e93ff2ae2367d6b7530c44ca71392a30ef3ca91007d9b891

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page