Skip to content

Commit

Permalink
Merge pull request #57 from djpugh/maintenance/docs
Browse files Browse the repository at this point in the history
  • Loading branch information
djpugh authored May 22, 2021
2 parents 0722c88 + 665e695 commit de2f1e3
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 28 deletions.
17 changes: 15 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@
#keep_warnings = False

autoclass_content='both'
autodoc_class_signature='mix'

# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
Expand Down Expand Up @@ -478,15 +480,18 @@ def _process_variables(self, object, path):
config_vars = []
config_nested = {}
for field_name, field in object.__fields__.items():
if BaseModel in field.type_.__mro__:

if 'providers' == field_name:
config_nested[field_name] = [' List of auth provider classes to use (defaults to AAD)', '']
elif BaseModel in field.type_.__mro__:
# This is recursive here
config_nested[field_name] = self._process_variables(field.type_, f'{path}.{field_name}')
else:
default_str = ''
if field.default:
if not SecretStr in field.type_.__mro__:
if Path in field.type_.__mro__:
field.default = Path(field.default).relative_to(Path(field.default).parents[2])
field.default = str(Path(field.default).relative_to(Path(field.default).parents[2]))
if field_name == 'user_klass':
default_str = f' [default: :class:`{field.default.replace("`", "").replace(":", ".")}`]'
else:
Expand All @@ -511,10 +516,18 @@ def _process_variables(self, object, path):
config_vars.append(f' ``{path}.{field_name}``:')
for var in config_nested[field_name]:
config_vars.append(f' {var}')
config_vars.append('')
return config_vars


def autodoc_process_pydantic_signature(app, what, name, obj, options, signature, return_annotation):
if what=='class' and BaseModel in obj.__mro__:
signature = '(**kwargs)'
return signature, return_annotation


def setup(app):
from sphinx.util.texescape import tex_replacements
tex_replacements += [(u'£', u"\\")]
app.add_autodocumenter(ConfigDocumenter)
app.connect('autodoc-process-signature', autodoc_process_pydantic_signature)
4 changes: 2 additions & 2 deletions docs/source/module/fastapi_aad_auth.config.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fastapi_aad_auth.config
***********************

.. automodule:: fastapi_aad_auth.config
:members:
:members:
10 changes: 5 additions & 5 deletions src/fastapi_aad_auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@
class Authenticator(LoggingMixin):
"""Authenticator class.
Creates the key components based on the provided configurations
Creates the key components based on the provided configurations.
"""

def __init__(self, config: Config = None, add_to_base_routes: bool = True, base_context: Optional[Dict[str, Any]] = None, user_klass: Optional[type] = None):
"""Initialise the Authenticator based on the provided configuration.
Keyword Args:
config (fastapi_aad_auth.config.Config): Authentication configuration (includes ui and routing, as well as AAD Application and Tenant IDs)
add_to_base_routes (bool): Add the authentication to the router
base_context (Dict[str, Any]): a base context to provide
user_klass (type): The user class to use as part of the auth state
* config (fastapi_aad_auth.config.Config): Authentication configuration (includes ui and routing, as well as AAD Application and Tenant IDs)
* add_to_base_routes (bool): Add the authentication to the router
* base_context (Dict[str, Any]): a base context to provide
* user_klass (type): The user class to use as part of the auth state
"""
super().__init__()
if config is None:
Expand Down
11 changes: 8 additions & 3 deletions src/fastapi_aad_auth/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
class BaseSettings(DeprecatableFieldsMixin, _BaseSettings):
"""Allow deprecations in the BaseSettings object."""

def __init__(self, *args, **kwargs): # type: ignore[no-redef]
"""Initialise the config object."""
# For handling docstrings
super().__init__(*args, **kwargs)


_DEPRECATION_VERSION = '0.2.0'

