Skip to content

Commit de2f1e3

Browse files
authored
Merge pull request #57 from djpugh/maintenance/docs
2 parents 0722c88 + 665e695 commit de2f1e3

File tree

8 files changed

+61
-28
lines changed

8 files changed

+61
-28
lines changed

docs/source/conf.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@
127127
#keep_warnings = False
128128

129129
autoclass_content='both'
130+
autodoc_class_signature='mix'
131+
130132
# -- Options for HTML output ----------------------------------------------
131133

132134
# The theme to use for HTML and HTML Help pages. See the documentation for
@@ -478,15 +480,18 @@ def _process_variables(self, object, path):
478480
config_vars = []
479481
config_nested = {}
480482
for field_name, field in object.__fields__.items():
481-
if BaseModel in field.type_.__mro__:
483+
484+
if 'providers' == field_name:
485+
config_nested[field_name] = [' List of auth provider classes to use (defaults to AAD)', '']
486+
elif BaseModel in field.type_.__mro__:
482487
# This is recursive here
483488
config_nested[field_name] = self._process_variables(field.type_, f'{path}.{field_name}')
484489
else:
485490
default_str = ''
486491
if field.default:
487492
if not SecretStr in field.type_.__mro__:
488493
if Path in field.type_.__mro__:
489-
field.default = Path(field.default).relative_to(Path(field.default).parents[2])
494+
field.default = str(Path(field.default).relative_to(Path(field.default).parents[2]))
490495
if field_name == 'user_klass':
491496
default_str = f' [default: :class:`{field.default.replace("`", "").replace(":", ".")}`]'
492497
else:
@@ -511,10 +516,18 @@ def _process_variables(self, object, path):
511516
config_vars.append(f' ``{path}.{field_name}``:')
512517
for var in config_nested[field_name]:
513518
config_vars.append(f' {var}')
519+
config_vars.append('')
514520
return config_vars
515521

516522

523+
def autodoc_process_pydantic_signature(app, what, name, obj, options, signature, return_annotation):
524+
if what=='class' and BaseModel in obj.__mro__:
525+
signature = '(**kwargs)'
526+
return signature, return_annotation
527+
528+
517529
def setup(app):
518530
from sphinx.util.texescape import tex_replacements
519531
tex_replacements += [(u'£', u"\\")]
520532
app.add_autodocumenter(ConfigDocumenter)
533+
app.connect('autodoc-process-signature', autodoc_process_pydantic_signature)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fastapi_aad_auth.config
22
***********************
3-
3+
44
.. automodule:: fastapi_aad_auth.config
5-
:members:
5+
:members:

src/fastapi_aad_auth/auth.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@
2626
class Authenticator(LoggingMixin):
2727
"""Authenticator class.
2828
29-
Creates the key components based on the provided configurations
29+
Creates the key components based on the provided configurations.
3030
"""
3131

3232
def __init__(self, config: Config = None, add_to_base_routes: bool = True, base_context: Optional[Dict[str, Any]] = None, user_klass: Optional[type] = None):
3333
"""Initialise the Authenticator based on the provided configuration.
3434
3535
Keyword Args:
36-
config (fastapi_aad_auth.config.Config): Authentication configuration (includes ui and routing, as well as AAD Application and Tenant IDs)
37-
add_to_base_routes (bool): Add the authentication to the router
38-
base_context (Dict[str, Any]): a base context to provide
39-
user_klass (type): The user class to use as part of the auth state
36+
* config (fastapi_aad_auth.config.Config): Authentication configuration (includes ui and routing, as well as AAD Application and Tenant IDs)
37+
* add_to_base_routes (bool): Add the authentication to the router
38+
* base_context (Dict[str, Any]): a base context to provide
39+
* user_klass (type): The user class to use as part of the auth state
4040
"""
4141
super().__init__()
4242
if config is None:

src/fastapi_aad_auth/config.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
class BaseSettings(DeprecatableFieldsMixin, _BaseSettings):
1414
"""Allow deprecations in the BaseSettings object."""
1515

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

1722
_DEPRECATION_VERSION = '0.2.0'
1823

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

