from dataclasses import dataclass
from typing import TYPE_CHECKING, Annotated, Any, Final, TypeAlias
from dmr.internal.dataclass_aliases import Field
if TYPE_CHECKING:
from dmr.openapi.objects.operation import Operation
from dmr.openapi.objects.parameter import Parameter
from dmr.openapi.objects.reference import Reference
from dmr.openapi.objects.server import Server
_SplitOperations: TypeAlias = tuple[
# We can't use `Operation` here, because we use it for `**` operation,
# which requires `Any` :(
dict[str, Any],
dict[str, 'Operation'] | None,
]
_STANDARD_HTTP_METHODS: Final = frozenset((
'get',
'put',
'post',
'delete',
'options',
'head',
'patch',
'trace',
'query',
))
[docs]
@dataclass(kw_only=True, slots=True)
class PathItem:
"""
Describes the operations available on a single path.
A Path Item MAY be empty, due to ACL constraints.
The path itself is still exposed to the documentation viewer but
they will not know which operations and parameters are available.
.. versionchanged:: 0.16.0
Added ``x_extensions`` for specification extensions.
"""
ref: Annotated[str | None, Field(alias='$ref')] = None
summary: str | None = None
description: str | None = None
get: 'Operation | None' = None
put: 'Operation | None' = None
post: 'Operation | None' = None
delete: 'Operation | None' = None
options: 'Operation | None' = None
head: 'Operation | None' = None
patch: 'Operation | None' = None
trace: 'Operation | None' = None
query: 'Operation | None' = None
servers: list['Server'] | None = None
parameters: list['Parameter | Reference'] | None = None
additional_operations: dict[str, 'Operation'] | None = None
#: Specification extensions, keys must start with ``x-``.
x_extensions: dict[str, Any] | None = None
[docs]
@classmethod
def split_operations(
cls,
operations: dict[str, 'Operation'],
) -> _SplitOperations:
"""Split operations into standard HTTP methods and custom ones."""
standard: dict[str, Operation] = {}
additional: dict[str, Operation] = {}
# Sorted, so the schema does not depend on the definition order:
for method_name, operation in sorted(operations.items()):
if method_name in _STANDARD_HTTP_METHODS:
standard[method_name] = operation
else:
additional[method_name.upper()] = operation
return standard, additional or None