apexdevkit 1.23.6__tar.gz → 1.23.8__tar.gz
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.
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/PKG-INFO +1 -1
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/resource.py +19 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/router.py +22 -1
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/schema.py +12 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/service.py +3 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/http/fake.py +2 -2
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/http/fluent.py +3 -3
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/http/httpx/client.py +9 -4
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/testing/rest.py +9 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/pyproject.toml +1 -1
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/LICENSE +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/README.md +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/date.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/environment.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/error.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/builder.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/dependable.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/name.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/request.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fastapi/response.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/fluent.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/formatter.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/http/httpx/__init__.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/http/httpx/hooks.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/id.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/key_fn.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/query/__init__.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/query/generator.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/query/query.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/base.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/database.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/decorator.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/in_memory.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/interface.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/mssql.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/repository.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/sql.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/repository/sqlite.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/server.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/synchronization.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/testing/fake.py +0 -0
- {apexdevkit-1.23.6 → apexdevkit-1.23.8}/apexdevkit/value.py +0 -0
|
@@ -88,6 +88,19 @@ class RestfulResource:
|
|
|
88
88
|
|
|
89
89
|
return endpoint
|
|
90
90
|
|
|
91
|
+
def sum_with(self, Service, FilterOptions) -> _Endpoint: # type: ignore
|
|
92
|
+
def endpoint(service: Service, options: FilterOptions) -> _Response:
|
|
93
|
+
try:
|
|
94
|
+
return {
|
|
95
|
+
"status": "success",
|
|
96
|
+
"code": 200,
|
|
97
|
+
"count": service.sum_with(options),
|
|
98
|
+
}
|
|
99
|
+
except ForbiddenError as e:
|
|
100
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
101
|
+
|
|
102
|
+
return endpoint
|
|
103
|
+
|
|
91
104
|
def read_all(self, Service) -> _Endpoint: # type: ignore
|
|
92
105
|
def endpoint(service: Service) -> _Response:
|
|
93
106
|
try:
|
|
@@ -312,3 +325,9 @@ class SummaryResponse(BaseModel):
|
|
|
312
325
|
status: str
|
|
313
326
|
code: int
|
|
314
327
|
data: _SummaryListEnvelope
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
class SumResponse(BaseModel):
|
|
331
|
+
status: str
|
|
332
|
+
code: int
|
|
333
|
+
count: int
|
|
@@ -7,7 +7,7 @@ from fastapi import APIRouter, Depends, Path, Query
|
|
|
7
7
|
from fastapi.responses import JSONResponse
|
|
8
8
|
|
|
9
9
|
from apexdevkit.fastapi.name import RestfulName
|
|
10
|
-
from apexdevkit.fastapi.resource import RestfulResource, SummaryResponse
|
|
10
|
+
from apexdevkit.fastapi.resource import RestfulResource, SummaryResponse, SumResponse
|
|
11
11
|
from apexdevkit.fastapi.response import RestfulResponse
|
|
12
12
|
from apexdevkit.fastapi.schema import RestfulSchema, Schema, SchemaFields
|
|
13
13
|
from apexdevkit.fastapi.service import RawCollection, RawItem, RestfulService
|
|
@@ -185,6 +185,27 @@ class RestfulRouter:
|
|
|
185
185
|
|
|
186
186
|
return self
|
|
187
187
|
|
|
188
|
+
def with_sum_endpoint(
|
|
189
|
+
self,
|
|
190
|
+
dependency: Dependency | None = None,
|
|
191
|
+
is_documented: bool = True,
|
|
192
|
+
) -> Self:
|
|
193
|
+
self.router.add_api_route(
|
|
194
|
+
"/sum",
|
|
195
|
+
self.resource.sum_with(
|
|
196
|
+
Service=self._resolve(dependency),
|
|
197
|
+
FilterOptions=Annotated[RawItem, Depends(self.schema.for_sum())],
|
|
198
|
+
),
|
|
199
|
+
methods=["POST"],
|
|
200
|
+
status_code=200,
|
|
201
|
+
responses={},
|
|
202
|
+
response_model=SumResponse,
|
|
203
|
+
include_in_schema=is_documented,
|
|
204
|
+
summary="Sum",
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
return self
|
|
208
|
+
|
|
188
209
|
def with_read_all_endpoint(
|
|
189
210
|
self,
|
|
190
211
|
dependency: Dependency | None = None,
|
|
@@ -24,6 +24,9 @@ class SchemaFields(ABC):
|
|
|
24
24
|
def filters(self) -> FluentDict[type]:
|
|
25
25
|
return JsonDict()
|
|
26
26
|
|
|
27
|
+
def sum_filters(self) -> FluentDict[type]:
|
|
28
|
+
return JsonDict()
|
|
29
|
+
|
|
27
30
|
@abstractmethod
|
|
28
31
|
def readable(self) -> FluentDict[type]: # pragma: no cover
|
|
29
32
|
pass
|
|
@@ -43,6 +46,7 @@ class RestfulSchema:
|
|
|
43
46
|
"UpdateManyItem", self.fields.editable().merge(self.fields.id())
|
|
44
47
|
)
|
|
45
48
|
self._schema_for("Filter", self.fields.filters())
|
|
49
|
+
self._schema_for("Sum", self.fields.sum_filters())
|
|
46
50
|
|
|
47
51
|
self._schema_for("Item", {self.name.singular: schema})
|
|
48
52
|
self._schema_for("Collection", {self.name.plural: list[schema], "count": int})
|
|
@@ -143,6 +147,14 @@ class RestfulSchema:
|
|
|
143
147
|
|
|
144
148
|
return _
|
|
145
149
|
|
|
150
|
+
def for_sum(self) -> Callable[[BaseModel], dict[str, Any]]:
|
|
151
|
+
schema = self.schemas["Sum"]
|
|
152
|
+
|
|
153
|
+
def _(request: schema) -> dict[str, Any]:
|
|
154
|
+
return request.model_dump()
|
|
155
|
+
|
|
156
|
+
return _
|
|
157
|
+
|
|
146
158
|
|
|
147
159
|
@dataclass(frozen=True)
|
|
148
160
|
class Schema:
|
|
@@ -38,6 +38,9 @@ class RestfulService: # pragma: no cover
|
|
|
38
38
|
def filter_with(self, options: RawItem) -> RawCollection:
|
|
39
39
|
raise NotImplementedError(self.filter_with.__name__)
|
|
40
40
|
|
|
41
|
+
def sum_with(self, options: RawItem) -> int:
|
|
42
|
+
raise NotImplementedError(self.filter_with.__name__)
|
|
43
|
+
|
|
41
44
|
def read_all(self) -> RawCollection:
|
|
42
45
|
raise NotImplementedError(self.read_all.__name__)
|
|
43
46
|
|
|
@@ -45,7 +45,7 @@ class FakeHttp:
|
|
|
45
45
|
headers: dict[str, str] = field(default_factory=dict)
|
|
46
46
|
params: dict[str, str] = field(default_factory=dict)
|
|
47
47
|
json: JsonDict = field(default_factory=JsonDict)
|
|
48
|
-
data:
|
|
48
|
+
data: Any = field(default_factory=JsonDict)
|
|
49
49
|
|
|
50
50
|
_request: InterceptedRequest = field(init=False)
|
|
51
51
|
|
|
@@ -67,7 +67,7 @@ class FakeHttp:
|
|
|
67
67
|
|
|
68
68
|
return self
|
|
69
69
|
|
|
70
|
-
def with_data(self, value:
|
|
70
|
+
def with_data(self, value: Any) -> Self:
|
|
71
71
|
self.data = value
|
|
72
72
|
|
|
73
73
|
return self
|
|
@@ -20,7 +20,7 @@ class Http(Protocol): # pragma: no cover
|
|
|
20
20
|
def with_json(self, value: JsonDict) -> Http:
|
|
21
21
|
pass
|
|
22
22
|
|
|
23
|
-
def with_data(self, value:
|
|
23
|
+
def with_data(self, value: Any) -> Http:
|
|
24
24
|
pass
|
|
25
25
|
|
|
26
26
|
def request(self, method: HttpMethod, endpoint: str = "") -> HttpResponse:
|
|
@@ -68,10 +68,10 @@ class FluentHttp:
|
|
|
68
68
|
def with_json(self, value: JsonDict) -> FluentHttp:
|
|
69
69
|
return FluentHttp(self.http.with_json(value))
|
|
70
70
|
|
|
71
|
-
def and_data(self, value:
|
|
71
|
+
def and_data(self, value: Any) -> FluentHttp:
|
|
72
72
|
return self.with_data(value)
|
|
73
73
|
|
|
74
|
-
def with_data(self, value:
|
|
74
|
+
def with_data(self, value: Any) -> FluentHttp:
|
|
75
75
|
return FluentHttp(self.http.with_data(value))
|
|
76
76
|
|
|
77
77
|
def post(self) -> FluentHttpRequest:
|
|
@@ -38,7 +38,7 @@ class Httpx:
|
|
|
38
38
|
def with_param(self, key: str, value: str) -> Httpx:
|
|
39
39
|
return Httpx(self.client, self.config.with_param(key, value))
|
|
40
40
|
|
|
41
|
-
def with_data(self, value:
|
|
41
|
+
def with_data(self, value: Any) -> Httpx:
|
|
42
42
|
return Httpx(self.client, self.config.with_data(value))
|
|
43
43
|
|
|
44
44
|
def with_json(self, value: JsonDict) -> Httpx:
|
|
@@ -120,7 +120,7 @@ class HttpxConfig(Mapping[str, Any]):
|
|
|
120
120
|
headers: JsonDict = field(default_factory=JsonDict)
|
|
121
121
|
params: JsonDict = field(default_factory=JsonDict)
|
|
122
122
|
json: JsonDict | None = None
|
|
123
|
-
data:
|
|
123
|
+
data: Any | None = None
|
|
124
124
|
|
|
125
125
|
def with_endpoint(self, endpoint: str) -> HttpxConfig:
|
|
126
126
|
return HttpxConfig(
|
|
@@ -149,7 +149,7 @@ class HttpxConfig(Mapping[str, Any]):
|
|
|
149
149
|
data=self.data,
|
|
150
150
|
)
|
|
151
151
|
|
|
152
|
-
def with_data(self, value:
|
|
152
|
+
def with_data(self, value: Any) -> HttpxConfig:
|
|
153
153
|
return HttpxConfig(
|
|
154
154
|
endpoint=self.endpoint,
|
|
155
155
|
headers=self.headers,
|
|
@@ -173,9 +173,14 @@ class HttpxConfig(Mapping[str, Any]):
|
|
|
173
173
|
"headers": dict(self.headers),
|
|
174
174
|
"params": dict(self.params),
|
|
175
175
|
"json": dict(self.json) if self.json is not None else None,
|
|
176
|
-
"data":
|
|
176
|
+
"data": self._data() if self.data is not None else None,
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
def _data(self) -> Any:
|
|
180
|
+
if isinstance(self.data, Mapping):
|
|
181
|
+
return dict(self.data)
|
|
182
|
+
return str(self.data)
|
|
183
|
+
|
|
179
184
|
def __len__(self) -> int:
|
|
180
185
|
return len(self.as_dict())
|
|
181
186
|
|
|
@@ -59,6 +59,15 @@ class _RestResource:
|
|
|
59
59
|
),
|
|
60
60
|
)
|
|
61
61
|
|
|
62
|
+
def sum_with(self) -> _TestRequest:
|
|
63
|
+
return _TestRequest(
|
|
64
|
+
self.name,
|
|
65
|
+
HttpRequest(
|
|
66
|
+
HttpMethod.post,
|
|
67
|
+
self.http.with_endpoint(self.name.plural).with_endpoint("sum"),
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
|
|
62
71
|
def read_all(self) -> _TestRequest:
|
|
63
72
|
return _TestRequest(
|
|
64
73
|
self.name,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|