Skip to main content

A powerful, reusable package for generating comprehensive OpenAPI documentation with Flask-Pydantic-Spec

Project description

Flask OpenAPI Documentation Package

A powerful, reusable package for generating comprehensive OpenAPI documentation with Flask-Pydantic-Spec. Features custom metadata, security schemes, and flexible configuration options.

✨ Features

  • Flexible Configuration: Easy-to-use configuration system for API metadata
  • Custom Security Schemes: Support for multiple authentication types
  • Tag-based Organization: Group endpoints by functionality
  • Route Format Control: Choose between Flask (<string:param>) and OpenAPI ({param}) formats
  • Automatic Schema Registration: Seamless Pydantic model integration
  • Backward Compatibility: Drop-in replacement for existing setups
  • Zero Dependencies: Only requires flask-pydantic-spec and pydantic

🚀 Quick Start

Basic Usage

from flask import Flask
from quas_docs import FlaskOpenAPISpec, DocsConfig, SecurityScheme, endpoint

# Create configuration
config = DocsConfig(
    title="My API",
    version="0.0.1",
    description="A sample API with comprehensive documentation",
    contact=ContactInfo(
        email="api@example.com",
        name="API Team"
    )
)

# Initialize the spec
spec = FlaskOpenAPISpec(config)

# Create Flask app
app = Flask(__name__)

# Add endpoints with metadata
@app.post("/users")
@endpoint(
    request_body=CreateUserRequest,
    security=SecurityScheme.BEARER_AUTH,
    tags=["Users"],
    summary="Create New User",
    description="Creates a new user account with validation"
)
def create_user():
    return {"message": "User created"}

# Initialize documentation
spec.init_app(app)

Dynamic Configuration Methods

from quas_docs import FlaskOpenAPISpec, DocsConfig

# Method 1: From dictionary (recommended)
config = DocsConfig.from_dict({
    'title': 'My API',
    'version': '2.0.0',
    'description': 'API built with dynamic configuration',
    'contact': {
        'email': 'dev@mycompany.com',
        'name': 'Development Team',
        'url': 'https://mycompany.com'
    },
    'security_schemes': {
        'BearerAuth': {'description': 'JWT authentication'},
        'ApiKeyAuth': {
            'scheme_type': 'apiKey',
            'location': 'header',
            'parameter_name': 'X-API-Key',
            'description': 'API key authentication'
        }
    },
    'preserve_flask_routes': True
})

# Method 2: From environment variables
config = DocsConfig.from_env(prefix="MY_API_")

# Method 3: Create default and customize
config = DocsConfig.create_default()
config.title = "Custom API"
config.version = "2.0.0"

# Method 4: Manual construction
config = DocsConfig(
    title="Custom API",
    version="2.0.0",
    description="Custom API with specific requirements"
)

📋 Configuration Options

DocsConfig Class

@dataclass
class DocsConfig:
    # Basic API Information
    title: str = "Flask API"
    version: str = "0.0.1"
    description: Optional[str] = None
    terms_of_service: Optional[str] = None
    
    # Contact Information
    contact: Optional[ContactInfo] = None
    
    # License Information
    license_name: Optional[str] = None
    license_url: Optional[str] = None
    
    # Server Information
    servers: List[Dict[str, str]] = field(default_factory=list)
    
    # Security Schemes
    security_schemes: Dict[str, SecuritySchemeConfig] = field(default_factory=dict)
    
    # Customization Options
    preserve_flask_routes: bool = True  # Keep <string:param> format
    clear_auto_discovered: bool = True  # Remove auto-discovered duplicates
    add_default_responses: bool = True  # Add default response schemas
    
    # External Documentation
    external_docs_url: Optional[str] = None
    external_docs_description: Optional[str] = None

Security Schemes

from quas_docs import SecuritySchemeConfig

# API Key Authentication
api_key_config = SecuritySchemeConfig(
    name="ApiKeyAuth",
    scheme_type="apiKey",
    location="header",
    parameter_name="X-API-Key",
    description="API key authentication"
)

# Bearer Token Authentication
bearer_config = SecuritySchemeConfig(
    name="BearerAuth",
    scheme_type="apiKey",
    location="header", 
    parameter_name="Authorization",
    description="JWT Bearer token authentication"
)

