mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
feat(backend): api schema stats (#9478)
* feat(backend): Add API Schema stats * add scope stats * fix scope output
This commit is contained in:
parent
2987cdfbb2
commit
bb1faf236a
@ -1,5 +1,6 @@
|
|||||||
"""Schema processing functions for cleaning up generated schema."""
|
"""Schema processing functions for cleaning up generated schema."""
|
||||||
|
|
||||||
|
from itertools import chain
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from drf_spectacular.openapi import AutoSchema
|
from drf_spectacular.openapi import AutoSchema
|
||||||
@ -78,3 +79,47 @@ def postprocess_required_nullable(result, generator, request, public):
|
|||||||
schema.pop('required')
|
schema.pop('required')
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def postprocess_print_stats(result, generator, request, public):
|
||||||
|
"""Prints statistics against schema."""
|
||||||
|
rlt_dict = {}
|
||||||
|
for path in result['paths']:
|
||||||
|
for method in result['paths'][path]:
|
||||||
|
sec = result['paths'][path][method].get('security', [])
|
||||||
|
scopes = list(filter(None, (item.get('oauth2') for item in sec)))
|
||||||
|
rlt_dict[f'{path}:{method}'] = {
|
||||||
|
'method': method,
|
||||||
|
'oauth': list(chain(*scopes)),
|
||||||
|
'sec': sec is None,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get paths without oauth2
|
||||||
|
no_oauth2 = [
|
||||||
|
path for path, details in rlt_dict.items() if not any(details['oauth'])
|
||||||
|
]
|
||||||
|
no_oauth2_wa = [path for path in no_oauth2 if not path.startswith('/api/auth/v1/')]
|
||||||
|
# Get paths without security
|
||||||
|
no_security = [path for path, details in rlt_dict.items() if details['sec']]
|
||||||
|
# Get path counts per scope
|
||||||
|
scopes = {}
|
||||||
|
for path, details in rlt_dict.items():
|
||||||
|
if details['oauth']:
|
||||||
|
for scope in details['oauth']:
|
||||||
|
if scope not in scopes:
|
||||||
|
scopes[scope] = []
|
||||||
|
scopes[scope].append(path)
|
||||||
|
# Sort scopes by keys
|
||||||
|
scopes = dict(sorted(scopes.items()))
|
||||||
|
|
||||||
|
# Print statistics
|
||||||
|
print('\nSchema statistics:')
|
||||||
|
print(f'Paths without oauth2: {len(no_oauth2)}')
|
||||||
|
print(f'Paths without oauth2 (without allauth): {len(no_oauth2_wa)}')
|
||||||
|
print(f'Paths without security: {len(no_security)}\n')
|
||||||
|
print('Scope stats:')
|
||||||
|
for scope, paths in scopes.items():
|
||||||
|
print(f' {scope}: {len(paths)}')
|
||||||
|
print()
|
||||||
|
|
||||||
|
return result
|
||||||
|
@ -1434,6 +1434,7 @@ SPECTACULAR_SETTINGS = {
|
|||||||
'POSTPROCESSING_HOOKS': [
|
'POSTPROCESSING_HOOKS': [
|
||||||
'drf_spectacular.hooks.postprocess_schema_enums',
|
'drf_spectacular.hooks.postprocess_schema_enums',
|
||||||
'InvenTree.schema.postprocess_required_nullable',
|
'InvenTree.schema.postprocess_required_nullable',
|
||||||
|
'InvenTree.schema.postprocess_print_stats',
|
||||||
],
|
],
|
||||||
'ENUM_NAME_OVERRIDES': {
|
'ENUM_NAME_OVERRIDES': {
|
||||||
'UserTypeEnum': 'users.models.UserProfile.UserType',
|
'UserTypeEnum': 'users.models.UserProfile.UserType',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user