nexo-schemas 0.0.16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. nexo/schemas/__init__.py +0 -0
  2. nexo/schemas/application.py +292 -0
  3. nexo/schemas/connection.py +134 -0
  4. nexo/schemas/data.py +27 -0
  5. nexo/schemas/document.py +237 -0
  6. nexo/schemas/error/__init__.py +476 -0
  7. nexo/schemas/error/constants.py +50 -0
  8. nexo/schemas/error/descriptor.py +354 -0
  9. nexo/schemas/error/enums.py +40 -0
  10. nexo/schemas/error/metadata.py +15 -0
  11. nexo/schemas/error/spec.py +312 -0
  12. nexo/schemas/exception/__init__.py +0 -0
  13. nexo/schemas/exception/exc.py +911 -0
  14. nexo/schemas/exception/factory.py +1928 -0
  15. nexo/schemas/exception/handlers.py +110 -0
  16. nexo/schemas/google.py +14 -0
  17. nexo/schemas/key/__init__.py +0 -0
  18. nexo/schemas/key/rsa.py +131 -0
  19. nexo/schemas/metadata.py +21 -0
  20. nexo/schemas/mixins/__init__.py +0 -0
  21. nexo/schemas/mixins/filter.py +140 -0
  22. nexo/schemas/mixins/general.py +65 -0
  23. nexo/schemas/mixins/hierarchy.py +19 -0
  24. nexo/schemas/mixins/identity.py +387 -0
  25. nexo/schemas/mixins/parameter.py +50 -0
  26. nexo/schemas/mixins/service.py +40 -0
  27. nexo/schemas/mixins/sort.py +111 -0
  28. nexo/schemas/mixins/timestamp.py +192 -0
  29. nexo/schemas/model.py +240 -0
  30. nexo/schemas/operation/__init__.py +0 -0
  31. nexo/schemas/operation/action/__init__.py +9 -0
  32. nexo/schemas/operation/action/base.py +14 -0
  33. nexo/schemas/operation/action/resource.py +371 -0
  34. nexo/schemas/operation/action/status.py +8 -0
  35. nexo/schemas/operation/action/system.py +6 -0
  36. nexo/schemas/operation/action/websocket.py +6 -0
  37. nexo/schemas/operation/base.py +289 -0
  38. nexo/schemas/operation/constants.py +18 -0
  39. nexo/schemas/operation/context.py +68 -0
  40. nexo/schemas/operation/dependency.py +26 -0
  41. nexo/schemas/operation/enums.py +168 -0
  42. nexo/schemas/operation/extractor.py +36 -0
  43. nexo/schemas/operation/mixins.py +53 -0
  44. nexo/schemas/operation/request.py +1066 -0
  45. nexo/schemas/operation/resource.py +839 -0
  46. nexo/schemas/operation/system.py +55 -0
  47. nexo/schemas/operation/websocket.py +55 -0
  48. nexo/schemas/pagination.py +67 -0
  49. nexo/schemas/parameter.py +60 -0
  50. nexo/schemas/payload.py +116 -0
  51. nexo/schemas/resource.py +64 -0
  52. nexo/schemas/response.py +1041 -0
  53. nexo/schemas/security/__init__.py +0 -0
  54. nexo/schemas/security/api_key.py +63 -0
  55. nexo/schemas/security/authentication.py +848 -0
  56. nexo/schemas/security/authorization.py +922 -0
  57. nexo/schemas/security/enums.py +32 -0
  58. nexo/schemas/security/impersonation.py +179 -0
  59. nexo/schemas/security/token.py +402 -0
  60. nexo/schemas/security/types.py +17 -0
  61. nexo/schemas/success/__init__.py +0 -0
  62. nexo/schemas/success/descriptor.py +100 -0
  63. nexo/schemas/success/enums.py +23 -0
  64. nexo/schemas/user_agent.py +46 -0
  65. nexo_schemas-0.0.16.dist-info/METADATA +87 -0
  66. nexo_schemas-0.0.16.dist-info/RECORD +69 -0
  67. nexo_schemas-0.0.16.dist-info/WHEEL +5 -0
  68. nexo_schemas-0.0.16.dist-info/licenses/LICENSE +21 -0
  69. nexo_schemas-0.0.16.dist-info/top_level.txt +1 -0
