sera-2 1.1.0__py3-none-any.whl → 1.2.1__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.
- sera/libs/base_orm.py +3 -4
- sera/libs/base_service.py +19 -6
- sera/make/make_app.py +9 -3
- sera/make/make_python_api.py +562 -7
- sera/make/make_python_model.py +480 -94
- sera/models/__init__.py +2 -1
- sera/models/_class.py +2 -0
- sera/models/_datatype.py +49 -11
- sera/models/_module.py +12 -3
- sera/models/_parse.py +20 -19
- sera/models/_property.py +6 -2
- {sera_2-1.1.0.dist-info → sera_2-1.2.1.dist-info}/METADATA +3 -1
- {sera_2-1.1.0.dist-info → sera_2-1.2.1.dist-info}/RECORD +14 -14
- {sera_2-1.1.0.dist-info → sera_2-1.2.1.dist-info}/WHEEL +0 -0
sera/make/make_python_api.py
CHANGED
@@ -4,7 +4,7 @@ from typing import Sequence
|
|
4
4
|
|
5
5
|
from codegen.models import DeferredVar, PredefinedFn, Program, expr, stmt
|
6
6
|
from loguru import logger
|
7
|
-
from sera.misc import to_snake_case
|
7
|
+
from sera.misc import assert_not_null, to_snake_case
|
8
8
|
from sera.models import App, DataCollection, Module, Package
|
9
9
|
|
10
10
|
|
@@ -13,17 +13,25 @@ def make_python_api(app: App, collections: Sequence[DataCollection]):
|
|
13
13
|
app.api.ensure_exists()
|
14
14
|
app.api.pkg("routes").ensure_exists()
|
15
15
|
|
16
|
+
# make routes & depdnencies
|
16
17
|
dep_pkg = app.api.pkg("dependencies")
|
18
|
+
routes: list[Module] = []
|
17
19
|
for collection in collections:
|
18
20
|
make_dependency(collection, dep_pkg)
|
19
21
|
route = app.api.pkg("routes").pkg(collection.get_pymodule_name())
|
20
22
|
|
21
|
-
|
23
|
+
controllers = []
|
24
|
+
controllers.append(make_python_get_api(collection, route))
|
25
|
+
controllers.append(make_python_get_by_id_api(collection, route))
|
26
|
+
controllers.append(make_python_has_api(collection, route))
|
27
|
+
controllers.append(make_python_create_api(collection, route))
|
28
|
+
controllers.append(make_python_update_api(collection, route))
|
22
29
|
|
23
30
|
program = Program()
|
24
31
|
program.import_("__future__.annotations", True)
|
25
32
|
program.import_("litestar.Router", True)
|
26
|
-
|
33
|
+
for get_route, get_route_fn in controllers:
|
34
|
+
program.import_(get_route.path + "." + get_route_fn, True)
|
27
35
|
|
28
36
|
program.root(
|
29
37
|
stmt.LineBreak(),
|
@@ -42,7 +50,8 @@ def make_python_api(app: App, collections: Sequence[DataCollection]):
|
|
42
50
|
"route_handlers",
|
43
51
|
PredefinedFn.list(
|
44
52
|
[
|
45
|
-
expr.ExprIdent(get_route_fn)
|
53
|
+
expr.ExprIdent(get_route_fn)
|
54
|
+
for get_route, get_route_fn in controllers
|
46
55
|
]
|
47
56
|
),
|
48
57
|
),
|
@@ -52,6 +61,43 @@ def make_python_api(app: App, collections: Sequence[DataCollection]):
|
|
52
61
|
)
|
53
62
|
|
54
63
|
route.module("route").write(program)
|
64
|
+
routes.append(route.module("route"))
|
65
|
+
|
66
|
+
# make the main entry point
|
67
|
+
make_main(app.api, routes)
|
68
|
+
|
69
|
+
|
70
|
+
def make_main(target_pkg: Package, routes: Sequence[Module]):
|
71
|
+
outmod = target_pkg.module("app")
|
72
|
+
if outmod.exists():
|
73
|
+
logger.info("`{}` already exists. Skip generation.", outmod.path)
|
74
|
+
return
|
75
|
+
|
76
|
+
program = Program()
|
77
|
+
program.import_("__future__.annotations", True)
|
78
|
+
program.import_("litestar.Litestar", True)
|
79
|
+
for route in routes:
|
80
|
+
program.import_(route.path, False)
|
81
|
+
|
82
|
+
program.root(
|
83
|
+
stmt.LineBreak(),
|
84
|
+
lambda ast: ast.assign(
|
85
|
+
DeferredVar.simple("app"),
|
86
|
+
expr.ExprFuncCall(
|
87
|
+
expr.ExprIdent("Litestar"),
|
88
|
+
[
|
89
|
+
PredefinedFn.keyword_assignment(
|
90
|
+
"route_handlers",
|
91
|
+
PredefinedFn.list(
|
92
|
+
[expr.ExprIdent(route.path + ".router") for route in routes]
|
93
|
+
),
|
94
|
+
)
|
95
|
+
],
|
96
|
+
),
|
97
|
+
),
|
98
|
+
)
|
99
|
+
|
100
|
+
outmod.write(program)
|
55
101
|
|
56
102
|
|
57
103
|
def make_dependency(collection: DataCollection, target_pkg: Package):
|
@@ -76,7 +122,10 @@ def make_dependency(collection: DataCollection, target_pkg: Package):
|
|
76
122
|
program.root(
|
77
123
|
stmt.LineBreak(),
|
78
124
|
lambda ast: ast.func(
|
79
|
-
ServiceNameDep,
|
125
|
+
ServiceNameDep,
|
126
|
+
[],
|
127
|
+
expr.ExprIdent(collection.get_service_name()),
|
128
|
+
is_async=True,
|
80
129
|
)(
|
81
130
|
lambda ast01: ast01.return_(
|
82
131
|
expr.ExprFuncCall(expr.ExprIdent(collection.get_service_name()), [])
|
@@ -97,10 +146,13 @@ def make_python_get_api(
|
|
97
146
|
program = Program()
|
98
147
|
program.import_("__future__.annotations", True)
|
99
148
|
program.import_("typing.Annotated", True)
|
149
|
+
program.import_("typing.Sequence", True)
|
100
150
|
program.import_("litestar.get", True)
|
101
151
|
program.import_("litestar.Request", True)
|
102
152
|
program.import_("litestar.params.Parameter", True)
|
153
|
+
program.import_(app.models.db.path + ".base.get_session", True)
|
103
154
|
program.import_("litestar.di.Provide", True)
|
155
|
+
program.import_("sqlalchemy.orm.Session", True)
|
104
156
|
program.import_(app.config.path + ".ROUTER_DEBUG", True)
|
105
157
|
program.import_(
|
106
158
|
f"{app.api.path}.dependencies.{collection.get_pymodule_name()}.{ServiceNameDep}",
|
@@ -111,6 +163,10 @@ def make_python_get_api(
|
|
111
163
|
+ f".{collection.get_pymodule_name()}.{collection.get_service_name()}",
|
112
164
|
True,
|
113
165
|
)
|
166
|
+
program.import_(
|
167
|
+
app.models.data.path + f".{collection.get_pymodule_name()}.{collection.name}",
|
168
|
+
True,
|
169
|
+
)
|
114
170
|
program.import_("sera.libs.api_helper.parse_query", True)
|
115
171
|
|
116
172
|
func_name = "get_"
|
@@ -133,7 +189,11 @@ def make_python_get_api(
|
|
133
189
|
(
|
134
190
|
expr.ExprConstant("service"),
|
135
191
|
expr.ExprIdent(f"Provide({ServiceNameDep})"),
|
136
|
-
)
|
192
|
+
),
|
193
|
+
(
|
194
|
+
expr.ExprConstant("session"),
|
195
|
+
expr.ExprIdent(f"Provide(get_session)"),
|
196
|
+
),
|
137
197
|
]
|
138
198
|
),
|
139
199
|
),
|
@@ -187,7 +247,12 @@ def make_python_get_api(
|
|
187
247
|
"service",
|
188
248
|
expr.ExprIdent(collection.get_service_name()),
|
189
249
|
),
|
250
|
+
DeferredVar.simple(
|
251
|
+
"session",
|
252
|
+
expr.ExprIdent("Session"),
|
253
|
+
),
|
190
254
|
],
|
255
|
+
return_type=expr.ExprIdent(f"Sequence[{collection.name}]"),
|
191
256
|
is_async=True,
|
192
257
|
)(
|
193
258
|
stmt.SingleExprStatement(
|
@@ -207,7 +272,8 @@ def make_python_get_api(
|
|
207
272
|
],
|
208
273
|
),
|
209
274
|
),
|
210
|
-
lambda ast12: ast12.
|
275
|
+
lambda ast12: ast12.assign(
|
276
|
+
DeferredVar.simple("result"),
|
211
277
|
expr.ExprFuncCall(
|
212
278
|
expr.ExprIdent("service.get"),
|
213
279
|
[
|
@@ -230,7 +296,21 @@ def make_python_get_api(
|
|
230
296
|
PredefinedFn.keyword_assignment(
|
231
297
|
"fields", expr.ExprIdent("fields")
|
232
298
|
),
|
299
|
+
PredefinedFn.keyword_assignment(
|
300
|
+
"session", expr.ExprIdent("session")
|
301
|
+
),
|
233
302
|
],
|
303
|
+
),
|
304
|
+
),
|
305
|
+
lambda ast13: ast13.return_(
|
306
|
+
PredefinedFn.map_list(
|
307
|
+
expr.ExprIdent("result"),
|
308
|
+
lambda item: expr.ExprFuncCall(
|
309
|
+
PredefinedFn.attr_getter(
|
310
|
+
expr.ExprIdent(collection.name), expr.ExprIdent("from_db")
|
311
|
+
),
|
312
|
+
[item],
|
313
|
+
),
|
234
314
|
)
|
235
315
|
),
|
236
316
|
),
|
@@ -240,3 +320,478 @@ def make_python_get_api(
|
|
240
320
|
outmod.write(program)
|
241
321
|
|
242
322
|
return outmod, func_name
|
323
|
+
|
324
|
+
|
325
|
+
def make_python_get_by_id_api(
|
326
|
+
collection: DataCollection, target_pkg: Package
|
327
|
+
) -> tuple[Module, str]:
|
328
|
+
"""Make an endpoint for querying resource by id"""
|
329
|
+
app = target_pkg.app
|
330
|
+
|
331
|
+
ServiceNameDep = to_snake_case(f"{collection.name}ServiceDependency")
|
332
|
+
|
333
|
+
program = Program()
|
334
|
+
program.import_("__future__.annotations", True)
|
335
|
+
program.import_("litestar.get", True)
|
336
|
+
program.import_("litestar.status_codes", True)
|
337
|
+
program.import_("litestar.exceptions.HTTPException", True)
|
338
|
+
program.import_("litestar.di.Provide", True)
|
339
|
+
program.import_("sqlalchemy.orm.Session", True)
|
340
|
+
program.import_(app.models.db.path + ".base.get_session", True)
|
341
|
+
program.import_(
|
342
|
+
f"{app.api.path}.dependencies.{collection.get_pymodule_name()}.{ServiceNameDep}",
|
343
|
+
True,
|
344
|
+
)
|
345
|
+
program.import_(
|
346
|
+
app.services.path
|
347
|
+
+ f".{collection.get_pymodule_name()}.{collection.get_service_name()}",
|
348
|
+
True,
|
349
|
+
)
|
350
|
+
program.import_(
|
351
|
+
app.models.data.path + f".{collection.get_pymodule_name()}.{collection.name}",
|
352
|
+
True,
|
353
|
+
)
|
354
|
+
|
355
|
+
# assuming the collection has only one class
|
356
|
+
cls = collection.cls
|
357
|
+
id_type = assert_not_null(cls.get_id_property()).datatype.get_python_type().type
|
358
|
+
|
359
|
+
func_name = "get_by_id"
|
360
|
+
program.root(
|
361
|
+
stmt.LineBreak(),
|
362
|
+
stmt.PythonDecoratorStatement(
|
363
|
+
expr.ExprFuncCall(
|
364
|
+
expr.ExprIdent("get"),
|
365
|
+
[
|
366
|
+
expr.ExprConstant("/{id:%s}" % id_type),
|
367
|
+
PredefinedFn.keyword_assignment(
|
368
|
+
"dependencies",
|
369
|
+
PredefinedFn.dict(
|
370
|
+
[
|
371
|
+
(
|
372
|
+
expr.ExprConstant("service"),
|
373
|
+
expr.ExprIdent(f"Provide({ServiceNameDep})"),
|
374
|
+
),
|
375
|
+
(
|
376
|
+
expr.ExprConstant("session"),
|
377
|
+
expr.ExprIdent(f"Provide(get_session)"),
|
378
|
+
),
|
379
|
+
]
|
380
|
+
),
|
381
|
+
),
|
382
|
+
],
|
383
|
+
)
|
384
|
+
),
|
385
|
+
lambda ast10: ast10.func(
|
386
|
+
func_name,
|
387
|
+
[
|
388
|
+
DeferredVar.simple(
|
389
|
+
"id",
|
390
|
+
expr.ExprIdent(id_type),
|
391
|
+
),
|
392
|
+
DeferredVar.simple(
|
393
|
+
"service",
|
394
|
+
expr.ExprIdent(collection.get_service_name()),
|
395
|
+
),
|
396
|
+
DeferredVar.simple(
|
397
|
+
"session",
|
398
|
+
expr.ExprIdent("Session"),
|
399
|
+
),
|
400
|
+
],
|
401
|
+
return_type=expr.ExprIdent(f"{cls.name}"),
|
402
|
+
is_async=True,
|
403
|
+
)(
|
404
|
+
stmt.SingleExprStatement(expr.ExprConstant("Retrieving record by id")),
|
405
|
+
lambda ast11: ast11.assign(
|
406
|
+
DeferredVar.simple("record"),
|
407
|
+
expr.ExprFuncCall(
|
408
|
+
expr.ExprIdent("service.get_by_id"),
|
409
|
+
[
|
410
|
+
expr.ExprIdent("id"),
|
411
|
+
expr.ExprIdent("session"),
|
412
|
+
],
|
413
|
+
),
|
414
|
+
),
|
415
|
+
lambda ast12: ast12.if_(PredefinedFn.is_null(expr.ExprIdent("record")))(
|
416
|
+
lambda ast23: ast23.raise_exception(
|
417
|
+
expr.StandardExceptionExpr(
|
418
|
+
expr.ExprIdent("HTTPException"),
|
419
|
+
[
|
420
|
+
PredefinedFn.keyword_assignment(
|
421
|
+
"status_code",
|
422
|
+
expr.ExprIdent("status_codes.HTTP_404_NOT_FOUND"),
|
423
|
+
),
|
424
|
+
PredefinedFn.keyword_assignment(
|
425
|
+
"detail",
|
426
|
+
expr.ExprIdent('f"Record with id {id} not found"'),
|
427
|
+
),
|
428
|
+
],
|
429
|
+
)
|
430
|
+
)
|
431
|
+
),
|
432
|
+
lambda ast13: ast13.return_(
|
433
|
+
expr.ExprFuncCall(
|
434
|
+
PredefinedFn.attr_getter(
|
435
|
+
expr.ExprIdent(cls.name), expr.ExprIdent("from_db")
|
436
|
+
),
|
437
|
+
[expr.ExprIdent("record")],
|
438
|
+
)
|
439
|
+
),
|
440
|
+
),
|
441
|
+
)
|
442
|
+
|
443
|
+
outmod = target_pkg.module("get_by_id")
|
444
|
+
outmod.write(program)
|
445
|
+
|
446
|
+
return outmod, func_name
|
447
|
+
|
448
|
+
|
449
|
+
def make_python_has_api(
|
450
|
+
collection: DataCollection, target_pkg: Package
|
451
|
+
) -> tuple[Module, str]:
|
452
|
+
"""Make an endpoint for querying resource by id"""
|
453
|
+
app = target_pkg.app
|
454
|
+
|
455
|
+
ServiceNameDep = to_snake_case(f"{collection.name}ServiceDependency")
|
456
|
+
|
457
|
+
program = Program()
|
458
|
+
program.import_("__future__.annotations", True)
|
459
|
+
program.import_("litestar.head", True)
|
460
|
+
program.import_("litestar.status_codes", True)
|
461
|
+
program.import_("litestar.exceptions.HTTPException", True)
|
462
|
+
program.import_("litestar.di.Provide", True)
|
463
|
+
program.import_("sqlalchemy.orm.Session", True)
|
464
|
+
program.import_(app.models.db.path + ".base.get_session", True)
|
465
|
+
program.import_(
|
466
|
+
f"{app.api.path}.dependencies.{collection.get_pymodule_name()}.{ServiceNameDep}",
|
467
|
+
True,
|
468
|
+
)
|
469
|
+
program.import_(
|
470
|
+
app.services.path
|
471
|
+
+ f".{collection.get_pymodule_name()}.{collection.get_service_name()}",
|
472
|
+
True,
|
473
|
+
)
|
474
|
+
program.import_(
|
475
|
+
app.models.data.path + f".{collection.get_pymodule_name()}.{collection.name}",
|
476
|
+
True,
|
477
|
+
)
|
478
|
+
|
479
|
+
# assuming the collection has only one class
|
480
|
+
cls = collection.cls
|
481
|
+
id_type = assert_not_null(cls.get_id_property()).datatype.get_python_type().type
|
482
|
+
|
483
|
+
func_name = "has"
|
484
|
+
program.root(
|
485
|
+
stmt.LineBreak(),
|
486
|
+
stmt.PythonDecoratorStatement(
|
487
|
+
expr.ExprFuncCall(
|
488
|
+
expr.ExprIdent("head"),
|
489
|
+
[
|
490
|
+
expr.ExprConstant("/{id:%s}" % id_type),
|
491
|
+
PredefinedFn.keyword_assignment(
|
492
|
+
"status_code",
|
493
|
+
expr.ExprIdent("status_codes.HTTP_204_NO_CONTENT"),
|
494
|
+
),
|
495
|
+
PredefinedFn.keyword_assignment(
|
496
|
+
"dependencies",
|
497
|
+
PredefinedFn.dict(
|
498
|
+
[
|
499
|
+
(
|
500
|
+
expr.ExprConstant("service"),
|
501
|
+
expr.ExprIdent(f"Provide({ServiceNameDep})"),
|
502
|
+
),
|
503
|
+
(
|
504
|
+
expr.ExprConstant("session"),
|
505
|
+
expr.ExprIdent(f"Provide(get_session)"),
|
506
|
+
),
|
507
|
+
]
|
508
|
+
),
|
509
|
+
),
|
510
|
+
],
|
511
|
+
)
|
512
|
+
),
|
513
|
+
lambda ast10: ast10.func(
|
514
|
+
func_name,
|
515
|
+
[
|
516
|
+
DeferredVar.simple(
|
517
|
+
"id",
|
518
|
+
expr.ExprIdent(id_type),
|
519
|
+
),
|
520
|
+
DeferredVar.simple(
|
521
|
+
"service",
|
522
|
+
expr.ExprIdent(collection.get_service_name()),
|
523
|
+
),
|
524
|
+
DeferredVar.simple(
|
525
|
+
"session",
|
526
|
+
expr.ExprIdent("Session"),
|
527
|
+
),
|
528
|
+
],
|
529
|
+
return_type=expr.ExprConstant(None),
|
530
|
+
is_async=True,
|
531
|
+
)(
|
532
|
+
stmt.SingleExprStatement(expr.ExprConstant("Retrieving record by id")),
|
533
|
+
lambda ast11: ast11.assign(
|
534
|
+
DeferredVar.simple("record_exist"),
|
535
|
+
expr.ExprFuncCall(
|
536
|
+
expr.ExprIdent("service.has_id"),
|
537
|
+
[
|
538
|
+
expr.ExprIdent("id"),
|
539
|
+
expr.ExprIdent("session"),
|
540
|
+
],
|
541
|
+
),
|
542
|
+
),
|
543
|
+
lambda ast12: ast12.if_(expr.ExprNegation(expr.ExprIdent("record_exist")))(
|
544
|
+
lambda ast23: ast23.raise_exception(
|
545
|
+
expr.StandardExceptionExpr(
|
546
|
+
expr.ExprIdent("HTTPException"),
|
547
|
+
[
|
548
|
+
PredefinedFn.keyword_assignment(
|
549
|
+
"status_code",
|
550
|
+
expr.ExprIdent("status_codes.HTTP_404_NOT_FOUND"),
|
551
|
+
),
|
552
|
+
PredefinedFn.keyword_assignment(
|
553
|
+
"detail",
|
554
|
+
expr.ExprIdent('f"Record with id {id} not found"'),
|
555
|
+
),
|
556
|
+
],
|
557
|
+
)
|
558
|
+
)
|
559
|
+
),
|
560
|
+
lambda ast13: ast13.return_(expr.ExprConstant(None)),
|
561
|
+
),
|
562
|
+
)
|
563
|
+
|
564
|
+
outmod = target_pkg.module("has")
|
565
|
+
outmod.write(program)
|
566
|
+
|
567
|
+
return outmod, func_name
|
568
|
+
|
569
|
+
|
570
|
+
def make_python_create_api(collection: DataCollection, target_pkg: Package):
|
571
|
+
"""Make an endpoint for creating a resource"""
|
572
|
+
app = target_pkg.app
|
573
|
+
|
574
|
+
ServiceNameDep = to_snake_case(f"{collection.name}ServiceDependency")
|
575
|
+
|
576
|
+
program = Program()
|
577
|
+
program.import_("__future__.annotations", True)
|
578
|
+
program.import_("litestar.post", True)
|
579
|
+
program.import_("litestar.di.Provide", True)
|
580
|
+
program.import_("sqlalchemy.orm.Session", True)
|
581
|
+
program.import_(app.models.db.path + ".base.get_session", True)
|
582
|
+
program.import_(
|
583
|
+
f"{app.api.path}.dependencies.{collection.get_pymodule_name()}.{ServiceNameDep}",
|
584
|
+
True,
|
585
|
+
)
|
586
|
+
program.import_(
|
587
|
+
app.services.path
|
588
|
+
+ f".{collection.get_pymodule_name()}.{collection.get_service_name()}",
|
589
|
+
True,
|
590
|
+
)
|
591
|
+
program.import_(
|
592
|
+
app.models.data.path + f".{collection.get_pymodule_name()}.{collection.name}",
|
593
|
+
True,
|
594
|
+
)
|
595
|
+
program.import_(
|
596
|
+
app.models.data.path
|
597
|
+
+ f".{collection.get_pymodule_name()}.Upsert{collection.name}",
|
598
|
+
True,
|
599
|
+
)
|
600
|
+
|
601
|
+
# assuming the collection has only one class
|
602
|
+
cls = collection.cls
|
603
|
+
id_type = assert_not_null(cls.get_id_property()).datatype.get_python_type().type
|
604
|
+
|
605
|
+
func_name = "create"
|
606
|
+
|
607
|
+
program.root(
|
608
|
+
stmt.LineBreak(),
|
609
|
+
stmt.PythonDecoratorStatement(
|
610
|
+
expr.ExprFuncCall(
|
611
|
+
expr.ExprIdent("post"),
|
612
|
+
[
|
613
|
+
expr.ExprConstant("/"),
|
614
|
+
PredefinedFn.keyword_assignment(
|
615
|
+
"dependencies",
|
616
|
+
PredefinedFn.dict(
|
617
|
+
[
|
618
|
+
(
|
619
|
+
expr.ExprConstant("service"),
|
620
|
+
expr.ExprIdent(f"Provide({ServiceNameDep})"),
|
621
|
+
),
|
622
|
+
(
|
623
|
+
expr.ExprConstant("session"),
|
624
|
+
expr.ExprIdent(f"Provide(get_session)"),
|
625
|
+
),
|
626
|
+
]
|
627
|
+
),
|
628
|
+
),
|
629
|
+
],
|
630
|
+
)
|
631
|
+
),
|
632
|
+
lambda ast10: ast10.func(
|
633
|
+
func_name,
|
634
|
+
[
|
635
|
+
DeferredVar.simple(
|
636
|
+
"record",
|
637
|
+
expr.ExprIdent(f"Upsert{cls.name}"),
|
638
|
+
),
|
639
|
+
DeferredVar.simple(
|
640
|
+
"service",
|
641
|
+
expr.ExprIdent(collection.get_service_name()),
|
642
|
+
),
|
643
|
+
DeferredVar.simple(
|
644
|
+
"session",
|
645
|
+
expr.ExprIdent("Session"),
|
646
|
+
),
|
647
|
+
],
|
648
|
+
return_type=expr.ExprIdent(cls.name),
|
649
|
+
is_async=True,
|
650
|
+
)(
|
651
|
+
stmt.SingleExprStatement(expr.ExprConstant("Creating new record")),
|
652
|
+
lambda ast13: ast13.return_(
|
653
|
+
expr.ExprMethodCall(
|
654
|
+
expr.ExprIdent(cls.name),
|
655
|
+
"from_db",
|
656
|
+
[
|
657
|
+
expr.ExprMethodCall(
|
658
|
+
expr.ExprIdent("service"),
|
659
|
+
"create",
|
660
|
+
[
|
661
|
+
expr.ExprMethodCall(
|
662
|
+
expr.ExprIdent("record"), "to_db", []
|
663
|
+
),
|
664
|
+
expr.ExprIdent("session"),
|
665
|
+
],
|
666
|
+
)
|
667
|
+
],
|
668
|
+
)
|
669
|
+
),
|
670
|
+
),
|
671
|
+
)
|
672
|
+
|
673
|
+
outmod = target_pkg.module("create")
|
674
|
+
outmod.write(program)
|
675
|
+
|
676
|
+
return outmod, func_name
|
677
|
+
|
678
|
+
|
679
|
+
def make_python_update_api(collection: DataCollection, target_pkg: Package):
|
680
|
+
"""Make an endpoint for updating resource"""
|
681
|
+
app = target_pkg.app
|
682
|
+
|
683
|
+
ServiceNameDep = to_snake_case(f"{collection.name}ServiceDependency")
|
684
|
+
|
685
|
+
program = Program()
|
686
|
+
program.import_("__future__.annotations", True)
|
687
|
+
program.import_("litestar.put", True)
|
688
|
+
program.import_("litestar.di.Provide", True)
|
689
|
+
program.import_("sqlalchemy.orm.Session", True)
|
690
|
+
program.import_(app.models.db.path + ".base.get_session", True)
|
691
|
+
program.import_(
|
692
|
+
f"{app.api.path}.dependencies.{collection.get_pymodule_name()}.{ServiceNameDep}",
|
693
|
+
True,
|
694
|
+
)
|
695
|
+
program.import_(
|
696
|
+
app.services.path
|
697
|
+
+ f".{collection.get_pymodule_name()}.{collection.get_service_name()}",
|
698
|
+
True,
|
699
|
+
)
|
700
|
+
program.import_(
|
701
|
+
app.models.data.path + f".{collection.get_pymodule_name()}.{collection.name}",
|
702
|
+
True,
|
703
|
+
)
|
704
|
+
program.import_(
|
705
|
+
app.models.data.path
|
706
|
+
+ f".{collection.get_pymodule_name()}.Upsert{collection.name}",
|
707
|
+
True,
|
708
|
+
)
|
709
|
+
|
710
|
+
# assuming the collection has only one class
|
711
|
+
cls = collection.cls
|
712
|
+
id_prop = assert_not_null(cls.get_id_property())
|
713
|
+
id_type = id_prop.datatype.get_python_type().type
|
714
|
+
|
715
|
+
func_name = "update"
|
716
|
+
|
717
|
+
program.root(
|
718
|
+
stmt.LineBreak(),
|
719
|
+
stmt.PythonDecoratorStatement(
|
720
|
+
expr.ExprFuncCall(
|
721
|
+
expr.ExprIdent("put"),
|
722
|
+
[
|
723
|
+
expr.ExprConstant("/{id:%s}" % id_type),
|
724
|
+
PredefinedFn.keyword_assignment(
|
725
|
+
"dependencies",
|
726
|
+
PredefinedFn.dict(
|
727
|
+
[
|
728
|
+
(
|
729
|
+
expr.ExprConstant("service"),
|
730
|
+
expr.ExprIdent(f"Provide({ServiceNameDep})"),
|
731
|
+
),
|
732
|
+
(
|
733
|
+
expr.ExprConstant("session"),
|
734
|
+
expr.ExprIdent(f"Provide(get_session)"),
|
735
|
+
),
|
736
|
+
]
|
737
|
+
),
|
738
|
+
),
|
739
|
+
],
|
740
|
+
)
|
741
|
+
),
|
742
|
+
lambda ast10: ast10.func(
|
743
|
+
func_name,
|
744
|
+
[
|
745
|
+
DeferredVar.simple(
|
746
|
+
"id",
|
747
|
+
expr.ExprIdent(id_type),
|
748
|
+
),
|
749
|
+
DeferredVar.simple(
|
750
|
+
"record",
|
751
|
+
expr.ExprIdent(f"Upsert{cls.name}"),
|
752
|
+
),
|
753
|
+
DeferredVar.simple(
|
754
|
+
"service",
|
755
|
+
expr.ExprIdent(collection.get_service_name()),
|
756
|
+
),
|
757
|
+
DeferredVar.simple(
|
758
|
+
"session",
|
759
|
+
expr.ExprIdent("Session"),
|
760
|
+
),
|
761
|
+
],
|
762
|
+
return_type=expr.ExprIdent(cls.name),
|
763
|
+
is_async=True,
|
764
|
+
)(
|
765
|
+
stmt.SingleExprStatement(expr.ExprConstant("Update an existing record")),
|
766
|
+
stmt.SingleExprStatement(
|
767
|
+
PredefinedFn.attr_setter(
|
768
|
+
expr.ExprIdent("record"),
|
769
|
+
expr.ExprIdent(id_prop.name),
|
770
|
+
expr.ExprIdent("id"),
|
771
|
+
)
|
772
|
+
),
|
773
|
+
lambda ast13: ast13.return_(
|
774
|
+
expr.ExprMethodCall(
|
775
|
+
expr.ExprIdent(cls.name),
|
776
|
+
"from_db",
|
777
|
+
[
|
778
|
+
expr.ExprMethodCall(
|
779
|
+
expr.ExprIdent("service"),
|
780
|
+
"update",
|
781
|
+
[
|
782
|
+
expr.ExprMethodCall(
|
783
|
+
expr.ExprIdent("record"), "to_db", []
|
784
|
+
),
|
785
|
+
expr.ExprIdent("session"),
|
786
|
+
],
|
787
|
+
)
|
788
|
+
],
|
789
|
+
)
|
790
|
+
),
|
791
|
+
),
|
792
|
+
)
|
793
|
+
|
794
|
+
outmod = target_pkg.module("update")
|
795
|
+
outmod.write(program)
|
796
|
+
|
797
|
+
return outmod, func_name
|