apexdevkit 1.24.4__tar.gz → 1.25.2__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.
Files changed (54) hide show
  1. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/PKG-INFO +1 -1
  2. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/router.py +75 -55
  3. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/schema.py +6 -7
  4. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/pyproject.toml +1 -1
  5. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/LICENSE +0 -0
  6. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/README.md +0 -0
  7. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/__init__.py +0 -0
  8. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/annotation/__init__.py +0 -0
  9. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/annotation/deprecate.py +0 -0
  10. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/date.py +0 -0
  11. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/environment.py +0 -0
  12. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/error.py +0 -0
  13. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/__init__.py +0 -0
  14. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/builder.py +0 -0
  15. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/dependable.py +0 -0
  16. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/docs.py +0 -0
  17. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/name.py +0 -0
  18. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/resource.py +0 -0
  19. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/response.py +0 -0
  20. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fastapi/service.py +0 -0
  21. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/fluent.py +0 -0
  22. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/formatter.py +0 -0
  23. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/http/__init__.py +0 -0
  24. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/http/fake.py +0 -0
  25. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/http/fluent.py +0 -0
  26. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/http/httpx/__init__.py +0 -0
  27. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/http/httpx/client.py +0 -0
  28. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/http/httpx/hooks.py +0 -0
  29. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/http/json.py +0 -0
  30. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/http/url.py +0 -0
  31. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/id.py +0 -0
  32. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/key_fn.py +0 -0
  33. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/py.typed +0 -0
  34. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/query/__init__.py +0 -0
  35. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/query/generator.py +0 -0
  36. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/query/query.py +0 -0
  37. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/__init__.py +0 -0
  38. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/base.py +0 -0
  39. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/connector.py +0 -0
  40. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/database.py +0 -0
  41. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/decorator.py +0 -0
  42. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/in_memory.py +0 -0
  43. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/interface.py +0 -0
  44. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/mssql.py +0 -0
  45. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/repository.py +0 -0
  46. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/sql.py +0 -0
  47. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/repository/sqlite.py +0 -0
  48. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/server.py +0 -0
  49. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/synchronization.py +0 -0
  50. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/testing/__init__.py +0 -0
  51. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/testing/database.py +0 -0
  52. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/testing/fake.py +0 -0
  53. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/testing/rest.py +0 -0
  54. {apexdevkit-1.24.4 → apexdevkit-1.25.2}/apexdevkit/value.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apexdevkit
3
- Version: 1.24.4
3
+ Version: 1.25.2
4
4
  Summary: Apex Development Tools for python.
5
5
  License-File: LICENSE
6
6
  Author: Apex Dev
@@ -1,6 +1,5 @@
1
1
  from dataclasses import dataclass, field
2
2
  from enum import Enum
3
- from functools import cached_property
4
3
  from typing import Annotated, Any, Protocol, Self, TypeVar
5
4
 
6
5
  from fastapi import APIRouter, Depends, Path, Query
@@ -25,16 +24,28 @@ class Dependency(Protocol): # pragma: no cover
25
24
 
26
25
  @dataclass
27
26
  class RestfulRouter:
27
+ name: RestfulName
28
+
29
+ parent: RestfulName | None = None
28
30
  router: APIRouter = field(default_factory=APIRouter)
29
31
 
30
- name: RestfulName = field(init=False)
31
- fields: SchemaFields = field(init=False)
32
+ _schema: RestfulSchema = field(init=False)
33
+ _dependency: Dependency | None = field(init=False, default=None)
34
+
35
+ @classmethod
36
+ def named(cls, singular: str, *, plural: str | None = None) -> "RestfulRouter":
37
+ if plural:
38
+ return cls(RestfulName(singular, plural))
39
+
40
+ return cls(RestfulName(singular))
32
41
 
33
- dependency: Dependency | None = None
42
+ def child_of(self, singular: str, *, plural: str | None = None) -> Self:
43
+ self.parent = RestfulName(singular)
34
44
 
35
- @cached_property
36
- def schema(self) -> RestfulSchema:
37
- return RestfulSchema(name=self.name, fields=self.fields)
45
+ if plural:
46
+ self.parent = RestfulName(singular, plural)
47
+
48
+ return self
38
49
 
39
50
  @property
40
51
  def resource(self) -> RestfulResource:
@@ -48,27 +59,35 @@ class RestfulRouter:
48
59
  def item_path(self) -> str:
49
60
  return "/{" + self.id_alias + "}"
50
61
 
51
- def with_name(self, value: RestfulName) -> Self:
52
- self.name = value
62
+ def with_fields(self, value: SchemaFields) -> Self:
63
+ self._schema = RestfulSchema(
64
+ name=self.name,
65
+ fields=value,
66
+ generator=self._schema_generator,
67
+ )
53
68
 