@@ -0,0 +1,55 @@
1
+ from typing import Generic, Literal
2
+ from nexo.types.boolean import BoolT
3
+ from ..connection import OptConnectionContext
4
+ from ..error import (
5
+ OptAnyErrorT,
6
+ AnyErrorT,
7
+ )
8
+ from ..response import OptResponseT, ErrorResponseT, OptSuccessResponseT
9
+ from .action.system import SystemOperationAction
10
+ from .base import BaseOperation
11
+ from .enums import OperationType
12
+
13
+
14
+ class SystemOperation(
15
+ BaseOperation[
16
+ SystemOperationAction,
17
+ None,
18
+ BoolT,
19
+ OptAnyErrorT,
20
+ OptConnectionContext,
21
+ OptResponseT,
22
+ None,
23
+ ],
24
+ Generic[
25
+ BoolT,
26
+ OptAnyErrorT,
27
+ OptResponseT,
28
+ ],
29
+ ):
30
+ type: OperationType = OperationType.SYSTEM
31
+ resource: None = None
32
+ response_context: None = None
33
+
34
+
35
+ class FailedSystemOperation(
36
+ SystemOperation[
37
+ Literal[False],
38
+ AnyErrorT,
39
+ ErrorResponseT,
40
+ ],
41
+ Generic[AnyErrorT, ErrorResponseT],
42
+ ):
43
+ success: Literal[False] = False
44
+
45
+
46
+ class SuccessfulSystemOperation(
47
+ SystemOperation[
48
+ Literal[True],
49
+ None,
50
+ OptSuccessResponseT,
51
+ ],
52
+ Generic[OptSuccessResponseT],
53
+ ):
54
+ success: Literal[True] = True
55
+ error: None = None
@@ -0,0 +1,55 @@
1
+ from typing import Generic, Literal
2
+ from nexo.types.boolean import BoolT
3
+ from ..connection import OptConnectionContext
4
+ from ..error import (
5
+ OptAnyErrorT,
6
+ AnyErrorT,
7
+ )
8
+ from ..response import OptResponseT, ErrorResponseT, OptSuccessResponseT
9
+ from .action.websocket import WebSocketOperationAction
10
+ from .base import BaseOperation
11
+ from .enums import OperationType
12
+
13
+
14
+ class WebSocketOperation(
15
+ BaseOperation[
16
+ WebSocketOperationAction,
17
+ None,
18
+ BoolT,
19
+ OptAnyErrorT,
20
+ OptConnectionContext,
21
+ OptResponseT,
22
+ None,
23
+ ],
24
+ Generic[
25
+ BoolT,
26
+ OptAnyErrorT,
27
+ OptResponseT,
28
+ ],
29
+ ):
30
+ type: OperationType = OperationType.WEBSOCKET
31
+ resource: None = None
32
+ response_context: None = None
33
+
34
+
35
+ class FailedWebSocketOperation(
36
+ WebSocketOperation[
37
+ Literal[False],
38
+ AnyErrorT,
39
+ ErrorResponseT,
40
+ ],
41
+ Generic[AnyErrorT, ErrorResponseT],
42
+ ):
43
+ success: Literal[False] = False
44
+
45
+
46
+ class SuccessfulWebSocketOperation(
47
+ WebSocketOperation[
48
+ Literal[True],
49
+ None,
50
+ OptSuccessResponseT,
51
+ ],
52
+ Generic[OptSuccessResponseT],
53
+ ):
54
+ success: Literal[True] = True
55
+ error: None = None
@@ -0,0 +1,67 @@
1
+ from enum import IntEnum
2
+ from pydantic import BaseModel, Field, model_validator
3
+ from typing import Annotated, Generic, Self, TypeVar
4
+ from nexo.types.integer import ListOfInts, OptInt
5
+
6
+
7
+ class Limit(IntEnum):
8
+ LIM_10 = 10
9
+ LIM_20 = 20
10
+ LIM_50 = 50
11
+ LIM_100 = 100
12
+
13
+ @classmethod
14
+ def choices(cls) -> ListOfInts:
15
+ return [e.value for e in cls]
16
+
17
+
18
+ class Page(BaseModel):
19
+ page: Annotated[int, Field(1, ge=1, description="Page number, must be >= 1")] = 1
20
+
21
+
22
+ class FlexibleLimit(BaseModel):
23
+ limit: Annotated[
24
+ OptInt, Field(None, description="Page limit. (Optional)", ge=1)
25
+ ] = None
26
+
27
+
28
+ class StrictLimit(BaseModel):
29
+ limit: Annotated[Limit, Field(Limit.LIM_10, description="Page limit")] = (
30
+ Limit.LIM_10
31
+ )
32
+
33
+
34
+ class PageInfo(BaseModel):
35
+ data_count: Annotated[int, Field(0, description="Fetched data count", ge=0)] = 0
36
+ total_data: Annotated[int, Field(0, description="Total data count", ge=0)] = 0
37
+ total_pages: Annotated[int, Field(1, description="Total pages count", ge=1)] = 1
38
+
39
+
40
+ class BaseFlexiblePagination(FlexibleLimit, Page):
41
+ @model_validator(mode="after")
42
+ def validate_page_and_limit(self) -> Self:
43
+ if self.limit is None:
44
+ self.page = 1
45
+ return self
46
+
47
+
48
+ class FlexiblePagination(PageInfo, BaseFlexiblePagination):
49
+ pass
50
+
51
+
52
+ class BaseStrictPagination(StrictLimit, Page):
53
+ pass
54
+
55
+
56
+ class StrictPagination(PageInfo, BaseStrictPagination):
57
+ pass
58
+
59
+
60
+ AnyPagination = FlexiblePagination | StrictPagination
61
+ PaginationT = TypeVar("PaginationT", bound=AnyPagination)
62
+ OptAnyPagination = AnyPagination | None
63
+ OptPaginationT = TypeVar("OptPaginationT", bound=OptAnyPagination)
64
+
65
+
66
+ class PaginationMixin(BaseModel, Generic[OptPaginationT]):
67
+ pagination: Annotated[OptPaginationT, Field(..., description="Pagination")]
@@ -0,0 +1,60 @@
1
+ from typing import Generic
2
+ from .mixins.filter import DateFilters
3
+ from .mixins.identity import IdentifierMixin, IdentifierT
4
+ from .mixins.parameter import (
5
+ MandatorySimpleDataStatusesMixin,
6
+ Search,
7
+ UseCache,
8
+ )
9
+ from .mixins.sort import SortColumns
10
+ from .operation.action.status import StatusUpdateOperationAction
11
+ from .pagination import BaseFlexiblePagination, BaseStrictPagination
12
+
13
+
14
+ class ReadSingleParameter(
15
+ UseCache,
16
+ MandatorySimpleDataStatusesMixin,
17
+ IdentifierMixin[IdentifierT],
18
+ Generic[IdentifierT],
19
+ ):
20
+ pass
21
+
22
+
23
+ class BaseReadMultipleParameter(
24
+ SortColumns,
25
+ Search,
26
+ MandatorySimpleDataStatusesMixin,
27
+ DateFilters,
28
+ ):
29
+ pass
30
+
31
+
32
+ class ReadUnpaginatedMultipleParameter(
33
+ UseCache,
34
+ BaseFlexiblePagination,
35
+ BaseReadMultipleParameter,
36
+ ):
37
+ pass
38
+
39
+
40
+ class ReadPaginatedMultipleParameter(
41
+ UseCache,
42
+ BaseStrictPagination,
43
+ BaseReadMultipleParameter,
44
+ ):
45
+ pass
46
+
47
+
48
+ class StatusUpdateParameter(
49
+ StatusUpdateOperationAction,
50
+ IdentifierMixin[IdentifierT],
51
+ Generic[IdentifierT],
52
+ ):
53
+ pass
54
+
55
+
56
+ class DeleteSingleParameter(
57
+ IdentifierMixin[IdentifierT],
58
+ Generic[IdentifierT],
59
+ ):
60
+ pass
@@ -0,0 +1,116 @@
1
+ from pydantic import BaseModel, Field
2
+ from typing import Generic, TypeVar
3
+ from .data import DataPair, AnyDataT, DataMixin, ModelDataT
4
+ from .metadata import MetadataMixin, AnyMetadataT, ModelMetadataT
5
+ from .mixins.general import Other
6
+ from .pagination import OptPaginationT, PaginationT, PaginationMixin
7
+
8
+
9
+ class Payload(
10
+ Other,
11
+ MetadataMixin[AnyMetadataT],
12
+ PaginationMixin[OptPaginationT],
13
+ DataMixin[AnyDataT],
14
+ BaseModel,
15
+ Generic[AnyDataT, OptPaginationT, AnyMetadataT],
16
+ ):
17
+ pass
18
+
19
+
20
+ PayloadT = TypeVar("PayloadT", bound=Payload)
21
+
22
+
23
+ class PayloadMixin(BaseModel, Generic[PayloadT]):
24
+ payload: PayloadT = Field(..., description="Payload")
25
+
26
+
27
+ class NoDataPayload(
28
+ Payload[None, None, ModelMetadataT],
29
+ Generic[ModelMetadataT],
30
+ ):
31
+ data: None = None
32
+ pagination: None = None
33
+
34
+
35
+ class SingleDataPayload(
36
+ Payload[ModelDataT, None, ModelMetadataT],
37
+ Generic[ModelDataT, ModelMetadataT],
38
+ ):
39
+ pagination: None = None
40
+
41
+
42
+ class CreateSingleDataPayload(
43
+ Payload[DataPair[None, ModelDataT], None, ModelMetadataT],
44
+ Generic[ModelDataT, ModelMetadataT],
45
+ ):
46
+ pass
47
+
48
+
49
+ class ReadSingleDataPayload(
50
+ Payload[DataPair[ModelDataT, None], None, ModelMetadataT],
51
+ Generic[ModelDataT, ModelMetadataT],
52
+ ):
53
+ pass
54
+
55
+
56
+ class UpdateSingleDataPayload(
57
+ Payload[DataPair[ModelDataT, ModelDataT], None, ModelMetadataT],
58
+ Generic[ModelDataT, ModelMetadataT],
59
+ ):
60
+ pass
61
+
62
+
63
+ class DeleteSingleDataPayload(
64
+ Payload[DataPair[ModelDataT, None], None, ModelMetadataT],
65
+ Generic[ModelDataT, ModelMetadataT],
66
+ ):
67
+ pass
68
+
69
+
70
+ class OptSingleDataPayload(
71
+ Payload[ModelDataT | None, None, ModelMetadataT],
72
+ Generic[ModelDataT, ModelMetadataT],
73
+ ):
74
+ pagination: None = None
75
+
76
+
77
+ class MultipleDataPayload(
78
+ Payload[list[ModelDataT], PaginationT, ModelMetadataT],
79
+ Generic[ModelDataT, PaginationT, ModelMetadataT],
80
+ ):
81
+ pass
82
+
83
+
84
+ class CreateMultipleDataPayload(
85
+ Payload[DataPair[None, list[ModelDataT]], PaginationT, ModelMetadataT],
86
+ Generic[ModelDataT, PaginationT, ModelMetadataT],
87
+ ):
88
+ pass
89
+
90
+
91
+ class ReadMultipleDataPayload(
92
+ Payload[DataPair[list[ModelDataT], None], PaginationT, ModelMetadataT],
93
+ Generic[ModelDataT, PaginationT, ModelMetadataT],
94
+ ):
95
+ pass
96
+
97
+
98
+ class UpdateMultipleDataPayload(
99
+ Payload[DataPair[list[ModelDataT], list[ModelDataT]], PaginationT, ModelMetadataT],
100
+ Generic[ModelDataT, PaginationT, ModelMetadataT],
101
+ ):
102
+ pass
103
+
104
+
105
+ class DeleteMultipleDataPayload(
106
+ Payload[DataPair[list[ModelDataT], None], PaginationT, ModelMetadataT],
107
+ Generic[ModelDataT, PaginationT, ModelMetadataT],
108
+ ):
109
+ pass
110
+
111
+
112
+ class OptMultipleDataPayload(
113
+ Payload[list[ModelDataT] | None, PaginationT, ModelMetadataT],
114
+ Generic[ModelDataT, PaginationT, ModelMetadataT],
115
+ ):
116
+ pass
@@ -0,0 +1,64 @@
1
+ from enum import StrEnum
2
+ from pydantic import BaseModel, Field
3
+ from typing import Annotated, Generic, Literal, TypeVar, overload
4
+ from nexo.types.dict import OptStrToAnyDict
5
+ from nexo.types.string import ListOfStrs
6
+
7
+
8
+ class AggregateField(StrEnum):
9
+ KEY = "key"
10
+ NAME = "name"
11
+ SLUG = "slug"
12
+
13
+ @classmethod
14
+ def choices(cls) -> ListOfStrs:
15
+ return [e.value for e in cls]
16
+
17
+
18
+ class ResourceIdentifier(BaseModel):
19
+ key: Annotated[str, Field(..., description="Key", pattern=r"^[a-zA-Z0-9_-]+$")]
20
+ name: Annotated[str, Field(..., description="Name")]
21
+ slug: Annotated[
22
+ str, Field(..., description="URL Slug", pattern=r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
23
+ ]
24
+
25
+
26
+ class Resource(BaseModel):
27
+ identifiers: Annotated[
28
+ list[ResourceIdentifier], Field(..., min_length=1, description="Identifiers")
29
+ ]
30
+ details: Annotated[OptStrToAnyDict, Field(None, description="Details")] = None
31
+
32
+ @overload
33
+ def aggregate(
34
+ self, field: Literal[AggregateField.KEY], *, sep: str = "_"
35
+ ) -> str: ...
36
+ @overload
37
+ def aggregate(
38
+ self, field: Literal[AggregateField.NAME], *, sep: str = " "
39
+ ) -> str: ...
40
+ @overload
41
+ def aggregate(
42
+ self, field: Literal[AggregateField.SLUG], *, sep: str = "/"
43
+ ) -> str: ...
44
+ @overload
45
+ def aggregate(
46
+ self, field: AggregateField = AggregateField.KEY, *, sep: str = "_"
47
+ ) -> str: ...
48
+ def aggregate(
49
+ self, field: AggregateField = AggregateField.KEY, *, sep: str = "_"
50
+ ) -> str:
51
+ if field is AggregateField.KEY:
52
+ return sep.join([id.key for id in self.identifiers])
53
+ elif field is AggregateField.NAME:
54
+ return sep.join([id.name for id in self.identifiers])
55
+ elif field is AggregateField.SLUG:
56
+ return sep.join([id.slug for id in self.identifiers])
57
+
58
+
59
+ OptResource = Resource | None
60
+ OptResourceT = TypeVar("OptResourceT", bound=OptResource)
61
+
62
+
63
+ class ResourceMixin(BaseModel, Generic[OptResourceT]):
64
+ resource: OptResourceT = Field(..., description="Resource")