# Add to configuration
config.add_security_scheme("ApiKeyAuth", api_key_config)
config.add_security_scheme("BearerAuth", bearer_config)

Contact Information

from quas_docs import ContactInfo

contact = ContactInfo(
    email="api@example.com",
    name="API Development Team",
    url="https://example.com/contact"
)

config.contact = contact

🎯 Endpoint Decoration

The @endpoint Decorator

@endpoint(
    request_body=Optional[Type[BaseModel]],      # Pydantic model for request body
    security=Optional[SecurityScheme],           # Security requirement
    tags=Optional[List[str]],                    # Organization tags
    summary=Optional[str],                       # Brief description
    description=Optional[str],                   # Detailed description
    query_params=Optional[List[QueryParameter]], # Query parameters for GET endpoints
    deprecated=bool,                             # Mark as deprecated
    **extra_metadata                             # Custom metadata
)

Examples

# Basic endpoint with request body
@app.post("/auth/login")
@endpoint(
    request_body=LoginRequest,
    tags=["Authentication"],
    summary="User Login",
    description="Authenticate user with email and password"
)
@spec.validate(resp=Response(HTTP_200=ApiResponse))
def login():
    return AuthController.login()

# Secured endpoint with query parameters
@app.get("/users")
@endpoint(
    security=SecurityScheme.BEARER_AUTH,
    tags=["Users"],
    summary="List Users",
    description="Get paginated list of users with filtering options",
    query_params=[
        QueryParameter("page", "integer", required=False, description="Page number", default=1),
        QueryParameter("per_page", "integer", required=False, description="Items per page", default=10),
        QueryParameter("search", "string", required=False, description="Search by name or email"),
        QueryParameter("active", "boolean", required=False, description="Filter by active status", default=True),
    ]
)
@spec.validate(resp=Response(HTTP_200=UsersListResponse))
def list_users():
    return UserController.list()

# Public endpoint with custom metadata
@app.get("/health")
@endpoint(
    tags=["System"],
    summary="Health Check",
    description="Check API health status",
    custom_field="health-check"  # Custom metadata
)
def health_check():
    return {"status": "healthy"}

🔧 Advanced Configuration

Custom Response Schemas

# The package automatically adds default response schemas
# You can disable this behavior:
config.add_default_responses = False

# Custom response schemas are preserved from @spec.validate decorators
@app.post("/users")
@endpoint(tags=["Users"])
@spec.validate(resp=Response(
    HTTP_201=CreateUserResponse,
    HTTP_400=ErrorResponse,
    HTTP_409=ConflictResponse
))
def create_user():
    return UserController.create()

Route Format Control

# Keep Flask format: /users/<string:user_id>
config.preserve_flask_routes = True

# Use OpenAPI format: /users/{user_id}  
config.preserve_flask_routes = False

Servers Configuration

# Add multiple servers
config.add_server("https://api.example.com", "Production")
config.add_server("https://staging-api.example.com", "Staging")
config.add_server("http://localhost:5000", "Development")

External Documentation

config.external_docs_url = "https://docs.example.com"
config.external_docs_description = "Complete API Documentation"

Environment Variable Configuration

Set environment variables and load them automatically:

# .env file or environment
export API_TITLE="My Project API"
export API_VERSION="1.2.0"
export API_DESCRIPTION="API for my awesome project"
export API_CONTACT_EMAIL="api@myproject.com"
export API_CONTACT_NAME="API Team"
export API_CONTACT_URL="https://myproject.com/contact"
export API_LICENSE_NAME="MIT"
export API_PRESERVE_FLASK_ROUTES="true"
# Load configuration from environment
config = DocsConfig.from_env()  # Uses API_ prefix by default

# Or use custom prefix
config = DocsConfig.from_env(prefix="MYAPI_")

📦 Integration Examples

Replace Existing Setup

If you have an existing Flask app with manual OpenAPI setup:

# OLD WAY
from flask_pydantic_spec import FlaskPydanticSpec
spec = FlaskPydanticSpec('flask', title='My API', version='0.0.1')

# NEW WAY
from quas_docs import FlaskOpenAPISpec, DocsConfig
config = DocsConfig(title='My API', version='0.0.1')
spec_instance = FlaskOpenAPISpec(config)
spec = spec_instance.spec  # For backward compatibility

Multiple APIs

