OpenAPI/Swagger spec-first web framework for Python with automatic request validation and response serialization
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core application classes for creating Connexion-based web services. These classes provide different underlying frameworks and deployment models while maintaining a consistent interface for OpenAPI-driven development.
Native asynchronous ASGI application providing the best performance and modern Python async/await support. Recommended for new projects.
class AsyncApp:
def __init__(
self,
import_name: str,
*,
lifespan=None,
middlewares=None,
specification_dir: Union[pathlib.Path, str] = "",
arguments: dict = None,
auth_all_paths: bool = None,
jsonifier=None,
pythonic_params: bool = None,
resolver=None,
resolver_error: int = None,
strict_validation: bool = None,
swagger_ui_options=None,
uri_parser_class=None,
validate_responses: bool = None,
validator_map: dict = None,
security_map: dict = None
):
"""
Create a new AsyncApp instance.
Parameters:
- import_name: Name of the application module
- lifespan: ASGI lifespan handler
- middlewares: List of additional middlewares
- specification_dir: Directory containing OpenAPI specs
- arguments: Global arguments for spec templating
- auth_all_paths: Whether to authenticate all paths
- jsonifier: Custom JSON serializer
- pythonic_params: Convert parameter names to pythonic style
- resolver: Custom operation resolver
- resolver_error: Error code for unresolved operations
- strict_validation: Enable strict validation mode
- swagger_ui_options: SwaggerUI configuration options
- uri_parser_class: Custom URI parser class
- validate_responses: Enable response validation
- validator_map: Custom validator mapping
- security_map: Custom security handler mapping
"""
def add_api(
self,
specification: Union[pathlib.Path, str, dict],
*,
base_path: str = None,
name: str = None,
arguments: dict = None,
auth_all_paths: bool = None,
jsonifier=None,
pythonic_params: bool = None,
resolver=None,
resolver_error: int = None,
strict_validation: bool = None,
swagger_ui_options=None,
uri_parser_class=None,
validate_responses: bool = None,
validator_map: dict = None,
security_map: dict = None,
**kwargs
):
"""
Add an OpenAPI specification to the application.
Parameters:
- specification: OpenAPI specification as path, dict, or URL
- base_path: Override base path from spec
- name: Name to register the API with
- arguments: Arguments for spec templating
- auth_all_paths: Authenticate all paths override
- jsonifier: Custom JSON serializer override
- pythonic_params: Pythonic params override
- resolver: Custom operation resolver
- resolver_error: Error code for unresolved operations
- strict_validation: Strict validation override
- swagger_ui_options: SwaggerUI configuration options
- uri_parser_class: Custom URI parser override
- validate_responses: Response validation override
- validator_map: Custom validator mapping
- security_map: Custom security handler mapping
- **kwargs: Additional keyword arguments
Returns:
AsyncApi instance
"""
def run(
self,
host: str = None,
port: int = None,
debug: bool = None,
**options
):
"""
Run the application with uvicorn development server.
Parameters:
- host: Server host (default: 127.0.0.1)
- port: Server port (default: 5000)
- debug: Debug mode override
- **options: Additional uvicorn options
"""
async def __call__(self, scope: dict, receive, send):
"""ASGI application callable interface."""Flask-based WSGI application providing compatibility with Flask ecosystem and traditional deployment models.
class FlaskApp:
def __init__(
self,
import_name: str,
instance_relative_config: bool = False,
middlewares=None,
specification_dir: str = "",
arguments: dict = None,
auth_all_paths: bool = False,
jsonifier=None,
pythonic_params: bool = False,
options=None,
strict_validation: bool = False,
validate_responses: bool = False,
uri_parser_class=None,
debug: bool = False
):
"""
Create a new FlaskApp instance.
Parameters follow same pattern as AsyncApp with additional:
- instance_relative_config: Enable Flask instance-relative config
"""
def add_api(
self,
specification: Union[pathlib.Path, str, dict],
*,
base_path: str = None,
name: str = None,
arguments: dict = None,
auth_all_paths: bool = None,
jsonifier=None,
pythonic_params: bool = None,
resolver=None,
resolver_error: int = None,
strict_validation: bool = None,
swagger_ui_options=None,
uri_parser_class=None,
validate_responses: bool = None,
validator_map: dict = None,
security_map: dict = None,
**kwargs
):
"""
Add an OpenAPI specification to the Flask application.
Parameters match AsyncApp.add_api().
Returns:
FlaskApi instance
"""
def run(
self,
host: str = None,
port: int = None,
debug: bool = None,
load_dotenv: bool = True,
**options
):
"""
Run the Flask development server.
Parameters:
- host: Server host (default: 127.0.0.1)
- port: Server port (default: 5000)
- debug: Debug mode override
- load_dotenv: Load environment from .env file
- **options: Additional Flask run options
"""
@property
def app(self):
"""Access to underlying Flask application instance."""ASGI middleware for adding Connexion functionality to existing ASGI applications.
class ConnexionMiddleware:
def __init__(
self,
app,
*,
import_name: str = None,
lifespan=None,
middlewares=None,
specification_dir: Union[pathlib.Path, str] = "",
arguments: dict = None,
auth_all_paths: bool = None,
jsonifier=None,
pythonic_params: bool = None,
resolver=None,
resolver_error: int = None,
strict_validation: bool = None,
swagger_ui_options=None,
uri_parser_class=None,
validate_responses: bool = None,
validator_map: dict = None,
security_map: dict = None
):
"""
Wrap an existing ASGI application with Connexion middleware.
Parameters:
- app: ASGI application to wrap
- import_name: Name of the application module
- lifespan: ASGI lifespan handler
- middlewares: List of additional middlewares
- specification_dir: Directory containing OpenAPI specs
- arguments: Global arguments for spec templating
- auth_all_paths: Whether to authenticate all paths
- jsonifier: Custom JSON serializer
- pythonic_params: Convert parameter names to pythonic style
- resolver: Custom operation resolver
- resolver_error: Error code for unresolved operations
- strict_validation: Enable strict validation mode
- swagger_ui_options: SwaggerUI configuration options
- uri_parser_class: Custom URI parser class
- validate_responses: Enable response validation
- validator_map: Custom validator mapping
- security_map: Custom security handler mapping
"""
def add_api(
self,
specification: Union[pathlib.Path, str, dict],
*,
base_path: str = None,
name: str = None,
arguments: dict = None,
auth_all_paths: bool = None,
jsonifier=None,
pythonic_params: bool = None,
resolver=None,
resolver_error: int = None,
strict_validation: bool = None,
swagger_ui_options=None,
uri_parser_class=None,
validate_responses: bool = None,
validator_map: dict = None,
security_map: dict = None,
**kwargs
):
"""Add OpenAPI specification to middleware.
Parameters match AsyncApp.add_api()."""
async def __call__(self, scope: dict, receive, send):
"""ASGI middleware callable interface."""Base class for all Connexion applications providing common interface and functionality.
class AbstractApp:
def __init__(self, import_name: str, **kwargs):
"""Base application initialization."""
def add_api(self, specification: str, **kwargs):
"""Abstract method for adding OpenAPI specifications."""
def add_url_rule(
self,
rule: str,
endpoint: str = None,
view_func=None,
**options
):
"""
Add a URL routing rule.
Parameters:
- rule: URL rule pattern
- endpoint: Endpoint name
- view_func: View function to handle requests
- **options: Additional routing options
"""
def add_error_handler(
self,
code_or_exception,
function
):
"""
Add an error handler.
Parameters:
- code_or_exception: HTTP status code or exception class
- function: Error handler function
"""
def run(self, host: str = None, port: int = None, **options):
"""Abstract method for running the application."""from connexion import AsyncApp
from connexion.options import SwaggerUIOptions
# Configure Swagger UI
swagger_options = SwaggerUIOptions(
enabled=True,
path="/docs",
swagger_ui_bundle_js="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui-bundle.js",
swagger_ui_standalone_preset_js="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui-standalone-preset.js"
)
# Create application with production settings
app = AsyncApp(
__name__,
specification_dir='specs/',
strict_validation=True,
validate_responses=True,
options=swagger_options,
pythonic_params=True
)
# Add API specification
app.add_api('api.yaml', strict_validation=True)
# Add custom error handler
def handle_404(exception):
return {"error": "Resource not found"}, 404
app.add_error_handler(404, handle_404)from connexion import FlaskApp
from connexion.resolver import RestyResolver
app = FlaskApp(__name__)
# Add API with custom resolver
app.add_api(
'petstore.yaml',
resolver=RestyResolver('api'),
pythonic_params=True,
strict_validation=True
)
# Access Flask app for additional configuration
flask_app = app.app
flask_app.config['SECRET_KEY'] = 'your-secret-key'
if __name__ == '__main__':
app.run(debug=True)from connexion import ConnexionMiddleware
from starlette.applications import Starlette
from starlette.middleware.cors import CORSMiddleware
# Create base ASGI app
base_app = Starlette()
base_app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"]
)
# Wrap with Connexion middleware
app = ConnexionMiddleware(base_app)
app.add_api('openapi.yaml')Install with Tessl CLI
npx tessl i tessl/pypi-connexion