Expand Down Expand Up @@ -98,9 +103,9 @@ class AuthSessionConfig(BaseSettings):
variables in a multi-worker/multi-processing environment to enable
authentication across workers)
"""
secret: SecretStr = Field(str(uuid.uuid4()), description="Secret used for encoding authentication information",
secret: SecretStr = Field(default_factory=lambda: str(uuid.uuid4()), description="Secret used for encoding authentication information",
env='SESSION_AUTH_SECRET')
salt: SecretStr = Field(str(uuid.uuid4()), description="Salt used for encoding authentication information",
salt: SecretStr = Field(default_factory=lambda: str(uuid.uuid4()), description="Salt used for encoding authentication information",
env='SESSION_AUTH_SALT')

class Config: # noqa D106
Expand All @@ -117,7 +122,7 @@ class SessionConfig(BaseSettings):
Provides configuration for the fastapi session middleware
"""
secret_key: SecretStr = Field(str(uuid.uuid4()), description="Secret used for the session middleware",
secret_key: SecretStr = Field(default_factory=lambda: str(uuid.uuid4()), description="Secret used for the session middleware",
env='SESSION_SECRET')
session_cookie: str = Field('session', description="Cookie name for the session information",
env='SESSION_COOKIE')
Expand Down
26 changes: 13 additions & 13 deletions src/fastapi_aad_auth/providers/aad.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,21 +273,21 @@ def __init__(
"""Initialise the auth backend.
Args:
session_serializer: Session serializer object
client_id: Client ID from Azure App Registration
tenant_id: Tenant ID to connect to for Azure App Registration
* session_serializer: Session serializer object
* client_id: Client ID from Azure App Registration
* tenant_id: Tenant ID to connect to for Azure App Registration
Keyword Args:
prompt: Prompt options for Azure AD
client_secret: Client secret value
scopes: Additional scopes requested
enabled: Boolean flag to enable this backend
client_app_ids: List of client apps to accept tokens from
strict_token: Strictly evaluate token
api_audience: Api Audience declared in Azure AD App registration
redirect_uri: Full URI for post authentication callbacks
domain_hint: Hint for the domain
user_klass: Class to use as a user.
* prompt: Prompt options for Azure AD
* client_secret: Client secret value
* scopes: Additional scopes requested
* enabled: Boolean flag to enable this backend
* client_app_ids: List of client apps to accept tokens from
* strict_token: Strictly evaluate token
* api_audience: Api Audience declared in Azure AD App registration
* redirect_uri: Full URI for post authentication callbacks
* domain_hint: Hint for the domain
* user_klass: Class to use as a user.
"""
redirect_path = self._build_oauth_url(oauth_base_route, 'redirect')
token_validator = AADTokenValidator(client_id=client_id, tenant_id=tenant_id, api_audience=api_audience,
Expand Down
16 changes: 15 additions & 1 deletion src/fastapi_aad_auth/utilities/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"""Utilities."""
import importlib
from pathlib import Path
from typing import List, Union

from pydantic import SecretStr
from pydantic.main import ModelMetaclass
from starlette.requests import Request

Expand Down Expand Up @@ -49,8 +51,20 @@ def expand_doc(klass: ModelMetaclass) -> ModelMetaclass:
docs = ['', '', 'Keyword Args:']
for name, field in klass.__fields__.items(): # type: ignore
default_str = ''
#
if field.default:
default_str = f' [default: ``{field.default}``]'
default_str = ''
if field.default:
if SecretStr not in field.type_.__mro__:
default = field.default
if Path in field.type_.__mro__:
default = str(Path(default).relative_to(Path(default).parents[2]))
if field.name == 'user_klass':
default_str = f' [default: :class:`{default.replace("`", "").replace(":", ".")}`]'
else:
default_str = f' [default: ``{default}``]'
else:
default_str = ' [default: ``uuid.uuid4()``]'
module = field.outer_type_.__module__
if module != 'builtins':
if hasattr(field.outer_type_, '__origin__'):
Expand Down
3 changes: 2 additions & 1 deletion src/fastapi_aad_auth/utilities/deprecate.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def DeprecatedField(*args, **kwargs): # noqa: D103

class DeprecatableFieldsMixin:
"""Mixin for deprecatable fields."""

def __new__(cls, *args, **kwargs):
"""Initialise the Field Deprecation Validator."""
for field_name, field in cls.__fields__.items():
Expand Down Expand Up @@ -110,7 +111,7 @@ def _update_docstring(deprecation_message, docstring=None):
docstring = ''
else:
docstring += '\n\n'
docstring += f"DEPRECATED - {deprecation_message}"
docstring += f"*DEPRECATED* - {deprecation_message}"
return docstring


Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ commands =
lint: flake8 src/
lint: pipenv check
test: pytest {posargs: -rs tests/unit --log-level=WARNING --cov=fastapi_aad_auth --cov-report xml:{toxinidir}/reports/{envname}-coverage.xml}
docs: python -m sphinx -b html -a {toxinidir}/docs/source {toxinidir}/docs/html
docs: python -m sphinx -E -b html -a {toxinidir}/docs/source {toxinidir}/docs/html
build: python setup.py sdist --format=zip
build: python setup.py sdist --format=gztar
build: python setup.py bdist_wheel
Expand Down

0 comments on commit de2f1e3

Please sign in to comment.