106111
class Config: # noqa D106
@@ -117,7 +122,7 @@ class SessionConfig(BaseSettings):
117122
118123
Provides configuration for the fastapi session middleware
119124
"""
120-
secret_key: SecretStr = Field(str(uuid.uuid4()), description="Secret used for the session middleware",
125+
secret_key: SecretStr = Field(default_factory=lambda: str(uuid.uuid4()), description="Secret used for the session middleware",
121126
env='SESSION_SECRET')
122127
session_cookie: str = Field('session', description="Cookie name for the session information",
123128
env='SESSION_COOKIE')

src/fastapi_aad_auth/providers/aad.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -273,21 +273,21 @@ def __init__(
273273
"""Initialise the auth backend.
274274
275275
Args:
276-
session_serializer: Session serializer object
277-
client_id: Client ID from Azure App Registration
278-
tenant_id: Tenant ID to connect to for Azure App Registration
276+
* session_serializer: Session serializer object
277+
* client_id: Client ID from Azure App Registration
278+
* tenant_id: Tenant ID to connect to for Azure App Registration
279279
280280
Keyword Args:
281-
prompt: Prompt options for Azure AD
282-
client_secret: Client secret value
283-
scopes: Additional scopes requested
284-
enabled: Boolean flag to enable this backend
285-
client_app_ids: List of client apps to accept tokens from
286-
strict_token: Strictly evaluate token
287-
api_audience: Api Audience declared in Azure AD App registration
288-
redirect_uri: Full URI for post authentication callbacks
289-
domain_hint: Hint for the domain
290-
user_klass: Class to use as a user.
281+
* prompt: Prompt options for Azure AD
282+
* client_secret: Client secret value
283+
* scopes: Additional scopes requested
284+
* enabled: Boolean flag to enable this backend
285+
* client_app_ids: List of client apps to accept tokens from
286+
* strict_token: Strictly evaluate token
287+
* api_audience: Api Audience declared in Azure AD App registration
288+
* redirect_uri: Full URI for post authentication callbacks
289+
* domain_hint: Hint for the domain
290+
* user_klass: Class to use as a user.
291291
"""
292292
redirect_path = self._build_oauth_url(oauth_base_route, 'redirect')
293293
token_validator = AADTokenValidator(client_id=client_id, tenant_id=tenant_id, api_audience=api_audience,

src/fastapi_aad_auth/utilities/__init__.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"""Utilities."""
22
import importlib
3+
from pathlib import Path
34
from typing import List, Union
45

6+
from pydantic import SecretStr
57
from pydantic.main import ModelMetaclass
68
from starlette.requests import Request
79

@@ -49,8 +51,20 @@ def expand_doc(klass: ModelMetaclass) -> ModelMetaclass:
4951
docs = ['', '', 'Keyword Args:']
5052
for name, field in klass.__fields__.items(): # type: ignore
5153
default_str = ''
54+
#
5255
if field.default:
53-
default_str = f' [default: ``{field.default}``]'
56+
default_str = ''
57+
if field.default:
58+
if SecretStr not in field.type_.__mro__:
59+
default = field.default
60+
if Path in field.type_.__mro__:
61+
default = str(Path(default).relative_to(Path(default).parents[2]))
62+
if field.name == 'user_klass':
63+
default_str = f' [default: :class:`{default.replace("`", "").replace(":", ".")}`]'
64+
else:
65+
default_str = f' [default: ``{default}``]'
66+
else:
67+
default_str = ' [default: ``uuid.uuid4()``]'
5468
module = field.outer_type_.__module__
5569
if module != 'builtins':
5670
if hasattr(field.outer_type_, '__origin__'):

src/fastapi_aad_auth/utilities/deprecate.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def DeprecatedField(*args, **kwargs): # noqa: D103
4343

4444
class DeprecatableFieldsMixin:
4545
"""Mixin for deprecatable fields."""
46+
4647
def __new__(cls, *args, **kwargs):
4748
"""Initialise the Field Deprecation Validator."""
4849
for field_name, field in cls.__fields__.items():
@@ -110,7 +111,7 @@ def _update_docstring(deprecation_message, docstring=None):
110111
docstring = ''
111112
else:
112113
docstring += '\n\n'
113-
docstring += f"DEPRECATED - {deprecation_message}"
114+
docstring += f"*DEPRECATED* - {deprecation_message}"
114115
return docstring
115116

116117

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ commands =
2828
lint: flake8 src/
2929
lint: pipenv check
3030
test: pytest {posargs: -rs tests/unit --log-level=WARNING --cov=fastapi_aad_auth --cov-report xml:{toxinidir}/reports/{envname}-coverage.xml}
31-
docs: python -m sphinx -b html -a {toxinidir}/docs/source {toxinidir}/docs/html
31+
docs: python -m sphinx -E -b html -a {toxinidir}/docs/source {toxinidir}/docs/html
3232
build: python setup.py sdist --format=zip
3333
build: python setup.py sdist --format=gztar
3434
build: python setup.py bdist_wheel

0 commit comments

Comments
 (0)