54
69
  return self
55
70
 
56
- def with_fields(self, value: SchemaFields) -> Self:
57
- self.fields = value
71
+ @property
72
+ def _schema_generator(self) -> Schema:
73
+ if self.parent:
74
+ return Schema(
75
+ self.parent.singular.capitalize() + self.name.singular.capitalize()
76
+ )
58
77
 
59
- return self
78
+ return Schema(self.name.singular.capitalize())
60
79
 
61
80
  def with_tag(self, value: list[str | Enum]) -> Self:
62
81
  self.router.tags = value
63
82
 
64
83
  return self
65
84
 
66
- def with_dependency(self, value: Dependency) -> Self:
67
- self.dependency = value
85
+ def with_default_dependency(self, value: Dependency) -> Self:
86
+ self._dependency = value
68
87
 
69
88
  return self
70
89
 
71
- def with_create_one_endpoint(
90
+ def with_create_one(
72
91
  self,
73
92
  dependency: Dependency | None = None,
74
93
  is_documented: bool = True,
@@ -79,20 +98,20 @@ class RestfulRouter:
79
98
  Service=self._resolve(dependency),
80
99
  Item=Annotated[
81
100
  RawItem,
82
- Depends(self.schema.for_create_one()),
101
+ Depends(self._schema.for_create_one()),
83
102
  ],
84
103
  ),
85
104
  methods=["POST"],
86
105
  status_code=201,
87
106
  responses={409: {}},
88
- response_model=self.schema.for_item(),
107
+ response_model=self._schema.for_item(),
89
108
  include_in_schema=is_documented,
90
109
  summary="Create One",
91
110
  )
92
111
 
93
112
  return self
94
113
 
95
- def with_create_many_endpoint(
114
+ def with_create_many(
96
115
  self,
97
116
  dependency: Dependency | None = None,
98
117
  is_documented: bool = True,
@@ -103,20 +122,20 @@ class RestfulRouter:
103
122
  Service=self._resolve(dependency),
104
123
  Collection=Annotated[
105
124
  RawCollection,
106
- Depends(self.schema.for_create_many()),
125
+ Depends(self._schema.for_create_many()),
107
126
  ],
108
127
  ),
109
128
  methods=["POST"],
110
129
  status_code=201,
111
130
  responses={409: {}},
112
- response_model=self.schema.for_collection(),
131
+ response_model=self._schema.for_collection(),
113
132
  include_in_schema=is_documented,
114
133
  summary="Create Many",
115
134
  )
116
135
 
117
136
  return self
118
137
 
