/falcon-oas

Design first approach with OpenAPI 3 for Falcon

Primary LanguagePythonApache License 2.0Apache-2.0

falcon-oas

PyPI CI Coverage

Prerequisites

  • Validated OpenAPI 3 document
    • falcon-oas does not validate OpenAPI 3 document itself at runtime. It should be validated in advance.

Features

  • Request validation and unmarshaling
  • Access control
  • Association of Path Item Objects and resource classes in Falcon

Example

class PetItem:
    def on_get(self, req, resp, pet_id):
        pet = get_pet_by_id(pet_id)
        resp.media = pet.to_dict()

    def on_delete(self, req, resp, pet_id):
        pet = delete_pet_by_id(pet_id)
        resp.status = falcon.HTTP_NO_CONTENT


with open('/path/to/openapi.json') as f:
    spec_dict = json.load(f)
api = falcon_oas.OAS(spec_dict).create_api()

Here is the part of its OpenAPI 3 document in YAML:

paths:
  /api/v1/pets/{pet_id}:
    x-falcon-oas-implementation: path.to.PetItem
    get:
      responses:
        '200':
          description: A pet.
    delete:
      responses:
        '204':
          description: Successful deletion.
      security:
      - api_key: []
    parameters:
    - name: pet_id
      in: path
      required: true
      schema:
        type: integer
components:
  securitySchemes:
    api_key:
      x-falcon-oas-implementation: path.to.api_key_validator
      type: apiKey
      name: X-API-Key
      in: header

pet_id path parameter is unmarshaled to int without Field Converters since it is defined as integer type.

DELETE /api/v1/pets/{pet_id} requests are protected by the api_key security scheme. The corresponding responder is processed only if it grants the request. Otherwise, 403 Forbidden error occurs automatically.

x-falcon-oas-implementation associates Path Item Object and the REST resource class in Falcon so that falcon-oas automatically calls falcon.API.add_route with its path and the resource instance. Alternatively, the resource instance can be set programmatically using oas.resolve_path_item('/api/v1/pets/{pet_id}', PetItem()), which allows to inject dependencies into the resource instance.

Also x-falcon-oas-implementation associates Security Scheme Object and the access control function so that falcon-oas automatically handles Security Requirement Object in each request. See falcon_oas.extensions for details. Alternatively, the access control function can be set programmatically using oas.resolve_security_scheme('api_key', validate_api_key), which allows to inject dependencies into the access control function.

req.context['oas']

req.context['oas'].user
Authorized user.
req.context['oas'].parameters
Unmarshaled request parameters in dict.
req.context['oas'].request_body
Unmarshaled request body.

Problems

Media Type: application/problem+json only

Unmarshal Error

HTTP status code: 400

  • "type": "https://pypi.org/project/falcon-oas/0.3.0/#unmarshal-error"
  • "title": "Unmarshal Error"
  • "status": 400
  • "parameters": (optional) The array of parameter error objects
  • "request_body": (optional) The array of request body error objects

The parameter error object and the request body error object have the following members from jsonschema.ValidationError:

  • "path": The path to the offending element within the instance
  • "validator": The name of the failed validator
  • "message": A human readable message explaining the error

Example:

{
  "type": "https://pypi.org/project/falcon-oas/0.3.0/#unmarshal-error",
  "title": "Unmarshal Error",
  "status": 400,
  "parameters": [
    {
      "path": ["path", "pet_id"],
      "validator": "type",
      "message": "'me' is not of type 'integer'"
    }
  ],
  "request_body": [
    {
      "path": ["name"],
      "validator": "type",
      "message": "42 is not of type 'string'"
    }
  ]
}