### Running the Example App Source: https://github.com/pylons/pyramid_openapi3/blob/main/examples/todoapp/README.md Steps to clone the repository, set up a virtual environment, install dependencies, and run the example application. It also provides instructions on accessing the Swagger UI and running tests. ```bash git clone https://github.com/Pylons/pyramid_openapi3.git cd pyramid_openapi3/examples/todoapp virtualenv -p python3.10 . source bin/activate pip install pyramid_openapi3 python app.py ``` -------------------------------- ### Run Example Application Source: https://github.com/pylons/pyramid_openapi3/blob/main/examples/splitfile/README.md Command-line instructions to clone the repository, set up a virtual environment, install dependencies, and run the example application. This allows users to interact with the API and its Swagger documentation. ```bash git clone https://github.com/Pylons/pyramid_openapi3.git cd pyramid_openapi3/examples/splitfile virtualenv -p python3.10 . source bin/activate pip install pyramid_openapi3 python app.py ``` -------------------------------- ### GET /hello Source: https://context7.com/pylons/pyramid_openapi3/llms.txt An example endpoint defined in the OpenAPI spec that validates query parameters. ```APIDOC ## GET /hello ### Description Returns a greeting message. Validates that the 'name' query parameter is provided and meets length requirements. ### Method GET ### Endpoint /hello ### Parameters #### Query Parameters - **name** (string) - Required - The name of the person to greet (minLength: 3). ### Request Example GET /hello?name=John HTTP/1.1 ### Response #### Success Response (200) - **message** (string) - The greeting message. #### Response Example { "message": "Hello, John!" } ``` -------------------------------- ### Run Unit Tests Source: https://github.com/pylons/pyramid_openapi3/blob/main/examples/splitfile/README.md Instructions to execute the unit tests for the example application using Python's unittest module. This requires the 'webtest' module to be installed. ```bash pip install webtest python -m unittest tests.py ``` -------------------------------- ### Complete TODO Application Example with Pyramid OpenAPI3 Source: https://context7.com/pylons/pyramid_openapi3/llms.txt This snippet provides a full, working example of a TODO application using Pyramid and pyramid_openapi3. It includes the data model definition using dataclasses, in-memory storage for TODO items, and demonstrates how to set up the Pyramid application configuration, define views, and handle requests. It serves as a comprehensive guide to implementing an API with OpenAPI validation. ```python """Complete TODO application with pyramid_openapi3.""" from dataclasses import dataclass from pyramid.config import Configurator from pyramid.request import Request from pyramid.router import Router from pyramid.view import view_config from pyramid.httpexceptions import HTTPNotFound from wsgiref.simple_server import make_server import os import typing as t # Data model @dataclass class Item: """A single TODO item.""" title: str def __json__(self, request: Request) -> t.Dict[str, str]: """JSON serialization for Pyramid's JSON renderer.""" return {"title": self.title} # In-memory storage ITEMS = [ Item(title="Buy milk"), Item(title="Buy eggs"), Item(title="Make pancakes"), ] ``` -------------------------------- ### Basic Setup for pyramid_openapi3 Source: https://github.com/pylons/pyramid_openapi3/blob/main/README.md Initial configuration to include pyramid_openapi3, serve the OpenAPI spec, and add an explorer UI. This sets up the basic functionality for API documentation and exploration. ```python config.include("pyramid_openapi3") config.pyramid_openapi3_spec('openapi.yaml', route='/api/v1/openapi.yaml') config.pyramid_openapi3_add_explorer(route='/api/v1/') ``` -------------------------------- ### Configure Pyramid OpenAPI 3 and Swagger UI Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Demonstrates the basic setup for including the pyramid_openapi3 addon, registering an OpenAPI specification file, and enabling the Swagger UI explorer. ```python from pyramid.config import Configurator def app(): with Configurator() as config: # Include pyramid_openapi3 addon config.include("pyramid_openapi3") # Configure your OpenAPI spec file config.pyramid_openapi3_spec("openapi.yaml") # Add Swagger UI explorer config.pyramid_openapi3_add_explorer() # Add your routes config.add_route("todos", "/todos") # Scan for view configurations config.scan(".") return config.make_wsgi_app() ``` -------------------------------- ### GET /docs/ Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Serves the Swagger UI explorer for interactive API testing. ```APIDOC ## GET /docs/ ### Description Serves the Swagger UI interface to allow users to explore and test the API defined by the OpenAPI specification. ### Method GET ### Endpoint /docs/ (configurable) ### Parameters #### Query Parameters - **route** (string) - Optional - The URL path where the explorer is served. - **ui_version** (string) - Optional - The version of Swagger UI to use. ### Request Example GET /docs/ ### Response #### Success Response (200) - **html** (text/html) - The Swagger UI HTML page. ``` -------------------------------- ### GET /openapi.yaml Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Serves the registered OpenAPI specification file for the application. ```APIDOC ## GET /openapi.yaml ### Description Retrieves the OpenAPI specification file registered with the application. This endpoint is used by tools like Swagger UI to render API documentation. ### Method GET ### Endpoint /openapi.yaml ### Parameters None ### Request Example GET /openapi.yaml HTTP/1.1 ### Response #### Success Response (200) - **body** (string) - The content of the OpenAPI specification file (YAML or JSON). #### Response Example { "openapi": "3.1.0", "info": { "title": "My API", "version": "1.0.0" }, "paths": {} } ``` -------------------------------- ### Configure Swagger UI Explorer in Pyramid Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Demonstrates how to include the pyramid_openapi3 plugin and configure the Swagger UI explorer. It shows both basic setup and advanced configuration including custom routes, UI versions, and OAuth2 settings. ```python from pyramid.config import Configurator def app(): with Configurator() as config: config.include("pyramid_openapi3") config.pyramid_openapi3_spec("openapi.yaml") # Basic usage - serve Swagger UI at /docs/ config.pyramid_openapi3_add_explorer() # Advanced configuration config.pyramid_openapi3_add_explorer( route="/api/docs/", route_name="api_explorer", ui_version="5.12.0", permission="view_docs", ui_config={ "deepLinking": True, "displayRequestDuration": True, "filter": True }, oauth_config={ "clientId": "your-client-id", "appName": "Your App" }, proto_port=("https", 443) ) return config.make_wsgi_app() ``` -------------------------------- ### Run Pyramid Server (Python) Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Starts a Pyramid WSGI server on port 6543, serving the configured application. It also prints the API and Swagger UI URLs. ```python if __name__ == "__main__": print("API available at http://localhost:6543/todos") print("Swagger UI at http://localhost:6543/docs/") server = make_server("0.0.0.0", 6543, create_app()) server.serve_forever() ``` -------------------------------- ### WebTest Integration for OpenAPI-Validated Views Source: https://context7.com/pylons/pyramid_openapi3/llms.txt This snippet demonstrates how to test Pyramid views that are validated by OpenAPI specifications using the WebTest library. It includes setup for the test application and various test cases for GET and POST requests, covering success scenarios, query parameter handling, and validation errors for missing fields, field constraints, and incorrect parameter types. It also verifies the availability of Swagger UI and the OpenAPI specification file. ```python from webtest import TestApp import unittest class TestTodoAPI(unittest.TestCase): """Test suite for TODO API endpoints.""" def setUp(self): """Set up test application.""" from myapp import app self.testapp = TestApp(app()) def test_list_todos_success(self): """Test successful GET request.""" res = self.testapp.get("/todos", status=200) self.assertIsInstance(res.json, list) def test_list_todos_with_limit(self): """Test GET with query parameter.""" res = self.testapp.get("/todos", {"limit": 2}, status=200) self.assertEqual(len(res.json), 2) def test_create_todo_success(self): """Test successful POST request.""" res = self.testapp.post_json( "/todos", {"title": "New item"}, status=200 ) self.assertIn("added", res.json.lower()) def test_create_todo_missing_title(self): """Test validation error for missing required field.""" res = self.testapp.post_json("/todos", {}, status=400) self.assertEqual(res.json[0]["field"], "title") self.assertIn("required", res.json[0]["message"]) def test_create_todo_title_too_long(self): """Test validation error for field constraint violation.""" res = self.testapp.post_json( "/todos", {"title": "a" * 100}, # Exceeds maxLength status=400 ) self.assertIn("too long", res.json[0]["message"]) def test_invalid_query_param_type(self): """Test validation error for wrong parameter type.""" res = self.testapp.get( "/todos", {"limit": "not-a-number"}, status=400 ) self.assertIn("ValidationError", res.json[0]["exception"]) def test_swagger_ui_available(self): """Test Swagger UI is served.""" res = self.testapp.get("/docs/", status=200) self.assertIn("Swagger UI", res.text) def test_openapi_spec_available(self): """Test OpenAPI spec is served.""" res = self.testapp.get("/openapi.yaml", status=200) self.assertIn("openapi:", res.text) if __name__ == "__main__": unittest.main() ``` -------------------------------- ### GET List of Todos (Pyramid) Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Defines a Pyramid view to retrieve all TODO items. It uses `pyramid_openapi3` for request validation and supports an optional 'limit' query parameter. ```python @view_config( route_name="todos", renderer="json", request_method="GET", openapi=True ) def list_todos(request: Request) -> t.List[Item]: """Return all TODO items, optionally limited.""" params = request.openapi_validated.parameters limit = params.query.get("limit") return ITEMS[:limit] if limit else ITEMS ``` -------------------------------- ### Handle Request and Response Validation Exceptions Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Provides examples of using Pyramid exception views to catch and handle RequestValidationError and ResponseValidationError. This allows for controlled JSON responses when validation fails. ```python from pyramid_openapi3.exceptions import RequestValidationError from pyramid_openapi3.exceptions import ResponseValidationError from pyramid.view import exception_view_config from pyramid.request import Request from pyramid.response import Response import json @exception_view_config(context=RequestValidationError) def handle_request_validation_error(exc: RequestValidationError, request: Request) -> Response: errors = [] for error in exc.errors: errors.append({ "type": "request_validation_error", "detail": str(error), "field": getattr(error, "name", None) }) return Response(json_body={"errors": errors}, status=400, content_type="application/json") @exception_view_config(context=ResponseValidationError) def handle_response_validation_error(exc: ResponseValidationError, request: Request) -> Response: return Response(json_body={"errors": [{"type": "internal_error", "detail": "The server generated an invalid response"}]}, status=500, content_type="application/json") ``` -------------------------------- ### Configure Pyramid Application with OpenAPI (Pyramid) Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Sets up a Pyramid application, including `pyramid_openapi3` integration, loading an OpenAPI specification from 'openapi.yaml', adding Swagger UI, and defining routes. ```python def create_app() -> Router: """Create and configure the Pyramid application.""" with Configurator() as config: # Include pyramid_openapi3 config.include("pyramid_openapi3") # Load OpenAPI specification config.pyramid_openapi3_spec( os.path.join(os.path.dirname(__file__), "openapi.yaml") ) # Add Swagger UI explorer config.pyramid_openapi3_add_explorer() # Add routes config.add_route("todos", "/todos") config.add_route("todo", "/todos/{todo_id}") # Scan for view configurations config.scan(".") return config.make_wsgi_app() ``` -------------------------------- ### Serve Multi-file OpenAPI Specifications Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Configures the application to serve OpenAPI specifications that are split across multiple files using $ref references, allowing for modular API documentation. ```python from pyramid.config import Configurator def app(): with Configurator() as config: config.include("pyramid_openapi3") # Serve spec directory - path points to the root spec file config.pyramid_openapi3_spec_directory( filepath="spec/openapi.yaml", route="/api/v1/spec" ) config.pyramid_openapi3_add_explorer() return config.make_wsgi_app() ``` -------------------------------- ### Configuring Protocol and Port for OpenAPI Explorer Source: https://github.com/pylons/pyramid_openapi3/blob/main/README.md Demonstrates how to specify the protocol and port for accessing the OpenAPI 3 spec file when using the `pyramid_openapi3_add_explorer` function. ```python config.pyramid_openapi3_add_explorer(proto_port=('https', 443)) ``` -------------------------------- ### Initialize Swagger UI with OAuth Configuration Source: https://github.com/pylons/pyramid_openapi3/blob/main/pyramid_openapi3/static/index.html This script initializes the Swagger UI bundle by merging user-provided configuration with default presets and plugins. It also handles optional OAuth initialization if the oauth_config object is provided. ```javascript window.onload = function() { const uiConfig = ${ui_config}; Object.assign(uiConfig, { presets: [ SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset, ], plugins: [ SwaggerUIBundle.plugins.DownloadUrl, ], }); const oauthConfig = ${oauth_config}; const ui = SwaggerUIBundle(uiConfig); if (oauthConfig) { ui.initOAuth(oauthConfig); } window.ui = ui; }; ``` -------------------------------- ### Register OpenAPI Specification Files Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Shows how to register an OpenAPI specification file with custom routing and permission settings, ensuring the API documentation is served securely. ```python from pyramid.config import Configurator def app(): with Configurator() as config: config.include("pyramid_openapi3") # Basic usage - serve spec at /openapi.yaml config.pyramid_openapi3_spec("openapi.yaml") # Advanced usage with custom route and permissions config.pyramid_openapi3_spec( filepath="api/openapi.yaml", route="/api/v1/openapi.yaml", route_name="api_spec", permission="view_api" ) return config.make_wsgi_app() ``` -------------------------------- ### List TODO items Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Retrieves a list of all TODO items. Supports pagination with a limit parameter. ```APIDOC ## GET /todos ### Description Retrieves a list of TODO items. You can specify a limit for the number of items returned. ### Method GET ### Endpoint /todos ### Parameters #### Query Parameters - **limit** (integer) - Optional - The maximum number of TODO items to return. Minimum value is 1. ### Response #### Success Response (200) - **items** (array) - A list of TODO item objects. - **title** (string) - The title of the TODO item. Max length is 40. #### Response Example ```json [ { "title": "Buy groceries" }, { "title": "Schedule meeting" } ] ``` #### Error Response (400) - **ValidationError** - Indicates a validation failure. - **field** (string) - The field that caused the validation error. - **message** (string) - A message describing the validation error. - **exception** (string) - The type of exception that occurred. ``` -------------------------------- ### Enabling OpenAPI Validation in Views Source: https://github.com/pylons/pyramid_openapi3/blob/main/README.md Demonstrates how to use the 'openapi=True' view predicate to enable request and response validation based on the OpenAPI specification. It also shows how to access validated request parameters. ```python @view_config(route_name="foobar", openapi=True, renderer='json') def myview(request): return request.openapi_validated.parameters ``` -------------------------------- ### Registering Pyramid Routes from OpenAPI Schema Source: https://github.com/pylons/pyramid_openapi3/blob/main/README.md Shows how to define Pyramid routes directly within the OpenAPI schema using the 'x-pyramid-route-name' extension and register them using `pyramid_openapi3_register_routes()`. ```yaml paths: /foo: x-pyramid-route-name: foo_route get: responses: 200: description: GET foo ``` ```python config.pyramid_openapi3_register_routes() ``` -------------------------------- ### Serving OpenAPI Spec from a Directory Source: https://github.com/pylons/pyramid_openapi3/blob/main/README.md Configures pyramid_openapi3 to serve OpenAPI specifications from a directory, allowing for the use of relative file references within the spec. This replaces the single-file spec serving. ```python config.pyramid_openapi3_spec_directory('path/to/openapi.yaml', route='/api/v1/spec') ``` -------------------------------- ### POST Create Todo (Pyramid) Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Defines a Pyramid view to create a new TODO item. It expects a JSON body containing the 'title' and adds the new item to the list. ```python @view_config( route_name="todos", renderer="json", request_method="POST", openapi=True ) def create_todo(request: Request) -> str: """Create a new TODO item.""" body = request.openapi_validated.body item = Item(title=body["title"]) ITEMS.append(item) return "Item added." ``` -------------------------------- ### Injecting CSP Nonce for OpenAPI Explorer UI Source: https://github.com/pylons/pyramid_openapi3/blob/main/README.md Illustrates how to generate and inject a CSP nonce into the response headers to allow the OpenAPI explorer UI to function correctly when a Content Security Policy is in place. ```python import secrets def inject_csp_header_tween(request): nonce = secrets.token_urlsafe(16) request.csp_nonce = nonce response = handler(request) response.headers["Content-Security-Policy"] = f"script-src 'self' 'nonce-{nonce}'" return response ``` -------------------------------- ### Create TODO item Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Creates a new TODO item. Requires a title in the request body. ```APIDOC ## POST /todos ### Description Creates a new TODO item. The request body must contain a JSON object with a 'title' field. ### Method POST ### Endpoint /todos ### Request Body - **title** (string) - Required - The title of the TODO item. Max length is 40. ### Request Example ```json { "title": "Walk the dog" } ``` ### Response #### Success Response (200) - **message** (string) - A success message indicating the item was created. #### Response Example ```json "TODO item created successfully." ``` #### Error Response (400) - **ValidationError** - Indicates a validation failure. - **field** (string) - The field that caused the validation error. - **message** (string) - A message describing the validation error. - **exception** (string) - The type of exception that occurred. ``` -------------------------------- ### Enable OpenAPI Validation on Pyramid Views Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Shows how to use the openapi=True predicate in view_config to automatically validate requests against an OpenAPI specification. Validated data is accessed via the request.openapi_validated object. ```python from pyramid.view import view_config from pyramid.request import Request @view_config( route_name="todos", renderer="json", request_method="GET", openapi=True ) def list_todos(request: Request): parameters = request.openapi_validated.parameters limit = parameters.query.get("limit") items = get_all_items() if limit: return items[:limit] return items @view_config( route_name="todos", renderer="json", request_method="POST", openapi=True ) def create_todo(request: Request): body = request.openapi_validated.body item = Item(title=body["title"]) save_item(item) return {"message": "Item added.", "id": item.id} @view_config( route_name="todo", renderer="json", request_method="PUT", openapi=True ) def update_todo(request: Request): todo_id = request.openapi_validated.parameters.path["todo_id"] new_title = request.openapi_validated.body["title"] item = get_item(todo_id) item.title = new_title save_item(item) return {"message": "Item updated."} @view_config( route_name="todo", renderer="json", request_method="DELETE", openapi=True ) def delete_todo(request: Request): todo_id = request.openapi_validated.parameters.path["todo_id"] delete_item(todo_id) return {"message": "Item deleted."} ``` -------------------------------- ### Register Custom Media Type Deserializers Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Add support for non-standard content types by registering custom deserializers with pyramid_openapi3_add_deserializer. This is useful for handling formats like YAML or MessagePack. ```python from pyramid.config import Configurator import yaml def deserialize_yaml(content: bytes) -> dict: return yaml.safe_load(content) def app(): with Configurator() as config: config.include("pyramid_openapi3") config.pyramid_openapi3_add_deserializer("application/x-yaml", deserialize_yaml) config.pyramid_openapi3_spec("openapi.yaml") return config.make_wsgi_app() ``` -------------------------------- ### Exception Classes Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Handle specific validation exceptions thrown by pyramid_openapi3. ```APIDOC ## Exception Classes ### Description Handle validation exceptions in your application. ### RequestValidationError Custom handler for request validation errors. #### Method `@exception_view_config(context=RequestValidationError)` #### Endpoint N/A (Exception handler) ### ResponseValidationError Custom handler for response validation errors (server-side issues). #### Method `@exception_view_config(context=ResponseValidationError)` #### Endpoint N/A (Exception handler) ### Request Example ```python from pyramid_openapi3.exceptions import RequestValidationError from pyramid_openapi3.exceptions import ResponseValidationError from pyramid.view import exception_view_config from pyramid.request import Request from pyramid.response import Response import json @exception_view_config(context=RequestValidationError) def handle_request_validation_error(exc: RequestValidationError, request: Request) -> Response: """Custom handler for request validation errors.""" errors = [] for error in exc.errors: errors.append({ "type": "request_validation_error", "detail": str(error), "field": getattr(error, "name", None) }) response = Response( json_body={"errors": errors}, status=400, content_type="application/json" ) return response @exception_view_config(context=ResponseValidationError) def handle_response_validation_error(exc: ResponseValidationError, request: Request) -> Response: """Custom handler for response validation errors (server-side issues).""" # Log the error for debugging import logging logger = logging.getLogger(__name__) logger.error(f"Response validation failed: {exc.errors}") response = Response( json_body={ "errors": [{"type": "internal_error", "detail": "The server generated an invalid response"}] }, status=500, content_type="application/json" ) return response ``` ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Register Custom Unmarshallers in Pyramid Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Demonstrates how to register custom unmarshaller functions for complex data types like Decimal and datetime using the Configurator. This allows the library to correctly parse non-standard OpenAPI formats into Python objects. ```python from pyramid.config import Configurator from datetime import datetime from decimal import Decimal def unmarshal_decimal(value: str) -> Decimal: """Convert string to Decimal for precise numeric handling.""" return Decimal(value) def unmarshal_datetime(value: str) -> datetime: """Convert ISO format string to datetime.""" return datetime.fromisoformat(value.replace('Z', '+00:00')) def app(): with Configurator() as config: config.include("pyramid_openapi3") config.pyramid_openapi3_add_unmarshaller("decimal", unmarshal_decimal) config.pyramid_openapi3_add_unmarshaller("date-time", unmarshal_datetime) config.pyramid_openapi3_spec("openapi.yaml") return config.make_wsgi_app() ``` -------------------------------- ### Register Routes from OpenAPI Spec Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Automatically register Pyramid routes using the x-pyramid-route-name extension in your OpenAPI spec. This allows views to reference routes defined in the specification file. ```python from pyramid.config import Configurator from pyramid.view import view_config def app(): with Configurator() as config: config.include("pyramid_openapi3") config.pyramid_openapi3_spec("openapi.yaml") config.pyramid_openapi3_register_routes() config.pyramid_openapi3_register_routes(route_prefix="/api/v1") config.scan(".") return config.make_wsgi_app() @view_config(route_name="foo", renderer="json", openapi=True) def get_foo(request): return {"foo": "bar"} ``` -------------------------------- ### View Validation with openapi=True Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Enables automatic validation of request parameters and body against the OpenAPI schema for specific views. ```APIDOC ## [HTTP_METHOD] [ENDPOINT] ### Description Enables request/response validation for a view. Validated data is accessible via `request.openapi_validated`. ### Method GET, POST, PUT, DELETE ### Endpoint /todos, /todos/{todo_id} ### Parameters #### Path Parameters - **todo_id** (integer) - Required - The unique identifier of the TODO item. #### Query Parameters - **limit** (integer) - Optional - Limit the number of items returned. #### Request Body - **title** (string) - Required - The title of the TODO item. ### Request Example POST /todos { "title": "New Task" } ### Response #### Success Response (200) - **message** (string) - Status message. - **id** (integer) - ID of the created item. #### Response Example { "message": "Item added.", "id": 1 } ``` -------------------------------- ### Configure Validation Settings Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Selectively enable or disable endpoint, request, and response validation via registry settings. Disabling request validation will result in request.openapi_validated being unavailable. ```python from pyramid.config import Configurator def app(): with Configurator() as config: config.include("pyramid_openapi3") config.pyramid_openapi3_spec("openapi.yaml") config.registry.settings["pyramid_openapi3.enable_endpoint_validation"] = False config.registry.settings["pyramid_openapi3.enable_request_validation"] = False config.registry.settings["pyramid_openapi3.enable_response_validation"] = False return config.make_wsgi_app() ``` -------------------------------- ### Handle OAuth2 Redirect in Swagger UI (JavaScript) Source: https://github.com/pylons/pyramid_openapi3/blob/main/pyramid_openapi3/static/oauth2-redirect.html This JavaScript code is responsible for handling the OAuth2 redirect flow initiated by Swagger UI. It parses the URL hash or query parameters to extract authorization codes or tokens, validates the 'state' parameter against the one stored in the opener window, and then calls back to the opener with the obtained credentials or any errors. It supports different OAuth2 grant types like 'accessCode' and 'authorizationCode'. ```javascript var oauth2 = window.opener.swaggerUIRedirectOauth2; var sentState = oauth2.state; var redirectUrl = oauth2.redirectUrl; var isValid, qp, arr; if (/code|token|error/.test(window.location.hash)) { qp = window.location.hash.substring(1).replace('?', '&'); } else { qp = location.search.substring(1); } arr = qp.split("&"); arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"'; }); qp = qp ? JSON.parse('{' + arr.join() + '}', function (key, value) { return key === "" ? value : decodeURIComponent(value); } ) : {}; isValid = qp.state === sentState; if (( oauth2.auth.schema.get("flow") === "accessCode" || oauth2.auth.schema.get("flow") === "authorizationCode" || oauth2.auth.schema.get("flow") === "authorization_code" ) && !oauth2.auth.code) { if (!isValid) { oauth2.errCb({ authId: oauth2.auth.name, source: "auth", level: "warning", message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server." }); } if (qp.code) { delete oauth2.state; oauth2.auth.code = qp.code; oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl}); } else { let oauthErrorMsg; if (qp.error) { oauthErrorMsg = "["+qp.error+"]: " + (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") + (qp.error_uri ? "More info: "+qp.error_uri : ""); } oauth2.errCb({ authId: oauth2.auth.name, source: "auth", level: "error", message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server." }); } } else { oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl}); } window.close(); ``` -------------------------------- ### Implement Custom Error Extraction Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Shows how to provide a custom error extraction function to format validation errors returned by the library. This is useful for standardizing error responses across an API. ```python from pyramid.config import Configurator from pyramid.request import Request import typing as t def custom_extract_errors( request: Request, errors: t.List[Exception] ) -> t.Iterator[t.Dict[str, t.Any]]: """Custom error extractor with additional context.""" for error in errors: yield { "code": error.__class__.__name__, "message": str(error), "field": getattr(error, "name", None), "path": request.path, "method": request.method, } def app(): with Configurator() as config: config.include("pyramid_openapi3") config.registry.settings["pyramid_openapi3_extract_errors"] = custom_extract_errors config.pyramid_openapi3_spec("openapi.yaml") return config.make_wsgi_app() ``` -------------------------------- ### PUT Update Todo by ID (Pyramid) Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Defines a Pyramid view to update an existing TODO item. It uses the 'todo_id' from the path and the 'title' from the request body, handling `IndexError` for non-existent items. ```python @view_config( route_name="todo", renderer="json", request_method="PUT", openapi=True ) def update_todo(request: Request) -> str: """Update a TODO item.""" params = request.openapi_validated.parameters body = request.openapi_validated.body try: ITEMS[params.path["todo_id"]].title = body["title"] except IndexError: raise HTTPNotFound("Item not found") return "Item updated." ``` -------------------------------- ### DELETE Todo by ID (Pyramid) Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Defines a Pyramid view to delete a TODO item by its ID. It retrieves the 'todo_id' from the path parameters and handles potential `IndexError` if the item is not found. ```python @view_config( route_name="todo", renderer="json", request_method="DELETE", openapi=True ) def delete_todo(request: Request) -> str: """Delete a TODO item by index.""" todo_id = request.openapi_validated.parameters.path["todo_id"] try: del ITEMS[todo_id] except IndexError: raise HTTPNotFound("Item not found") return "Item deleted." ``` -------------------------------- ### Register Custom Format Validators Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Define and register custom validators for specific OpenAPI string formats using pyramid_openapi3_add_formatter. This allows for specialized validation logic like phone numbers or UUIDs. ```python from pyramid.config import Configurator import re def validate_phone_number(value: str) -> bool: pattern = r'^\+?1?\d{9,15}$' if not re.match(pattern, value): raise ValueError(f"Invalid phone number: {value}") return True def app(): with Configurator() as config: config.include("pyramid_openapi3") config.pyramid_openapi3_add_formatter("phone", validate_phone_number) config.pyramid_openapi3_spec("openapi.yaml") return config.make_wsgi_app() ``` -------------------------------- ### Custom Unmarshallers Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Register custom functions to handle complex data type conversions for request parameters. ```APIDOC ## pyramid_openapi3_add_unmarshaller() ### Description Register custom unmarshallers for complex data type conversions. ### Method `config.pyramid_openapi3_add_unmarshaller(type_name: str, unmarshaller: Callable)` ### Endpoint N/A (Configuration method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from pyramid.config import Configurator from datetime import datetime from decimal import Decimal def unmarshal_decimal(value: str) -> Decimal: """Convert string to Decimal for precise numeric handling.""" return Decimal(value) def unmarshal_datetime(value: str) -> datetime: """Convert ISO format string to datetime.""" return datetime.fromisoformat(value.replace('Z', '+00:00')) def app(): with Configurator() as config: config.include("pyramid_openapi3") # Register custom unmarshallers config.pyramid_openapi3_add_unmarshaller("decimal", unmarshal_decimal) config.pyramid_openapi3_add_unmarshaller("date-time", unmarshal_datetime) config.pyramid_openapi3_spec("openapi.yaml") return config.make_wsgi_app() ``` ### Response N/A (Configuration method) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Update TODO item Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Updates an existing TODO item identified by its ID. Requires the updated item data in the request body. ```APIDOC ## PUT /todos/{todo_id} ### Description Updates an existing TODO item. You must provide the ID of the item to update and the new item data in the request body. ### Method PUT ### Endpoint /todos/{todo_id} ### Parameters #### Path Parameters - **todo_id** (integer) - Required - The ID of the TODO item to update. Must be 0 or greater. ### Request Body - **title** (string) - Required - The updated title of the TODO item. Max length is 40. ### Request Example ```json { "title": "Buy organic groceries" } ``` ### Response #### Success Response (200) - **message** (string) - A success message indicating the item was updated. #### Response Example ```json "TODO item updated successfully." ``` #### Error Response (400) - **ValidationError** - Indicates a validation failure. - **field** (string) - The field that caused the validation error. - **message** (string) - A message describing the validation error. - **exception** (string) - The type of exception that occurred. ``` -------------------------------- ### Delete TODO item Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Deletes a specific TODO item by its ID. ```APIDOC ## DELETE /todos/{todo_id} ### Description Deletes a specific TODO item identified by its unique ID. ### Method DELETE ### Endpoint /todos/{todo_id} ### Parameters #### Path Parameters - **todo_id** (integer) - Required - The ID of the TODO item to delete. Must be 0 or greater. ### Response #### Success Response (200) - **message** (string) - A success message indicating the item was deleted. #### Response Example ```json "TODO item deleted successfully." ``` #### Error Response (400) - **ValidationError** - Indicates a validation failure. - **field** (string) - The field that caused the validation error. - **message** (string) - A message describing the validation error. - **exception** (string) - The type of exception that occurred. ``` -------------------------------- ### Disabling Validation Features Source: https://github.com/pylons/pyramid_openapi3/blob/main/README.md Provides configuration settings to disable specific validation features of pyramid_openapi3, including endpoint, request, and response validation. Disabling request validation affects the availability of `request.openapi_validated`. ```python config.registry.settings["pyramid_openapi3.enable_endpoint_validation"] = False config.registry.settings["pyramid_openapi3.enable_request_validation"] = False config.registry.settings["pyramid_openapi3.enable_response_validation"] = False ``` -------------------------------- ### Custom Error Extraction Source: https://context7.com/pylons/pyramid_openapi3/llms.txt Customize the format of error responses returned by the API. ```APIDOC ## Custom Error Extraction ### Description Customize the error response format by providing a custom error extraction function. ### Method `config.registry.settings["pyramid_openapi3_extract_errors"] = custom_extract_errors` ### Endpoint N/A (Configuration method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from pyramid.config import Configurator from pyramid.request import Request import typing as t def custom_extract_errors( request: Request, errors: t.List[Exception] ) -> t.Iterator[t.Dict[str, t.Any]]: """Custom error extractor with additional context.""" for error in errors: yield { "code": error.__class__.__name__, "message": str(error), "field": getattr(error, "name", None), "path": request.path, "method": request.method, } def app(): with Configurator() as config: config.include("pyramid_openapi3") # Register custom error extractor before spec config.registry.settings["pyramid_openapi3_extract_errors"] = custom_extract_errors config.pyramid_openapi3_spec("openapi.yaml") return config.make_wsgi_app() # Default error response format expected in openapi.yaml: """ components: schemas: Error: type: object required: - exception - message properties: field: type: string message: type: string exception: type: string responses: ValidationError: description: OpenAPI request/response validation failed content: application/json: schema: type: array items: $ref: "#/components/schemas/Error" """ ``` ### Response N/A (Configuration method) #### Success Response (200) N/A #### Response Example N/A ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.