CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-robyn

A Super Fast Async Python Web Framework with a Rust runtime.

Pending
Overview
Eval results
Files

openapi.mddocs/

OpenAPI Integration

Automatic API documentation generation with Swagger UI, route documentation, schema definitions, and custom OpenAPI specification support for comprehensive API documentation.

Capabilities

OpenAPI Generator

Main class for managing OpenAPI specification generation and documentation.

class OpenAPI:
    def add_openapi_path_obj(
        self, 
        route_type, 
        endpoint: str, 
        openapi_name: str, 
        openapi_tags: Optional[list], 
        handler
    ):
        """
        Add a route to the OpenAPI specification.
        
        Args:
            route_type: HTTP method type
            endpoint: URL endpoint pattern
            openapi_name: Name for the operation in OpenAPI docs
            openapi_tags: List of tags for grouping operations
            handler: Route handler function
        """
    
    def get_openapi_docs_page(self) -> str:
        """
        Generate Swagger UI HTML page for API documentation.
        
        Returns:
            HTML string containing Swagger UI interface
        """
    
    def get_openapi_config(self) -> dict:
        """
        Get the complete OpenAPI specification as a dictionary.
        
        Returns:
            OpenAPI specification dictionary following OpenAPI 3.0 standard
        """
    
    def override_openapi(self, openapi_json_spec_path: str):
        """
        Override auto-generated OpenAPI spec with custom specification.
        
        Args:
            openapi_json_spec_path: Path to custom OpenAPI JSON specification file
        """

Route Documentation

Use decorators with OpenAPI parameters to document routes automatically.

# HTTP method decorators support OpenAPI documentation parameters
@app.get(
    endpoint="/users/{user_id}",
    openapi_name="Get User by ID", 
    openapi_tags=["Users"]
)
def get_user(request):
    """Route handler with OpenAPI documentation"""

@app.post(
    endpoint="/users",
    openapi_name="Create User",
    openapi_tags=["Users", "Management"]
)
def create_user(request):
    """Route handler with multiple OpenAPI tags"""

Usage Examples

Basic OpenAPI Setup

from robyn import Robyn, OpenAPI

# Create app with OpenAPI support
app = Robyn(__file__, openapi=OpenAPI())

# Document routes with OpenAPI metadata
@app.get("/", openapi_name="Get Root", openapi_tags=["General"])
def root(request):
    """Root endpoint returning welcome message"""
    return {"message": "Welcome to the API"}

@app.get("/users", openapi_name="List Users", openapi_tags=["Users"])
def list_users(request):
    """Get list of all users"""
    return {"users": ["alice", "bob", "charlie"]}

@app.get("/users/<user_id>", openapi_name="Get User", openapi_tags=["Users"])
def get_user(request):
    """Get specific user by ID"""
    user_id = request.path_params["user_id"]
    return {"user_id": user_id, "name": f"User {user_id}"}

@app.post("/users", openapi_name="Create User", openapi_tags=["Users", "Management"])
def create_user(request):
    """Create a new user"""
    user_data = request.json()
    return {"message": "User created", "data": user_data}

# Serve OpenAPI documentation
@app.get("/docs")
def docs(request):
    return app.openapi.get_openapi_docs_page()

@app.get("/openapi.json")
def openapi_spec(request):
    return app.openapi.get_openapi_config()

app.start()

Custom OpenAPI Specification

from robyn import Robyn, OpenAPI
import json

app = Robyn(__file__)

