Browse Source

Use set for security scope dedup and skip redundant jsonable_encoder

Use a set instead of a list for scope deduplication in
get_openapi_security_definitions, converting O(S²) membership
checks to O(S). Output is sorted for deterministic schema generation.

Guard jsonable_encoder with a dict membership check to skip
redundant serialization when the same security scheme appears
in multiple dependencies.

Benchmark (50 scopes, 1-20 deps):
  Speed: 42.7 µs → 39.5 µs (−7%)
  RAM:   9.7 KB → 9.7 KB (0%)
pull/15621/head
sebastianbreguel 1 week ago
parent
commit
255b686969
  1. 25
      fastapi/openapi/utils.py

25
fastapi/openapi/utils.py

@ -82,24 +82,23 @@ def get_openapi_security_definitions(
flat_dependant: Dependant,
) -> tuple[dict[str, Any], list[dict[str, Any]]]:
security_definitions = {}
# Use a dict to merge scopes for same security scheme
operation_security_dict: dict[str, list[str]] = {}
# Use a dict of sets to merge scopes for same security scheme
operation_security_dict: dict[str, set[str]] = {}
for security_dependency in flat_dependant._security_dependencies:
security_definition = jsonable_encoder(
security_dependency._security_scheme.model,
by_alias=True,
exclude_none=True,
)
security_name = security_dependency._security_scheme.scheme_name
security_definitions[security_name] = security_definition
# Merge scopes for the same security scheme
if security_name not in security_definitions:
security_definition = jsonable_encoder(
security_dependency._security_scheme.model,
by_alias=True,
exclude_none=True,
)
security_definitions[security_name] = security_definition
if security_name not in operation_security_dict:
operation_security_dict[security_name] = []
operation_security_dict[security_name] = set()
for scope in security_dependency.oauth_scopes or []:
if scope not in operation_security_dict[security_name]:
operation_security_dict[security_name].append(scope)
operation_security_dict[security_name].add(scope)
operation_security = [
{name: scopes} for name, scopes in operation_security_dict.items()
{name: sorted(scopes)} for name, scopes in operation_security_dict.items()
]
return security_definitions, operation_security

Loading…
Cancel
Save