119
- def with_read_one_endpoint(
138
+ def with_read_one(
120
139
  self,
121
140
  dependency: Dependency | None = None,
122
141
  is_documented: bool = True,
@@ -133,14 +152,14 @@ class RestfulRouter:
133
152
  methods=["GET"],
134
153
  status_code=200,
135
154
  responses={404: {}},
136
- response_model=self.schema.for_item(),
155
+ response_model=self._schema.for_item(),
137
156
  include_in_schema=is_documented,
138
157
  summary="Read One",
139
158
  )
140
159
 
141
160
  return self
142
161
 
143
- def with_read_many_endpoint(
162
+ def with_read_many(
144
163
  self,
145
164
  query: FluentDict[Any],
146
165
  dependency: Dependency | None = None,
@@ -151,20 +170,21 @@ class RestfulRouter:
151
170
  self.resource.read_many(
152
171
  Service=self._resolve(dependency),
153
172
  QueryParams=Annotated[
154
- Schema(self.name).optional_schema_for("ReadMany", query), Query()
173
+ Schema(self.name.singular).optional_schema_for("ReadMany", query),
174
+ Query(),
155
175
  ],
156
176
  ),
157
177
  methods=["GET"],
158
178
  status_code=200,
159
179
  responses={},
160
- response_model=self.schema.for_collection(),
180
+ response_model=self._schema.for_collection(),
161
181
  include_in_schema=is_documented,
162
182
  summary="Read Many",
163
183
  )
164
184
 
165
185
  return self
166
186
 
167
- def with_filter_endpoint(
187
+ def with_filter(
168
188
  self,
169
189
  dependency: Dependency | None = None,
170
190
  is_documented: bool = True,
@@ -173,19 +193,19 @@ class RestfulRouter:
173
193
  "/filter",
174
194
  self.resource.filter_with(
175
195
  Service=self._resolve(dependency),
176
- QueryOptions=Annotated[RawItem, Depends(self.schema.for_filters())],
196
+ QueryOptions=Annotated[RawItem, Depends(self._schema.for_filters())],
177
197
  ),
178
198
  methods=["POST"],
179
199
  status_code=200,
180
200
  responses={},
181
- response_model=self.schema.for_collection(),
201
+ response_model=self._schema.for_collection(),
182
202
  include_in_schema=is_documented,
183
203
  summary="Read Filtered",
184
204
  )
185
205
 
186
206
  return self
187
207
 
188
- def with_aggregation_endpoint(
208
+ def with_aggregation(
189
209
  self,
190
210
  dependency: Dependency | None = None,
191
211
  is_documented: bool = True,
@@ -195,20 +215,20 @@ class RestfulRouter:
195
215
  self.resource.aggregation_with(
196
216
  Service=self._resolve(dependency),
197
217
  FilterOptions=Annotated[
198
- RawItem, Depends(self.schema.for_aggregation())
218
+ RawItem, Depends(self._schema.for_aggregation())
199
219
  ],
200
220
  ),
201
221
  methods=["POST"],
202
222
  status_code=200,
203
223
  responses={},
204
- response_model=self.schema.for_aggregation_result(),
224
+ response_model=self._schema.for_aggregation_result(),
205
225
  include_in_schema=is_documented,
206
226
  summary="Aggregation",
207
227
  )
208
228
 
209
229
  return self
210
230
 
211
- def with_read_all_endpoint(
231
+ def with_read_all(
212
232
  self,
213
233
  dependency: Dependency | None = None,
214
234
  is_documented: bool = True,
@@ -219,14 +239,14 @@ class RestfulRouter:
219
239
  methods=["GET"],
220
240
  status_code=200,
221
241
  responses={},
222
- response_model=self.schema.for_collection(),
242
+ response_model=self._schema.for_collection(),
223
243
  include_in_schema=is_documented,
224
244
  summary="Read All",
225
245
  )
226
246
 
227
247
  return self
228
248
 
229
- def with_update_one_endpoint(
249
+ def with_update_one(
230
250
  self,
231
251
  dependency: Dependency | None = None,
232
252
  is_documented: bool = True,
@@ -241,20 +261,20 @@ class RestfulRouter:
241
261
  ],
242
262
  Updates=Annotated[
243
263
  RawItem,
244
- Depends(self.schema.for_update_one()),
264
+ Depends(self._schema.for_update_one()),
245
265
  ],
246
266
  ),
247
267
  methods=["PATCH"],
248
268
  status_code=200,
249
269
  responses={404: {}},
250
- response_model=self.schema.for_no_data(),
270
+ response_model=self._schema.for_no_data(),
251
271
  include_in_schema=is_documented,
252
272
  summary="Update One",
253
273
  )
254
274
 
255
275
  return self
256
276
 
257
- def with_update_many_endpoint(
277
+ def with_update_many(
258
278
  self,
259
279
  dependency: Dependency | None = None,
260
280
  is_documented: bool = True,
@@ -265,20 +285,20 @@ class RestfulRouter:
265
285
  Service=self._resolve(dependency),
266
286
  Collection=Annotated[
267
287
  RawCollection,
268
- Depends(self.schema.for_update_many()),
288
+ Depends(self._schema.for_update_many()),
269
289
  ],
270
290
  ),
271
291
  methods=["PATCH"],
272
292
  status_code=200,
273
293
  responses={},
274
- response_model=self.schema.for_no_data(),
294
+ response_model=self._schema.for_no_data(),
275
295
  include_in_schema=is_documented,
276
296
  summary="Update Many",
277
297
  )
278
298
 
279
299
  return self
280
300
 
281
- def with_replace_one_endpoint(
301
+ def with_replace_one(
282
302
  self,
283
303
  dependency: Dependency | None = None,
284
304
  is_documented: bool = True,
@@ -289,20 +309,20 @@ class RestfulRouter:
289
309
  Service=self._resolve(dependency),
290
310
  Item=Annotated[
291
311
  RawItem,
292
- Depends(self.schema.for_replace_one()),
312
+ Depends(self._schema.for_replace_one()),
293
313
  ],
294
314
  ),
295
315
  methods=["PUT"],
296
316
  status_code=200,
297
317
  responses={404: {}},
298
- response_model=self.schema.for_no_data(),
318
+ response_model=self._schema.for_no_data(),
299
319
  include_in_schema=is_documented,
300
320
  summary="Replace One",
301
321
  )
302
322
 
303
323
  return self
304
324
 
305
- def with_replace_many_endpoint(
325
+ def with_replace_many(
306
326
  self,
307
327
  dependency: Dependency | None = None,
308
328
  is_documented: bool = True,
@@ -313,20 +333,20 @@ class RestfulRouter:
313
333
  Service=self._resolve(dependency),
314
334
  Collection=Annotated[
315
335
  RawCollection,
316
- Depends(self.schema.for_replace_many()),
336
+ Depends(self._schema.for_replace_many()),
317
337
  ],
318
338
  ),
319
339
  methods=["PUT"],
320
340
  status_code=200,
321
341
  responses={},
322
- response_model=self.schema.for_no_data(),
342
+ response_model=self._schema.for_no_data(),
323
343
  include_in_schema=is_documented,
324
344
  summary="Replace Many",
325
345
  )
326
346
 
327
347
  return self
328
348
 
329
- def with_delete_one_endpoint(
349
+ def with_delete_one(
330
350
  self,
331
351
  dependency: Dependency | None = None,
332
352
  is_documented: bool = True,
@@ -343,7 +363,7 @@ class RestfulRouter:
343
363
  methods=["DELETE"],
344
364
  status_code=200,
345
365
  responses={404: {}},
346
- response_model=self.schema.for_no_data(),
366
+ response_model=self._schema.for_no_data(),
347
367
  include_in_schema=is_documented,
348
368
  summary="Delete One",
349
369
  )
@@ -358,20 +378,20 @@ class RestfulRouter:
358
378
 
359
379
  def default(self) -> Self:
360
380
  return (
361
- self.with_create_one_endpoint()
362
- .with_create_many_endpoint()
363
- .with_read_one_endpoint()
364
- .with_read_all_endpoint()
365
- .with_update_one_endpoint()
366
- .with_update_many_endpoint()
367
- .with_delete_one_endpoint()
381
+ self.with_create_one()
382
+ .with_create_many()
383
+ .with_read_one()
384
+ .with_read_all()
385
+ .with_update_one()
386
+ .with_update_many()
387
+ .with_delete_one()
368
388
  )
369
389
 
370
390
  def build(self) -> APIRouter:
371
391
  return self.router
372
392
 
373
393
  def _resolve(self, dependency: Dependency | None) -> type[RestfulService]:
374
- resolved = dependency or self.dependency
394
+ resolved = dependency or self._dependency
375
395
  assert resolved, "One of default or endpoint dependency must be specified"
376
396
 
377
397
  return resolved.as_dependable()
@@ -45,6 +45,7 @@ class SchemaFields(ABC):
45
45
  class RestfulSchema:
46
46
  name: RestfulName
47
47
  fields: SchemaFields
48
+ generator: "Schema"
48
49
 
49
50
  def __post_init__(self) -> None:
50
51
  schema = self._schema_for("", self.fields.readable())
@@ -66,7 +67,7 @@ class RestfulSchema:
66
67
 
67
68
  def _schema_for(self, action: str, fields: dict[str, Any]) -> type[BaseModel]:
68
69
  if action not in self.schemas:
69
- self.schemas[action] = Schema(self.name).schema_for(action, fields)
70
+ self.schemas[action] = self.generator.schema_for(action, fields)
70
71
 
71
72
  return self.schemas[action]
72
73
 
@@ -177,16 +178,16 @@ class RestfulSchema:
177
178
 
178
179
  @dataclass(frozen=True)
179
180
  class Schema:
180
- name: RestfulName
181
+ resource: str
181
182
 
182
183
  def schema_for(self, action: str, fields: dict[str, Any]) -> type[BaseModel]:
183
- return self._nested_schema_for(self.name.singular.capitalize() + action, fields)
184
+ return self._nested_schema_for(self.resource + action, fields)
184
185
 
185
186
  def optional_schema_for(
186
187
  self, action: str, fields: dict[str, Any]
187
188
  ) -> type[BaseModel]:
188
189
  return create_model(
189
- self.name.singular.capitalize() + action,
190
+ self.resource + action,
190
191
  **{
191
192
  field_name: (field_type | None, None)
192
193
  for field_name, field_type in fields.items()
@@ -199,9 +200,7 @@ class Schema:
199
200
  for field_name, field_type in fields.items():
200
201
  if isinstance(field_type, dict):
201
202
  model_fields[field_name] = (
202
- self._nested_schema_for(
203
- name.capitalize() + field_name.capitalize(), field_type
204
- ),
203
+ self._nested_schema_for(name + field_name.capitalize(), field_type),
205
204
  ...,
206
205
  )
207
206
  else:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "apexdevkit"
3
- version = "1.24.4"
3
+ version = "1.25.2"
4
4
  description = "Apex Development Tools for python."
5
5
  readme = "README.md"
6
6
  authors = [
File without changes
File without changes