diff --git a/docs/routing.rst b/docs/routing.rst index 5418aee..8d1dc29 100644 --- a/docs/routing.rst +++ b/docs/routing.rst @@ -4,7 +4,7 @@ Routing Endpoint Routing to Your Python Views ------------------------------------- -Firetail uses the ``operationId`` from each `Operation Object`_ to +FireTail uses the ``operationId`` from each `Operation Object`_ to identify which Python function should handle each URL. **Explicit Routing**: @@ -31,7 +31,7 @@ definition, making ``operationId`` relative: x-swagger-router-controller: myapp.api operationId: hello_world -NOTE: If you are using an OpenAPI spec, you should use ``x-openapi-router-controller`` +**Note**: If you are using an OpenAPI spec, you should use ``x-openapi-router-controller`` in your operation definition, making ``operationId`` relative: .. code-block:: yaml @@ -54,17 +54,17 @@ instead of repeating the same ``x-swagger-router-controller`` or app.add_api('swagger.yaml', resolver=RelativeResolver('api')) -Keep in mind that Firetail follows how `HTTP methods work in Flask`_ +Keep in mind that FireTail follows how `HTTP methods work in Flask`_ and therefore HEAD requests will be handled by the ``operationId`` specified under GET in the specification. If both methods are supported, ``firetail.request.method`` can be used to determine which request was made. -By default, Firetail strictly enforces the presence of a handler +By default, FireTail strictly enforces the presence of a handler function for any path defined in your specification. Because of this, adding new paths without implementing a corresponding handler function will produce runtime errors and your application will not start. To allow new paths to be -added to your specification, e.g. in an API design first workflow, set the -``resolver_error`` to configure Firetail to provide an error response for +added to your specification, for example, in an API design first workflow, set the +``resolver_error`` to configure FireTail to provide an error response for paths that are not yet implemented: .. code-block:: python @@ -77,7 +77,7 @@ paths that are not yet implemented: Automatic Routing ----------------- -To customize this behavior, Firetail can use alternative +To customize this behavior, FireTail can use alternative ``Resolvers``—for example, ``RestyResolver``. The ``RestyResolver`` will compose an ``operationId`` based on the path and HTTP method of the endpoints in your specification: @@ -121,15 +121,16 @@ the endpoints in your specification: ``RestyResolver`` will give precedence to any ``operationId`` encountered in the specification. It will also respect ``x-swagger-router-controller`` and ``x-openapi-router-controller``. -You may import and extend ``firetail.resolver.Resolver`` to implement your own +You can import and extend ``firetail.resolver.Resolver`` to implement your own ``operationId`` (and function) resolution algorithm. -Note that when using multiple parameters in the path, they will be + +**Note**: When using multiple parameters in the path, they will be collected and all passed to the endpoint handlers. Automatic Routing with MethodViewResolver ------------------------------------------- -``MethodViewResolver`` is an customised Resolver based on ``RestyResolver`` +``MethodViewResolver`` is a customized Resolver based on ``RestyResolver`` to take advantage of MethodView structure of building Flask APIs. The ``MethodViewResolver`` will compose an ``operationId`` based on the path and HTTP method of the endpoints in your specification. The path will be based on the path you provide in the app.add_api and the path provided in the URL endpoint (specified in the swagger or openapi3). @@ -141,7 +142,7 @@ the endpoints in your specification. The path will be based on the path you prov app = firetail.FlaskApp(__name__) app.add_api('swagger.yaml', resolver=MethodViewResolver('api')) -And associated YAML +And associated YAML: .. code-block:: yaml @@ -163,8 +164,8 @@ And associated YAML # Implied operationId: api.FooView.delete -The structure expects a Class to exists inside the directory ``api`` that conforms to the naming ``<>View``. -In the above yaml the necessary MethodView implementation is as follows: +The structure expects a Class to exist inside the directory ``api`` that conforms to the naming ``<>View``. +In the above YAML the necessary MethodView implementation is as follows: .. code-block:: python @@ -223,7 +224,7 @@ In the above yaml the necessary MethodView implementation is as follows: # NOTE: we need to wrap it with list for Python 3 as dict_values is not JSON serializable return list(self.pets.values())[0:limit] -and a __init__.py file to make the Class visible in the api directory. +and a __init__.py file to make the Class visible in the API directory. .. code-block:: Python @@ -232,7 +233,7 @@ and a __init__.py file to make the Class visible in the api directory. ``MethodViewResolver`` will give precedence to any ``operationId`` encountered in the specification. It will also respect ``x-swagger-router-controller`` and ``x-openapi-router-controller``. -You may import and extend ``firetail.resolver.MethodViewResolver`` to implement +You can import and extend ``firetail.resolver.MethodViewResolver`` to implement your own ``operationId`` (and function) resolution algorithm. Parameter Name Sanitation @@ -240,34 +241,34 @@ Parameter Name Sanitation The names of query and form parameters, as well as the name of the body parameter are sanitized by removing characters that are not allowed in Python -symbols. I.e. all characters that are not letters, digits or the underscore are -removed, and finally characters are removed from the front until a letter or an -under-score is encountered. As an example: +symbols. That is, all characters that are not letters, digits or an underscore are +removed. Characters are removed from the front until a letter or an +underscore is encountered. For example: .. code-block:: python >>> re.sub('^[^a-zA-Z_]+', '', re.sub('[^0-9a-zA-Z_]', '', '$top')) 'top' -Without this sanitation it would e.g. be impossible to implement an +For example, without this sanitation it would be impossible to implement an `OData `_ API. -You can also convert *CamelCase* parameters to *snake_case* automatically using `pythonic_params` option: +You can also convert *CamelCase* parameters to *snake_case* automatically using a `pythonic_params` option: .. code-block:: python app = firetail.FlaskApp(__name__) app.add_api('api.yaml', ..., pythonic_params=True) -With this option enabled, Firetail firstly converts *CamelCase* names +With this option enabled, FireTail firstly converts *CamelCase* names to *snake_case*. Secondly it looks to see if the name matches a known built-in and if it does it appends an underscore to the name. Parameter Variable Converters ----------------------------- -Firetail supports Flask's ``int``, ``float``, and ``path`` route parameter +FireTail supports Flask's ``int``, ``float``, and ``path`` route parameter `variable converters `_. Specify a route parameter's type as ``integer`` or ``number`` or its type as @@ -285,8 +286,8 @@ Specify a route parameter's type as ``integer`` or ``number`` or its type as type: string format: path -will create an equivalent Flask route ``/greeting/``, allowing -requests to include forward slashes in the ``name`` url variable. +This creates an equivalent Flask route ``/greeting/``, allowing +requests to include forward slashes in the ``name`` URL variable. API Versioning and basePath --------------------------- @@ -295,7 +296,7 @@ Setting a base path is useful for versioned APIs. An example of a base path would be the ``1.0`` in ``http://MYHOST/1.0/hello_world``. If you are using OpenAPI 3.x.x, you set your base URL path in the -servers block of the specification. You can either specify a full +server's block of the specification. You can either specify a full URL, or just a relative path. .. code-block:: yaml @@ -340,7 +341,7 @@ You can choose another path through options: Swagger JSON ------------ -Firetail makes the OpenAPI/Swagger specification in JSON format +FireTail makes the OpenAPI/Swagger specification in JSON format available from ``swagger.json`` in the base path of the API. You can disable the Swagger JSON at the application level: diff --git a/docs/security.rst b/docs/security.rst index 7017568..d51658a 100644 --- a/docs/security.rst +++ b/docs/security.rst @@ -4,8 +4,8 @@ Security OAuth 2 Authentication and Authorization ---------------------------------------- -Firetail supports one of the three OAuth 2 handling methods. -With Firetail, the API security definition **must** include a +FireTail supports one of the three OAuth 2 handling methods. +With FireTail, the API security definition **must** include a ``x-tokenInfoFunc`` or set ``TOKENINFO_FUNC`` env var. ``x-tokenInfoFunc`` must contain a reference to a function @@ -24,8 +24,10 @@ or set ``SCOPEVALIDATE_FUNC`` env var, otherwise default scope validation functi The recommended approach is to return a dict which complies with -`RFC 7662 `_. Note that you have to validate the ``active`` -or ``exp`` fields etc. yourself. +`RFC 7662 `_. + +**Note**: You have to validate the ``active`` +or ``exp`` fields yourself. The Token Info response will be passed in the ``token_info`` argument to the handler function. The ``sub`` property of the Token Info response will be passed in the ``user`` @@ -33,11 +35,11 @@ argument to the handler function. Deprecated features, retained for backward compatibility: -- As alternative to ``x-tokenInfoFunc``, you can set ``x-tokenInfoUrl`` or +- As an alternative to ``x-tokenInfoFunc``, you can set ``x-tokenInfoUrl`` or ``TOKENINFO_URL`` env var. It must contain a URL to validate and get the token information which complies with `RFC 6749 `_. - When both ``x-tokenInfoUrl`` and ``x-tokenInfoFunc`` are used, Firetail - will prioritize the function method. Firetail expects the authorization + When both ``x-tokenInfoUrl`` and ``x-tokenInfoFunc`` are used, FireTail + will prioritize the function method. FireTail expects the authorization server to receive the OAuth token in the ``Authorization`` header field in the format described in `RFC 6750 `_ section 2.1. This aspect represents a significant difference from the usual OAuth flow. @@ -46,7 +48,7 @@ Deprecated features, retained for backward compatibility: You can find a `minimal OAuth example application`_ showing the use of ``x-tokenInfoUrl``, and `another OAuth example`_ showing the use of -``x-tokenInfoFunc`` in Firetail's "examples" folder. +``x-tokenInfoFunc`` in FireTail's "examples" folder. .. _minimal OAuth example application: https://github.com/FireTail-io/firetail-py-lib/tree/main/examples/swagger2/oauth2 .. _another OAuth example: https://github.com/FireTail-io/firetail-py-lib/tree/main/examples/swagger2/oauth2_local_tokeninfo @@ -54,12 +56,12 @@ You can find a `minimal OAuth example application`_ showing the use of Basic Authentication -------------------- -With Firetail, the API security definition **must** include a +With FireTail, the API security definition **must** include a ``x-basicInfoFunc`` or set ``BASICINFO_FUNC`` env var. It uses the same semantics as for ``x-tokenInfoFunc``, but the function accepts three parameters: username, password and required_scopes. -You can find a `minimal Basic Auth example application`_ in Firetail's "examples" folder. +You can find a `minimal Basic Auth example application`_ in FireTail's "examples" folder. .. _oauth scope: https://oauth.net/2/scope/ .. _minimal Basic Auth example application: https://github.com/FireTail-io/firetail-py-lib/tree/main/examples/openapi3/basicauth @@ -67,26 +69,26 @@ You can find a `minimal Basic Auth example application`_ in Firetail's "examples ApiKey Authentication --------------------- -With Firetail, the API security definition **must** include a +With FireTail, the API security definition **must** include a ``x-apikeyInfoFunc`` or set ``APIKEYINFO_FUNC`` env var. It uses the same semantics as for ``x-basicInfoFunc``, but the function accepts two parameters: apikey and required_scopes. -You can find a `minimal API Key example application`_ in Firetail's "examples" folder. +You can find a `minimal API Key example application`_ in FireTail's "examples" folder. Bearer Authentication (JWT) --------------------------- -With Firetail, the API security definition **must** include a +With FireTail, the API security definition **must** include a ``x-bearerInfoFunc`` or set ``BEARERINFO_FUNC`` env var. It uses the same semantics as for ``x-tokenInfoFunc``, but the function accepts one parameter: token. -You can find a `minimal JWT example application`_ in Firetail's "examples/openapi3" folder. +You can find a `minimal JWT example application`_ in FireTail's "examples/openapi3" folder. Multiple Authentication Schemes ------------------------------- -With Firetail, it is also possible to combine multiple authentication schemes +With FireTail, it is also possible to combine multiple authentication schemes as described in the `OpenAPI specification`_. When multiple authentication schemes are combined using logical AND, the ``token_info`` argument will consist of a dictionary mapping the names of the security scheme to their @@ -100,7 +102,7 @@ Deploying Authentication ------------------------ Some production hosting environments, such as Apache with modwsgi, do not by default pass -authentication headers to WSGI applications. Therefore, to allow firetail to handle +authentication headers to WSGI applications. Therefore, to allow FireTail to handle authentication, you will need to enable passthrough. Instructions for `enabling authentication passthrough in modwsgi`_ are available as @@ -127,7 +129,7 @@ One way, `described by Flask`_, looks like this: app.run(host='127.0.0.1', port='12344', debug=False/True, ssl_context=context) -However, Firetail doesn't provide an ssl_context parameter. This is +However, FireTail doesn't provide an ssl_context parameter. This is because Flask doesn't, either--but it uses ``**kwargs`` to send the parameters to the underlying `werkzeug`_ server.