Skip to content

Docs fire 1030 #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 27 additions & 26 deletions docs/routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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**:
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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).
Expand All @@ -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

Expand All @@ -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 ``<<Classname with Capitalised name>>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 ``<<Classname with Capitalised name>>View``.
In the above YAML the necessary MethodView implementation is as follows:

.. code-block:: python

Expand Down Expand Up @@ -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

Expand All @@ -232,42 +233,42 @@ 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
-------------------------

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
<http://www.odata.org>`_ 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
<http://flask.pocoo.org/docs/0.12/quickstart/#variable-rules>`_.
Specify a route parameter's type as ``integer`` or ``number`` or its type as
Expand All @@ -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/<path:name>``, allowing
requests to include forward slashes in the ``name`` url variable.
This creates an equivalent Flask route ``/greeting/<path:name>``, allowing
requests to include forward slashes in the ``name`` URL variable.

API Versioning and basePath
---------------------------
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
36 changes: 19 additions & 17 deletions docs/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,20 +24,22 @@ or set ``SCOPEVALIDATE_FUNC`` env var, otherwise default scope validation functi


The recommended approach is to return a dict which complies with
`RFC 7662 <rfc7662_>`_. Note that you have to validate the ``active``
or ``exp`` fields etc. yourself.
`RFC 7662 <rfc7662_>`_.

**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``
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 <rfc6749_>`_.
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 <rfc6750_>`_ section 2.1. This aspect represents
a significant difference from the usual OAuth flow.
Expand All @@ -46,47 +48,47 @@ 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

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

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
Expand All @@ -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
Expand All @@ -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.

Expand Down