mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +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:
		| @@ -1,5 +1,6 @@ | ||||
| """Schema processing functions for cleaning up generated schema.""" | ||||
|  | ||||
| from itertools import chain | ||||
| from typing import Optional | ||||
|  | ||||
| from drf_spectacular.openapi import AutoSchema | ||||
| @@ -78,3 +79,47 @@ def postprocess_required_nullable(result, generator, request, public): | ||||
|             schema.pop('required') | ||||
|  | ||||
|     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': [ | ||||
|         'drf_spectacular.hooks.postprocess_schema_enums', | ||||
|         'InvenTree.schema.postprocess_required_nullable', | ||||
|         'InvenTree.schema.postprocess_print_stats', | ||||
|     ], | ||||
|     'ENUM_NAME_OVERRIDES': { | ||||
|         'UserTypeEnum': 'users.models.UserProfile.UserType', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user