# API 1: Public API
public_config = DocsConfig(
    title="Public API",
    version="0.0.1",
    preserve_flask_routes=True
)
public_spec = FlaskOpenAPISpec(public_config)

# API 2: Admin API  
admin_config = DocsConfig(
    title="Admin API",
    version="0.0.1",
    preserve_flask_routes=False
)
admin_spec = FlaskOpenAPISpec(admin_config)

Custom Project Setup

# projects/my_project/docs_config.py
from quas_docs import DocsConfig, ContactInfo, SecuritySchemeConfig

def create_my_project_config():
    config = DocsConfig(
        title="My Project API",
        version="2.1.0",
        description="Custom project with specific requirements",
        contact=ContactInfo(
            email="dev@myproject.com",
            name="Development Team",
            url="https://myproject.com"
        )
    )
    
    # Add custom security schemes
    config.add_security_scheme("ApiKey", SecuritySchemeConfig(
        name="ApiKey",
        parameter_name="X-API-Key",
        description="Project-specific API key"
    ))
    
    config.add_server("https://api.myproject.com", "Production")
    config.add_server("http://localhost:8000", "Development")
    
    return config

# projects/my_project/app.py
from quas_docs import FlaskOpenAPISpec
from .docs_config import create_my_project_config

config = create_my_project_config()
spec = FlaskOpenAPISpec(config)

🔄 Migration Guide

From Manual Setup

  1. Copy the docs/ folder to your project
  2. Replace your existing docs setup:
    # Replace your old setup with:
    from quas_docs import FlaskOpenAPISpec, DocsConfig, endpoint, SecurityScheme
    
    config = DocsConfig.from_dict({
        'title': 'Your API Name',
        'version': '0.0.1',
        # ... your settings
    })
    spec_instance = FlaskOpenAPISpec(config)
    spec = spec_instance.spec  # For @spec.validate decorators
    
  3. Use the @endpoint decorator:
    @endpoint(
        request_body=YourModel,
        security=SecurityScheme.BEARER_AUTH,
        tags=["Your Tag"],
        summary="Your Summary"
    )
    
  4. Initialize documentation:
    spec_instance.init_app(app)
    

Clean v1.0 Design

The package follows a clean, modern approach:

  • Single @endpoint decorator for all metadata
  • Configuration-driven setup
  • No legacy compatibility code
  • Streamlined API surface

📝 Best Practices

  1. Use meaningful tags to organize endpoints logically
  2. Provide clear summaries and descriptions for better developer experience
  3. Configure contact information for API support
  4. Use appropriate security schemes for different endpoint types
  5. Test documentation in both Swagger UI and Redoc
  6. Version your APIs properly using semantic versioning

🐛 Troubleshooting

Common Issues

Issue: Endpoints appear in "default" category Solution: Ensure clear_auto_discovered = True in config

Issue: Route parameters show wrong format Solution: Set preserve_flask_routes in config

Issue: Security schemes not working Solution: Verify security scheme names match those in config

Issue: Missing response schemas Solution: Check add_default_responses setting and @spec.validate decorators

📄 License

MIT License - feel free to use in your projects!

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Submit a pull request

Created by Emmanuel Olowu | GitHub | Website

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

quas_docs-0.0.3.tar.gz (17.8 kB view details)

Uploaded Source

Built Distribution

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

quas_docs-0.0.3-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file quas_docs-0.0.3.tar.gz.

File metadata

  • Download URL: quas_docs-0.0.3.tar.gz
  • Upload date:
  • Size: 17.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.5

File hashes

Hashes for quas_docs-0.0.3.tar.gz
Algorithm Hash digest
SHA256 5b43b9846cfafce625f6795798464dc63e49800341fd5d1fae07130775fe87cc
MD5 27a8744c931cd21d84d9b7f044249709
BLAKE2b-256 213001d394a44652a0d5fd0cab42bcbef235ec26f3767b96243d1d9a4a9b1feb

See more details on using hashes here.

File details

Details for the file quas_docs-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: quas_docs-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 13.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.5

File hashes

Hashes for quas_docs-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 905a018ba32b32c7f58daa561caa5c4f7303f7b634036ab7301d766f4f763600
MD5 6be72bb4827df7c40614ba6b03a7c6bc
BLAKE2b-256 f78b422c3e43bd61bfc5dcec051d0c202a5d74aac85f233ff06af444c8a2b318

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