# Create custom OpenAPI specification
custom_spec = {
    "openapi": "3.0.0",
    "info": {
        "title": "My Custom API",
        "description": "A comprehensive API for managing users and resources",
        "version": "1.0.0",
        "contact": {
            "name": "API Support",
            "url": "https://example.com/support",
            "email": "support@example.com"
        },
        "license": {
            "name": "MIT",
            "url": "https://opensource.org/licenses/MIT"
        }
    },
    "servers": [
        {
            "url": "https://api.example.com/v1",
            "description": "Production server"
        },
        {
            "url": "https://staging-api.example.com/v1", 
            "description": "Staging server"
        }
    ],
    "paths": {
        "/users": {
            "get": {
                "summary": "List all users",
                "description": "Retrieve a paginated list of all users in the system",
                "tags": ["Users"],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Page number for pagination",
                        "required": False,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 1
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query", 
                        "description": "Number of users per page",
                        "required": False,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List of users",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "users": {
                                            "type": "array",
                                            "items": {"$ref": "#/components/schemas/User"}
                                        },
                                        "pagination": {
                                            "$ref": "#/components/schemas/Pagination"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "summary": "Create a new user",
                "description": "Create a new user account with the provided information",
                "tags": ["Users"],
                "requestBody": {
                    "required": True,
                    "content": {
                        "application/json": {
                            "schema": {"$ref": "#/components/schemas/CreateUserRequest"}
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "User created successfully",
                        "content": {
                            "application/json": {
                                "schema": {"$ref": "#/components/schemas/User"}
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid input data",
                        "content": {
                            "application/json": {
                                "schema": {"$ref": "#/components/schemas/Error"}
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "User": {
                "type": "object",
                "required": ["id", "username", "email"],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Unique user identifier"
                    },
                    "username": {
                        "type": "string",
                        "description": "Username for the account",
                        "minLength": 3,
                        "maxLength": 50
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "description": "User's email address"
                    },
                    "full_name": {
                        "type": "string",
                        "description": "Full name of the user"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Account creation timestamp"
                    }
                }
            },
            "CreateUserRequest": {
                "type": "object",
                "required": ["username", "email", "password"],
                "properties": {
                    "username": {
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 50
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "password": {
                        "type": "string",
                        "minLength": 8,
                        "description": "User password (will be hashed)"
                    },
                    "full_name": {
                        "type": "string"
                    }
                }
            },
            "Pagination": {
                "type": "object",
                "properties": {
                    "page": {
                        "type": "integer",
                        "description": "Current page number"
                    },
                    "limit": {
                        "type": "integer", 
                        "description": "Items per page"
                    },
                    "total": {
                        "type": "integer",
                        "description": "Total number of items"
                    },
                    "has_next": {
                        "type": "boolean",
                        "description": "Whether there are more pages"
                    }
                }
            },
            "Error": {
                "type": "object",
                "required": ["message"],
                "properties": {
                    "message": {
                        "type": "string",
                        "description": "Error message"
                    },
                    "code": {
                        "type": "string",
                        "description": "Error code"
                    },
                    "details": {
                        "type": "object",
                        "description": "Additional error details"
                    }
                }
            }
        },
        "securitySchemes": {
            "BearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "JWT"
            },
            "ApiKeyAuth": {
                "type": "apiKey",
                "in": "header",
                "name": "X-API-Key"
            }
        }
    },
    "security": [
        {"BearerAuth": []},
        {"ApiKeyAuth": []}
    ]
}

# Save custom spec to file
with open("custom_openapi.json", "w") as f:
    json.dump(custom_spec, f, indent=2)

# Use custom specification
openapi = OpenAPI()
openapi.override_openapi("custom_openapi.json")
app = Robyn(__file__, openapi=openapi)

# Implement the actual routes
@app.get("/users")
def list_users(request):
    page = int(request.query_params.get("page", "1"))
    limit = int(request.query_params.get("limit", "20"))
    
    # Simulate user data
    users = [
        {"id": i, "username": f"user{i}", "email": f"user{i}@example.com"}
        for i in range((page-1)*limit + 1, page*limit + 1)
    ]
    
    return {
        "users": users,
        "pagination": {
            "page": page,
            "limit": limit,
            "total": 1000,
            "has_next": page * limit < 1000
        }
    }

@app.post("/users")
def create_user(request):
    user_data = request.json()
    
    # Validate required fields
    if not all(field in user_data for field in ["username", "email", "password"]):
        return Response(400, {}, {
            "message": "Missing required fields",
            "code": "MISSING_FIELDS",
            "details": {"required": ["username", "email", "password"]}
        })
    
    # Simulate user creation
    new_user = {
        "id": 1001,
        "username": user_data["username"],
        "email": user_data["email"],
        "full_name": user_data.get("full_name"),
        "created_at": "2023-12-01T12:00:00Z"
    }
    
    return Response(201, {}, new_user)

# Documentation endpoints
@app.get("/docs")
def swagger_ui(request):
    return app.openapi.get_openapi_docs_page()

@app.get("/openapi.json") 
def openapi_json(request):
    return app.openapi.get_openapi_config()

app.start()

Advanced OpenAPI with Authentication

from robyn import Robyn, OpenAPI, AuthenticationHandler, BearerGetter

class SimpleAuthHandler(AuthenticationHandler):
    def __init__(self):
        super().__init__(BearerGetter())
    
    def authenticate(self, request):
        token = self.token_getter.get_token(request)
        if token == "valid-token":
            return Identity(claims={"user_id": "123", "role": "admin"})
        return None

app = Robyn(__file__)

# Configure authentication
auth_handler = SimpleAuthHandler()
app.configure_authentication(auth_handler)

# Public endpoints
@app.get("/", openapi_name="API Info", openapi_tags=["General"])
def api_info(request):
    """Get API information and status"""
    return {
        "name": "My Secure API",
        "version": "1.0.0",
        "status": "healthy"
    }

@app.post("/auth/login", openapi_name="Login", openapi_tags=["Authentication"])
def login(request):
    """Authenticate user and get access token"""
    credentials = request.json()
    # Simplified login logic
    if credentials.get("username") == "admin":
        return {"token": "valid-token", "expires_in": 3600}
    return Response(401, {}, {"error": "Invalid credentials"})

# Protected endpoints
@app.get("/profile", auth_required=True, openapi_name="Get Profile", openapi_tags=["User"])
def get_profile(request):
    """Get current user's profile (requires authentication)"""
    return {
        "user_id": request.identity.claims["user_id"],
        "role": request.identity.claims["role"]
    }

@app.get("/admin/stats", auth_required=True, openapi_name="Get Admin Stats", openapi_tags=["Admin"])
def admin_stats(request):
    """Get administrative statistics (requires authentication)"""
    if request.identity.claims.get("role") != "admin":
        return Response(403, {}, {"error": "Admin access required"})
    
    return {
        "total_users": 150,
        "active_sessions": 23,
        "server_uptime": "5 days"
    }

# Custom documentation with authentication info
@app.get("/docs")
def docs_with_auth(request):
    """Swagger UI with authentication support"""
    html = app.openapi.get_openapi_docs_page()
    
    # You could customize the HTML here to add authentication instructions
    auth_info = """
    <div style="background: #f8f9fa; padding: 15px; margin: 10px 0; border-radius: 5px;">
        <h4>Authentication</h4>
        <p>This API requires authentication for protected endpoints.</p>
        <p>To authenticate:</p>
        <ol>
            <li>Call POST /auth/login with {"username": "admin"}</li>
            <li>Copy the returned token</li>
            <li>Click "Authorize" button and enter: Bearer YOUR_TOKEN</li>
        </ol>
    </div>
    """
    
    # Insert auth info after the body tag
    html = html.replace("<body>", f"<body>{auth_info}")
    
    return html

app.start()

OpenAPI with Multiple Routers

from robyn import Robyn, SubRouter, OpenAPI

# Create app with OpenAPI
app = Robyn(__file__, openapi=OpenAPI())

# Create sub-routers with different purposes
api_v1 = SubRouter(__file__, prefix="/api/v1", openapi=OpenAPI())
admin_router = SubRouter(__file__, prefix="/admin", openapi=OpenAPI())

# API v1 routes
@api_v1.get("/users", openapi_name="List Users V1", openapi_tags=["Users", "V1"])
def list_users_v1(request):
    """List users - API Version 1"""
    return {"users": [], "version": "v1"}

@api_v1.post("/users", openapi_name="Create User V1", openapi_tags=["Users", "V1"])
def create_user_v1(request):
    """Create user - API Version 1"""
    return {"message": "User created", "version": "v1"}

# Admin routes
@admin_router.get("/dashboard", openapi_name="Admin Dashboard", openapi_tags=["Admin"])
def admin_dashboard(request):
    """Administrative dashboard overview"""
    return {"dashboard": "admin", "stats": {"users": 100}}

@admin_router.get("/logs", openapi_name="View Logs", openapi_tags=["Admin", "Logs"])
def view_logs(request):
    """View system logs"""
    return {"logs": ["Log entry 1", "Log entry 2"]}

# Include routers
app.include_router(api_v1)
app.include_router(admin_router)

# Main app routes
@app.get("/", openapi_name="Root", openapi_tags=["General"])
def root(request):
    """Root endpoint with API information"""
    return {
        "api": "My Multi-Router API",
        "version": "1.0.0",
        "endpoints": {
            "docs": "/docs",
            "openapi": "/openapi.json",
            "api_v1": "/api/v1",
            "admin": "/admin"
        }
    }

# Consolidated documentation
@app.get("/docs")
def comprehensive_docs(request):
    """Comprehensive API documentation"""
    return app.openapi.get_openapi_docs_page()

@app.get("/openapi.json")
def full_openapi_spec(request):
    """Complete OpenAPI specification"""
    return app.openapi.get_openapi_config()

app.start()

Install with Tessl CLI

npx tessl i tessl/pypi-robyn

docs

authentication.md

core-app.md

exceptions.md

index.md

mcp.md

openapi.md

request-response.md

status-codes.md

templating.md

websocket.md

tile.json