### Usage Example for OpenAPINinjaClient Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Demonstrates how to use OpenAPINinjaClient with a Django Ninja application. This example shows initializing the client and making a GET request, asserting the response status code. ```python from ninja import NinjaAPI from openapi_tester import SchemaTester, OpenAPINinjaClient app = NinjaAPI() @app.get("/users/{user_id}/") def get_user(request, user_id: int): return {"id": user_id, "name": "Alice"} def test_get_user(): client = OpenAPINinjaClient(router_or_app=app) response = client.get('/users/1/') assert response.status_code == 200 ``` -------------------------------- ### Install Development Dependencies with uv Source: https://github.com/maticardenas/django-contract-tester/blob/master/CONTRIBUTING.md Use `uv sync` to install all project dependencies, including development extras. Ensure uv is installed first. ```bash uv sync --all-extras --group dev ``` -------------------------------- ### Install Pre-commit Hooks with prek Source: https://github.com/maticardenas/django-contract-tester/blob/master/CONTRIBUTING.md Install prek for project linting. Run this command if you haven't installed pre-commit hooks before or need to reinstall. ```bash prek install ``` ```bash prek install -f ``` -------------------------------- ### Case Transformation Examples Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/case-testers.md Examples demonstrating the output of `_camelize`, `_pascalize`, `_kebabize`, and `underscore` functions from the `inflection` library. ```python _camelize("user_name") # "userName" ``` ```python _pascalize("user_name") # "UserName" ``` ```python _kebabize("user_name") # "user-name" ``` ```python underscore("userName") # "user_name" ``` -------------------------------- ### Example .django-contract-tester Configuration Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md A comprehensive example of a `.django-contract-tester` file, demonstrating master switches, disabling specific types, formats, and constraints. ```ini [django-contract-tester] # Keys to ignore during case validation ignore_case = ID, API, URL [django-contract-tester:validation] # Master switches request = true response = true types = true formats = true query_parameters = true # Disable validation for specific types disabled_types = integer # Disable validation for specific formats disabled_formats = date-time, email # Disable specific constraint validations disabled_constraints = enum, pattern, minLength, maxLength, minimum, maximum, multipleOf ``` -------------------------------- ### Install Optional Dependencies for Schema Auto-Detection Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Install specific optional dependencies to enable auto-detection of generated OpenAPI schemas with popular libraries. Choose the installation command that matches your schema generation tool. ```bash pip install django-contract-tester[drf-spectacular] # Use drf-spectacular ``` ```bash pip install django-contract-tester[drf-yasg] # Use drf-yasg ``` ```bash pip install django-contract-tester[django-ninja] # Use Django Ninja ``` -------------------------------- ### Install django-contract-tester Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/INDEX.md Install the base package or with optional dependencies for auto-schema detection with DRF Spectacular, DRF Yasg, or Django Ninja. ```bash pip install django-contract-tester ``` ```bash pip install django-contract-tester[drf-spectacular] ``` ```bash pip install django-contract-tester[drf-yasg] ``` ```bash pip install django-contract-tester[django-ninja] ``` -------------------------------- ### Example Usage of ResponseHandlerFactory Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/response-handlers.md Demonstrates how to use the ResponseHandlerFactory to create handlers for DRF and Ninja responses. Ensure the necessary response objects are available. ```python from openapi_tester.response_handler_factory import ResponseHandlerFactory # With DRF drf_response = client.get('/api/users/') handler = ResponseHandlerFactory.create( 'GET', '/api/users/', response=drf_response ) # Returns: DRFResponseHandler # With Ninja ninja_response = ninja_client.get('/api/users/') handler = ResponseHandlerFactory.create( 'GET', '/api/users/', response=ninja_response, path_prefix="/api/v1" ) # Returns: DjangoNinjaResponseHandler ``` -------------------------------- ### Instantiate CaseError for Different Casing Scenarios Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exceptions.md These examples show how to manually create `CaseError` instances to represent different key naming convention violations, demonstrating the expected parameters for various casing styles. ```python # With is_camel_case CaseError("user_name", "camelCased", "userName") CaseError("UserId", "camelCased", "userId") # With is_snake_case CaseError("userName", "snake_cased", "user_name") CaseError("UserID", "snake_cased", "user_id") # With is_pascal_case CaseError("userName", "PascalCased", "UserName") # With is_kebab_case CaseError("userName", "kebab-cased", "user-name") ``` -------------------------------- ### Example Usage of UrlStaticSchemaLoader Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Create a SchemaTester instance with the URL of the OpenAPI schema file to load it. ```python from openapi_tester import SchemaTester ester = SchemaTester( schema_file_path="https://api.example.com/openapi.json" ) ``` -------------------------------- ### Install Django Contract Tester Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md Use pip to install the django-contract-tester package. Ensure your Python and Django versions are compatible. ```shell pip install django-contract-tester ``` -------------------------------- ### BaseSchemaLoader resolve_path Method Example Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Resolves a Django URL path to its parameterized OpenAPI path and Django ResolverMatch. Raises a ValueError if the path cannot be resolved. This example demonstrates resolving '/users/123/' for a 'get' request. ```python loader = DrfSpectacularSchemaLoader() path, resolver = loader.resolve_path('/users/123/', 'get') # Returns: ('/users/{user_id}/', ResolverMatch(...)) ``` -------------------------------- ### Example Usage of StaticSchemaLoader Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Instantiate StaticSchemaLoader with the path to your OpenAPI schema file and then call get_schema to retrieve the schema. ```python from openapi_tester.loaders import StaticSchemaLoader loader = StaticSchemaLoader(path="./schemas/api.yaml") schema = loader.get_schema() ``` -------------------------------- ### CaseError Handling Example Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/case-testers.md Demonstrates how to catch and handle `CaseError` when a key fails case validation. The exception provides details about the key, the expected case, and the expected value. ```python from openapi_tester.exceptions import CaseError try: is_camel_case("user_name") except CaseError as e: # Output: The response key `user_name` is not properly camelCased. Expected value: userName print(e) ``` -------------------------------- ### OpenAPIClient Usage Example Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Demonstrates how to integrate OpenAPIClient into Django REST framework tests or pytest tests. ```APIDOC ## OpenAPIClient Usage Example ### With `rest_framework.test.APITestCase` ```python from rest_framework.test import APITestCase from openapi_tester import SchemaTester, OpenAPIClient class MyAPITests(APITestCase): client_class = OpenAPIClient def test_get_user(self): response = self.client.get('/api/users/1/') self.assertEqual(response.status_code, 200) # Schema validation happens automatically ``` ### With `pytest` and `pytest-django` ```python import pytest from openapi_tester import SchemaTester, OpenAPIClient @pytest.fixture def schema_tester(): return SchemaTester() @pytest.fixture def client(schema_tester): return OpenAPIClient(schema_tester=schema_tester) def test_get_user(client): response = client.get('/api/users/1/') assert response.status_code == 200 ``` ``` -------------------------------- ### Validate Keys with `is_snake_case` Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/case-testers.md Demonstrates how to use `is_snake_case` to validate strings against the snake_case convention, including examples of valid and invalid cases. ```python from openapi_tester import is_snake_case is_snake_case("user_name") # is_snake_case("userName") # is_snake_case("UserName") # is_snake_case("user__name") # (double underscore) ``` -------------------------------- ### UndocumentedSchemaSectionError Message Example Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exceptions.md An example of the error message format for `UndocumentedSchemaSectionError`, indicating which route was not found and listing the documented routes. ```text Error: Unsuccessfully tried to index the OpenAPI schema by `/api/users/{id}`. Undocumented route /api/users/{id}. Documented routes: • /api/users/ • /api/posts/ ``` -------------------------------- ### Development vs. Production Configuration Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/configuration.md This example shows two INI configurations for django-contract-tester: one for development (enabling most validations) and one for production (disabling specific validations). ```ini [django-contract-tester:validation] request = true response = true types = true formats = true query_parameters = true disabled_types = disabled_formats = disabled_constraints = ``` ```ini [django-contract-tester:validation] request = false response = true types = true formats = false query_parameters = true disabled_types = string disabled_formats = date-time, email disabled_constraints = pattern ``` -------------------------------- ### Django Ninja Test Client Integration Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/patterns.md Integrate django-contract-tester with Django Ninja using the OpenAPINinjaClient. This example shows how to set up the client and test API endpoints. ```python from ninja import NinjaAPI, Router from openapi_tester import OpenAPINinjaClient, SchemaTester api = NinjaAPI() @api.get("/users/") def list_users(request): return {"users": []} def test_api_endpoints(): schema_tester = SchemaTester() client = OpenAPINinjaClient( router_or_app=api, schema_tester=schema_tester, path_prefix="/api" ) response = client.get('/api/users/') assert response.status_code == 200 ``` -------------------------------- ### Validate Keys with `is_camel_case` Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/case-testers.md Demonstrates how to use `is_camel_case` to validate strings against the camelCase convention, showing both valid and invalid examples that raise `CaseError`. ```python from openapi_tester import is_camel_case is_camel_case("userName") # is_camel_case("user_name") # is_camel_case("UserName") # ``` -------------------------------- ### Handle CaseError During Schema Testing Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exceptions.md Catch `CaseError` to identify and report issues with key naming conventions. This example demonstrates setting up `SchemaTester` with a specific case convention and handling the resulting `CaseError`. ```python from openapi_tester import SchemaTester, is_camel_case from openapi_tester.exceptions import CaseError tester = SchemaTester(case_tester=is_camel_case) try: tester.validate_response(response_handler) except CaseError as e: # Output: The response key `user_name` is not properly camelCased. Expected value: userName print(e) ``` -------------------------------- ### GitHub Actions Workflow for API Contract Tests Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/patterns.md This workflow runs API contract tests on push or pull request events. It checks out the code, sets up Python, installs project dependencies and testing tools, and then executes pytest. ```yaml # .github/workflows/api-tests.yml name: API Contract Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.11" - name: Install dependencies run: | pip install -e .[drf-spectacular] pip install pytest pytest-django - name: Run API contract tests run: | pytest tests/ -v --tb=short env: DJANGO_SETTINGS_MODULE: project.settings.test ENVIRONMENT: ci ``` -------------------------------- ### Initialize OpenAPINinjaClient Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Initialize an OpenAPINinjaClient instance with a Ninja app or router, an optional path prefix for schema matching, and a SchemaTester instance. The path prefix is used to match against the OpenAPI schema. ```python from ninja import Router from openapi_tester import SchemaTester, OpenAPINinjaClient router = Router() @router.get("/users/") def list_users(request): return {"users": []} schema_tester = SchemaTester() client = OpenAPINinjaClient( router_or_app=router, path_prefix="/api/v1", schema_tester=schema_tester ) response = client.get('/api/v1/users/') ``` -------------------------------- ### Basic SchemaTester and OpenAPIClient Usage (Python) Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Demonstrates how to initialize `SchemaTester` with a case tester and integrate it with `OpenAPIClient` for making API requests with automatic schema validation. ```python from openapi_tester import SchemaTester, OpenAPIClient, is_camel_case # Create tester tester = SchemaTester(case_tester=is_camel_case) # Use with OpenAPIClient client = OpenAPIClient(schema_tester=tester) response = client.get('/api/users/') ``` -------------------------------- ### Run Linting Checks Locally Source: https://github.com/maticardenas/django-contract-tester/blob/master/CONTRIBUTING.md Execute `prek run --all-files` to ensure all files adhere to the project's linting standards before committing. ```bash prek run --all-files ``` -------------------------------- ### Initialize and Use OpenAPIClient Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md Instantiate SchemaTester and OpenAPIClient, then use it like a regular Django testing client for request/response validation. ```python schema_tester = SchemaTester() client = OpenAPIClient(schema_tester=schema_tester) response = client.get('/api/v1/tests/123/') ``` -------------------------------- ### Handle UndocumentedSchemaSectionError Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exceptions.md Shows how to catch `UndocumentedSchemaSectionError` when validating a response, for example, if an endpoint path is not documented in the schema. ```python from openapi_tester.exceptions import UndocumentedSchemaSectionError try: tester.validate_response(response_handler) except UndocumentedSchemaSectionError as e: # Example: Undocumented route /api/internal/debug print(f"Endpoint not documented: {e}") ``` -------------------------------- ### Load Configuration with Priority Order Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/configuration.md Loads configuration by checking `.django-contract-tester` file, then `pyproject.toml`, and finally falling back to `DEFAULT_CONFIG`. This is the primary function for loading configuration. ```python def load_config() -> OpenAPITestConfig: pass ``` ```python from openapi_tester.config import load_config config = load_config() print(config.validation.disabled_types) ``` -------------------------------- ### Ninja Client Response Handling Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/response-handlers.md Shows how to use OpenAPINinjaClient with Ninja API for response testing, including manual handler creation. ```python from ninja import NinjaAPI from openapi_tester import OpenAPINinjaClient, SchemaTester api = NinjaAPI() @api.get("/users/") def list_users(request): return {"users": []} client = OpenAPINinjaClient(router_or_app=api) response = client.get('/api/users/?page=1') # Handler created automatically by OpenAPINinjaClient # But can also create manually: from openapi_tester.response_handler_factory import ResponseHandlerFactory handler = ResponseHandlerFactory.create( 'GET', '/api/users/?page=1', response=response, path_prefix="/api" ) print(handler.request.query_params) # {"page": 1} print(handler.endpoint()) # "GET /api/users/" ``` -------------------------------- ### Load Config from pyproject.toml Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/configuration.md Loads configuration from a `pyproject.toml` file. If no path is provided, it searches upwards from the current working directory. ```python def load_config_from_pyproject_toml( config_path: pathlib.Path | None = None, ) -> OpenAPITestConfig: pass ``` -------------------------------- ### Initialize SchemaTester Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/schema-tester.md Instantiate SchemaTester with various configuration options. Supports auto-detection of schemas or explicit file paths. Custom validators and field mappings can be provided. ```python def __init__( self, case_tester: Callable[[str], None] | None = None, ignore_case: list[str] | None = None, schema_file_path: str | None = None, validators: list[Callable[[dict, Any], str | None]] | None = None, field_key_map: dict[str, str] | None = None, path_prefix: str | None = None, ) -> None ``` ```python from openapi_tester import SchemaTester, is_camel_case # Auto-detect schema from drf-spectacular or drf-yasg tester = SchemaTester( case_tester=is_camel_case, ignore_case=["ID", "API"], validators=[my_custom_validator] ) # Or use a static schema file tester = SchemaTester(schema_file_path="./schemas/api.yaml") # Or from URL tester = SchemaTester(schema_file_path="https://example.com/openapi.json") ``` -------------------------------- ### BaseSchemaLoader.normalize_schema_paths Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Converts all path definitions within a schema from the standard OpenAPI format to a parameterized format, for example, transforming `/users/{id}` into `/users/{user_id}`. ```APIDOC ## BaseSchemaLoader.normalize_schema_paths ### Description Converts all path definitions from OpenAPI format to parameterized format (e.g., `/users/{id}` → `/users/{user_id}`). ### Method Signature ```python def normalize_schema_paths(self, schema: dict) -> dict[str, dict] ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Description | |-----------|------|-------------| | schema | `dict` | The schema with paths to normalize | ### Returns Schema with normalized paths ``` -------------------------------- ### Initialize SchemaTester with a Static Schema File Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Use the SchemaTester with a static OpenAPI schema file when auto-detection is not configured. Provide the path to your schema file during initialization. ```python from openapi_tester import SchemaTester tester = SchemaTester(schema_file_path="./schemas/api.yaml") ``` -------------------------------- ### Initialize and Use OpenAPINinjaClient Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md Instantiate SchemaTester and OpenAPINinjaClient for use with Django Ninja's test client. This client validates requests and responses against the OpenAPI schema. ```python schema_tester = SchemaTester() client = OpenAPINinjaClient( router_or_app=router, schema_tester=schema_tester, ) response = client.get('/api/v1/tests/123/') ``` -------------------------------- ### Pytest Integration with OpenAPIClient Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Configure OpenAPIClient using pytest fixtures for use in your tests. This setup allows for automatic schema validation during your test runs. ```python import pytest from openapi_tester import SchemaTester, OpenAPIClient @pytest.fixture def schema_tester(): return SchemaTester() @pytest.fixture def client(schema_tester): return OpenAPIClient(schema_tester=schema_tester) def test_get_user(client): response = client.get('/api/users/1/') assert response.status_code == 200 ``` -------------------------------- ### Initialize OpenAPIClient Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Instantiate OpenAPIClient with an optional SchemaTester. If no SchemaTester is provided, a default one will be created. This client can then be used like a standard Django REST Framework APIClient. ```python from openapi_tester import SchemaTester, OpenAPIClient schema_tester = SchemaTester() client = OpenAPIClient(schema_tester=schema_tester) # Use like a normal APIClient response = client.get('/api/users/') ``` -------------------------------- ### Importing Configuration Loading Functions (Python) Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Imports functions from `openapi_tester.config` for loading configuration settings from various sources. ```python from openapi_tester.config import ( load_config, load_config_from_ini_file, load_config_from_pyproject_toml, ) ``` -------------------------------- ### BaseSchemaLoader normalize_schema_paths Method Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Converts all path definitions in a schema from the standard OpenAPI format to a parameterized format, for example, changing `/users/{id}` to `/users/{user_id}`. ```python def normalize_schema_paths(self, schema: dict) -> dict[str, dict]: """Converts all path definitions from OpenAPI format to parameterized format (e.g., `/users/{id}` → `/users/{user_id}`).""" ``` -------------------------------- ### Instantiate SchemaTester with Global Options Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md Instantiate SchemaTester with global options for case validation, ignored keys, and custom validators. ```python from openapi_tester import SchemaTester, is_camel_case from tests.utils import my_uuid_4_validator schema_test_with_case_validation = SchemaTester( case_tester=is_camel_case, ignore_case=["IP"], validators=[my_uuid_4_validator] ) ``` -------------------------------- ### load_config_from_pyproject_toml Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/configuration.md Loads configuration from the `pyproject.toml` file. If no path is provided, it searches upwards from the current working directory. ```APIDOC ## load_config_from_pyproject_toml ### Description Loads configuration from `pyproject.toml`. ### Parameters #### Path Parameters - **config_path** (Path | None) - Optional - Explicit path to file. If None, searches from CWD upward ### Returns `OpenAPITestConfig` instance or `DEFAULT_CONFIG` if not found. ``` -------------------------------- ### BaseSchemaLoader Constructor Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Initializes a schema loader. Optionally accepts a dictionary to map URL parameter names to concrete values, useful when parameters cannot be automatically inferred from Django routes. ```python def __init__(self, field_key_map: dict[str, str] | None = None) ``` -------------------------------- ### Unit Test Snake Case Validation Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/case-testers.md Tests the `is_snake_case` function for validating snake_case strings. It includes examples of valid and invalid inputs, raising a `CaseError` for incorrect formats. ```python import pytest from openapi_tester import is_camel_case, is_snake_case from openapi_tester.exceptions import CaseError def test_is_snake_case(): """Test snake_case validation""" # Valid cases is_snake_case("user_name") is_snake_case("user_id") # Invalid cases with pytest.raises(CaseError): is_snake_case("userName") with pytest.raises(CaseError): is_snake_case("UserName") ``` -------------------------------- ### Unit Test Camel Case Validation Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/case-testers.md Tests the `is_camel_case` function for validating camelCase strings. It includes examples of valid and invalid inputs, raising a `CaseError` for incorrect formats. ```python import pytest from openapi_tester import is_camel_case, is_snake_case from openapi_tester.exceptions import CaseError def test_is_camel_case(): """Test camelCase validation""" # Valid cases is_camel_case("userName") is_camel_case("userID") is_camel_case("a") # Invalid cases with pytest.raises(CaseError): is_camel_case("user_name") with pytest.raises(CaseError): is_camel_case("UserName") ``` -------------------------------- ### Validator Error Messages Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/validators.md Examples of descriptive error messages returned by validators for various validation failures, including type, format, enum, pattern, minimum, and length constraints. ```text Expected a "string" type value Received: 42 Expected an "email" formatted "string" value Received: "not-an-email" Expected: a member of the enum ['red', 'green', 'blue'] Received: "yellow" The string "abc" does not match the specified pattern: ^[A-Z][a-z]+$ The value -5 is lower than the specified minimum of 0 The length of "" is shorter than the specified minimum length of 3 ``` -------------------------------- ### Load Configuration Based on Environment Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/configuration.md This Python code snippet demonstrates how to dynamically load the `django-contract-tester` configuration from INI files based on the `ENVIRONMENT` variable. It uses `pathlib` and `os.getenv` to determine the correct configuration file. ```python import os from openapi_tester.config import load_config_from_ini_file from pathlib import Path env = os.getenv('ENVIRONMENT', 'development') config_file = Path(f'.django-contract-tester.{env}') config = load_config_from_ini_file(config_file) ``` -------------------------------- ### Get Key Value from Schema Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/schema-tester.md Retrieves a value from a schema dictionary using a key. Supports optional regex matching for keys. Use when you need to dynamically access schema properties. ```python def get_key_value( schema: dict[str, dict], key: str, error_addon: str = "", use_regex: bool = False, ) -> dict: ``` -------------------------------- ### Instantiate SchemaTester Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md Create an instance of SchemaTester. If using drf-yasg or drf-spectacular, the schema will be auto-detected. Otherwise, provide the path to your schema file. ```python from openapi_tester import SchemaTester schema_tester = SchemaTester() ``` ```python from openapi_tester import SchemaTester # path should be a string schema_tester = SchemaTester(schema_file_path="./schemas/publishedSpecs.yaml") ``` -------------------------------- ### load_config Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/configuration.md Loads configuration by checking in the following priority order: `.django-contract-tester` file, `pyproject.toml` file, and finally the `DEFAULT_CONFIG`. It returns the first configuration found or the default. ```APIDOC ## load_config ### Description Loads configuration using priority order: 1. `.django-contract-tester` file 2. `pyproject.toml` file 3. `DEFAULT_CONFIG` ### Returns First found config or default. ### Example ```python from openapi_tester.config import load_config config = load_config() print(config.validation.disabled_types) ``` ``` -------------------------------- ### Advanced SchemaTester Configuration (Python) Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Shows how to configure `SchemaTester` with a custom schema file path, add custom validators, and apply specific validation settings using `OpenAPITestConfig`. ```python from openapi_tester import SchemaTester from openapi_tester.config import OpenAPITestConfig, ValidationSettings from openapi_tester.validators import validate_type config = OpenAPITestConfig( validation=ValidationSettings( types=True, disabled_formats=['date-time'] ) ) tester = SchemaTester( schema_file_path="./schemas/api.yaml", validators=[custom_validator] ) tester.validate_response(handler, test_config=config) ``` -------------------------------- ### Customizing OpenAPI Client Configuration Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Shows how to override global configuration for a specific OpenAPI client instance. Useful for fine-tuning validation settings like disabling specific format checks. ```python from openapi_tester import OpenAPIClient from openapi_tester.config import OpenAPITestConfig, ValidationSettings # Override global config for a specific client custom_config = OpenAPITestConfig( validation=ValidationSettings( request=True, response=True, types=True, disabled_formats=['date-time'] ) ) # Then use in validation context # tester = SchemaTester() # Pass custom config to validate_response/validate_request ``` -------------------------------- ### Get Status Code Section from Schema Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/schema-tester.md Retrieves the response definition for a given HTTP status code from a schema's responses object. Handles both string and integer status codes. Useful for validating specific response structures. ```python def get_status_code( schema: dict[str | int, dict], status_code: str | int, error_addon: str = "", ) -> dict: ``` -------------------------------- ### BaseSchemaLoader Constructor Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Initializes a schema loader. An optional mapping can be provided to resolve URL parameter names to specific values when they cannot be automatically inferred from Django routes. ```APIDOC ## BaseSchemaLoader Constructor ### Description Initializes a loader with optional field key mapping. ### Constructor Signature ```python def __init__(self, field_key_map: dict[str, str] | None = None) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | field_key_map | `dict[str, str] \| None` | No | None | Map of URL parameter names to concrete values. Used when the parameter cannot be automatically inferred from Django routes | ``` -------------------------------- ### Importing Utility Functions (Python) Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Imports various utility functions from `openapi_tester.utils` that assist in schema manipulation, serialization, and query parameter handling. ```python from openapi_tester.utils import ( merge_objects, normalize_schema_section, serialize_schema_section_data, lazy_combinations, serialize_json, get_required_keys, query_params_to_object, should_validate_query_param, normalize_query_param_value, ) ``` -------------------------------- ### OpenAPINinjaClient Constructor Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Initializes an OpenAPINinjaClient instance, which is a Django Ninja test client that validates requests and responses against the OpenAPI schema. It requires a NinjaAPI or Router instance and optionally accepts a path prefix and a SchemaTester instance. ```APIDOC ## OpenAPINinjaClient Constructor ### Description Initializes an OpenAPINinjaClient instance. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Constructor Signature ```python def __init__( self, *args, router_or_app: NinjaAPI | Router, path_prefix: str = "", schema_tester: SchemaTester | None = None, **kwargs, ) -> None ``` ### Parameters - **router_or_app** (`NinjaAPI | Router`) - Required - The Ninja app or router to test - **path_prefix** (`str`) - Optional - Prefix to add to all request paths when matching against the OpenAPI schema (e.g., `/api/v1`) - **schema_tester** (`SchemaTester | None`) - Optional - SchemaTester instance to use for validation. If not provided, a default is created ### Raises - `APIFrameworkNotInstalledError`: If Django Ninja is not installed ### Example ```python from ninja import Router from openapi_tester import SchemaTester, OpenAPINinjaClient router = Router() @router.get("/users/") def list_users(request): return {"users": []} schema_tester = SchemaTester() client = OpenAPINinjaClient( router_or_app=router, path_prefix="/api/v1", schema_tester=schema_tester ) response = client.get('/api/v1/users/') ``` ``` -------------------------------- ### OpenAPIClient Constructor Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Initializes an OpenAPIClient instance. It accepts an optional SchemaTester and passes any other arguments to the parent APIClient. ```APIDOC ## OpenAPIClient Constructor ### Description Initialize an OpenAPIClient instance. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Method Signature ```python def __init__( self, *args, schema_tester: SchemaTester | None = None, **kwargs, ) -> None ``` ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | schema_tester | `SchemaTester | None` | No | None | SchemaTester instance to use for validation. If not provided, a default SchemaTester is created | | *args, **kwargs | — | — | — | Passed to parent `APIClient` | ### Request Example ```python from openapi_tester import SchemaTester, OpenAPIClient schema_tester = SchemaTester() client = OpenAPIClient(schema_tester=schema_tester) # Use like a normal APIClient response = client.get('/api/users/') ``` ``` -------------------------------- ### Configure `SchemaTester` with `is_camel_case` Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/case-testers.md Illustrates how to integrate `is_camel_case` into a `SchemaTester` instance, including how to specify keys to ignore during case validation. ```python from openapi_tester import SchemaTester, is_camel_case tester = SchemaTester( case_tester=is_camel_case, ignore_case=["ID", "API"] # Skip validation for these ) ``` -------------------------------- ### Handling SchemaTester Exceptions (Python) Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Illustrates how to catch specific exceptions like `CaseError`, `UndocumentedSchemaSectionError`, and `DocumentationError` that can be raised during schema validation. ```python from openapi_tester import SchemaTester from openapi_tester.exceptions import ( DocumentationError, UndocumentedSchemaSectionError, CaseError ) tester = SchemaTester() try: tester.validate_response(handler) except CaseError as e: print(f"Case validation failed: {e}") except UndocumentedSchemaSectionError as e: print(f"Endpoint not documented: {e}") except DocumentationError as e: print(f"Schema mismatch: {e}") ``` -------------------------------- ### SchemaTester with Field Key Map Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md Instantiate SchemaTester with a field_key_map to map custom URL parameter names. ```python from openapi_tester import SchemaTester schema_tester = SchemaTester(field_key_map={ "language": "en", }) ``` -------------------------------- ### Configure Validation Settings via Constructor Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/configuration.md Use the OpenAPITestConfig constructor to pass validation settings directly when initializing SchemaTester. This method allows for fine-grained control over request, response, type, format, and constraint validation. ```python from openapi_tester import SchemaTester from openapi_tester.config import OpenAPITestConfig, ValidationSettings config = OpenAPITestConfig( case_tester=is_camel_case, ignore_case=["ID", "API"], validation=ValidationSettings( request=True, response=True, types=True, formats=True, query_parameters=True, disabled_types=["integer"], disabled_formats=["date-time"], disabled_constraints=["enum"] ) ) tester = SchemaTester() tester.validate_response(response_handler, test_config=config) ``` -------------------------------- ### Load Config from INI File Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/configuration.md Loads configuration from a `.django-contract-tester` INI file. If no path is provided, it searches upwards from the current working directory. ```python def load_config_from_ini_file( config_path: pathlib.Path | None = None, ) -> OpenAPITestConfig: pass ``` -------------------------------- ### Initialize StaticSchemaLoader Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Use StaticSchemaLoader to load OpenAPI schemas from local YAML or JSON files. Specify the file path and optionally provide a mapping for URL parameter names. ```python def __init__(self, path: str, field_key_map: dict[str, str] | None = None) ``` -------------------------------- ### Integrating SchemaTester with Pytest and pytest-django (Python) Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Demonstrates how to set up `SchemaTester` and `OpenAPIClient` as Pytest fixtures for seamless integration with `pytest-django` for API testing. ```python import pytest from openapi_tester import OpenAPIClient, SchemaTester @pytest.fixture def schema_tester(): return SchemaTester() @pytest.fixture def api_client(schema_tester): return OpenAPIClient(schema_tester=schema_tester) def test_list_users(api_client): response = api_client.get('/api/users/') assert response.status_code == 200 # Validation happens automatically ``` -------------------------------- ### Handle OpenAPISchemaError Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exceptions.md Demonstrates how to catch `OpenAPISchemaError` when initializing a `SchemaTester` with a potentially invalid schema file. ```python from openapi_tester.exceptions import OpenAPISchemaError try: tester = SchemaTester(schema_file_path="./schemas/broken.yaml") except OpenAPISchemaError as e: print(f"Schema error: {e}") ``` -------------------------------- ### StaticSchemaLoader Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Loads OpenAPI schemas from local YAML or JSON files. ```APIDOC ## StaticSchemaLoader Loads OpenAPI schemas from local YAML or JSON files. ### Constructor ```python def __init__(self, path: str, field_key_map: dict[str, str] | None = None) ``` Initialize loader with file path. | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | path | `str` | Yes | — | Path to YAML or JSON OpenAPI file (`.json` extension required for JSON, otherwise treated as YAML) | | field_key_map | `dict[str, str] | None` | No | None | URL parameter name mappings | **Raises:** `FileNotFoundError` if file does not exist ### load_schema ```python def load_schema(self) -> dict[str, Any] ``` Loads and parses the OpenAPI file. **Returns:** The schema as a dictionary **Raises:** `yaml.YAMLError` or `orjson.JSONDecodeError` if parsing fails **Example:** ```python from openapi_tester.loaders import StaticSchemaLoader loader = StaticSchemaLoader(path="./schemas/api.yaml") schema = loader.get_schema() ``` ``` -------------------------------- ### Initialize DrfYasgSchemaLoader Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Initializes the loader for drf-yasg schemas. Accepts an optional dictionary for mapping URL parameter names. ```python def __init__(self, field_key_map: dict[str, str] | None = None) -> None: pass ``` -------------------------------- ### Configure OpenAPITestConfig Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/exports.md Instantiate OpenAPITestConfig to customize validation behavior, including case testing and type/format validation settings. Specify disabled types to ignore certain data types during validation. ```python from openapi_tester.config import OpenAPITestConfig, ValidationSettings config = OpenAPITestConfig( case_tester=is_camel_case, validation=ValidationSettings( types=True, formats=True, disabled_types=["integer"] ) ) ``` -------------------------------- ### Initialize UrlStaticSchemaLoader Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Use UrlStaticSchemaLoader to load OpenAPI schemas directly from an HTTP(S) URL. Provide the URL and an optional mapping for URL parameter names. ```python def __init__(self, url: str, field_key_map: dict[str, str] | None = None) ``` -------------------------------- ### Configure OpenAPINinjaClient with Path Prefix Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md Configure OpenAPINinjaClient with a path prefix to specify the prefix of the path used to look into the OpenAPI schema. This is useful when Django Ninja's test client works separately from the Django URL resolver. ```python client = OpenAPINinjaClient( router_or_app=router, path_prefix='/api/v1', schema_tester=schema_tester, ) ``` -------------------------------- ### Configure `SchemaTester` with `is_snake_case` Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/case-testers.md Shows how to set `is_snake_case` as the case tester for a `SchemaTester` instance. ```python from openapi_tester import SchemaTester, is_snake_case tester = SchemaTester(case_tester=is_snake_case) ``` -------------------------------- ### Query Parameter Normalization Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/response-handlers.md Illustrates how ResponseHandler normalizes raw query parameters from a URL into appropriate Python types. ```python from openapi_tester.response_handler import ResponseHandler # Raw query params (all strings from URL) raw_params = { "page": "1", "limit": "50", "active": "true", "deleted": "false", "filter": "test" } normalized = ResponseHandler._normalize_query_params(raw_params) # Returns: # { # "page": 1, # "limit": 50, # "active": True, # "deleted": False, # "filter": "test" # } ``` -------------------------------- ### Error Handling with Validation Exceptions Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/clients.md Demonstrates how to catch specific validation exceptions raised by the clients. Use this to handle schema mismatches, undocumented sections, or casing errors. ```python from openapi_tester.exceptions import ( DocumentationError, UndocumentedSchemaSectionError, CaseError ) try: response = client.get('/api/users/') except DocumentationError as e: print(f"Schema mismatch: {e}") except UndocumentedSchemaSectionError as e: print(f"Endpoint not documented: {e}") except CaseError as e: print(f"Key casing error: {e}") ``` -------------------------------- ### BaseSchemaLoader load_schema Method Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Abstract method that must be implemented by subclasses. It is responsible for loading and returning the OpenAPI schema as a dictionary. ```python def load_schema(self) -> dict: """Raises: NotImplementedError""" ``` -------------------------------- ### SchemaTester Loader Selection Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/loaders.md Instantiate SchemaTester to automatically detect loaders or specify a schema file path for manual override. ```python from openapi_tester import SchemaTester # Auto-detect drf-spectacular/drf-yasg tester = SchemaTester() # Use static file tester = SchemaTester(schema_file_path="./schemas/api.yaml") # Use remote URL tester = SchemaTester(schema_file_path="https://api.example.com/schema.json") ``` -------------------------------- ### DRF Client Response Handling Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/response-handlers.md Demonstrates using APIClient from DRF with SchemaTester and ResponseHandlerFactory to validate API responses. ```python from rest_framework.test import APIClient from openapi_tester import SchemaTester from openapi_tester.response_handler_factory import ResponseHandlerFactory client = APIClient() tester = SchemaTester() response = client.get('/api/users/') handler = ResponseHandlerFactory.create( 'GET', '/api/users/', response=response ) print(handler.request.path) # "/api/users/" print(handler.request.method) # "GET" print(handler.data) # Response body dict print(handler.endpoint()) # "GET /api/users/" tester.validate_response(handler) ``` -------------------------------- ### DjangoNinjaResponseHandler _build_request_path Method Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/response-handlers.md Constructs the full request path by combining a path prefix with the request path. Strips any query string from the final path. ```python def _build_request_path(self, request_path: str, path_prefix: str) -> str: pass ``` -------------------------------- ### Prepare Query Params for Validation Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/utilities.md Converts a list of OpenAPI query parameter definitions into an object schema. This prepares query parameters for validation using `test_schema_section`. ```python from openapi_tester.utils import query_params_to_object params = [ {"name": "page", "in": "query", "required": True, "schema": {"type": "integer"}}, {"name": "search", "in": "query", "required": False, "schema": {"type": "string"}} ] object_schema = query_params_to_object(params) # Now can be validated with test_schema_section() ``` -------------------------------- ### Configure pyproject.toml Source: https://github.com/maticardenas/django-contract-tester/blob/master/README.md Configure the library using the `[tool.django-contract-tester]` section in `pyproject.toml`. This TOML format supports disabling validations and excluding endpoints. ```toml [tool.django-contract-tester] ignore_case = ["ID", "API", "URL"] [tool.django-contract-tester.validation] request = true response = true types = true formats = true query_parameters = true disabled_types = ["integer"] disabled_formats = ["date-time", "email"] disabled_constraints = [ "enum", "pattern", "minLength", "maxLength", "minimum", "maximum", "multipleOf" ] ``` -------------------------------- ### DjangoNinjaResponseHandler Constructor Source: https://github.com/maticardenas/django-contract-tester/blob/master/_autodocs/response-handlers.md Initializes DjangoNinjaResponseHandler with request arguments and a Django Ninja response object. Allows specifying a path prefix and additional headers. Handles positional arguments for method, path, and body. ```python # Typical usage (called internally by OpenAPINinjaClient) handler = DjangoNinjaResponseHandler( "GET", "/api/users/1/?page=1", None, response=response, path_prefix="/api/v1" ) ```