py2axum 0.1.0__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.
- py2axum/__init__.py +0 -0
- py2axum/__main__.py +81 -0
- py2axum/body.py +1180 -0
- py2axum/codegen.py +493 -0
- py2axum/dyn.py +5370 -0
- py2axum/frontend.py +812 -0
- py2axum/ir.py +180 -0
- py2axum/libmap.py +559 -0
- py2axum/modules.py +249 -0
- py2axum/report.py +234 -0
- py2axum/runtime/Cargo.lock +4421 -0
- py2axum/runtime/dynrt/aio.rs +224 -0
- py2axum/runtime/dynrt/asgi.rs +534 -0
- py2axum/runtime/dynrt/auth.rs +335 -0
- py2axum/runtime/dynrt/decimal.rs +474 -0
- py2axum/runtime/dynrt/dt.rs +484 -0
- py2axum/runtime/dynrt/email.rs +276 -0
- py2axum/runtime/dynrt/fernet.rs +106 -0
- py2axum/runtime/dynrt/files.rs +150 -0
- py2axum/runtime/dynrt/google.rs +206 -0
- py2axum/runtime/dynrt/http.rs +586 -0
- py2axum/runtime/dynrt/ini.rs +141 -0
- py2axum/runtime/dynrt/itsd.rs +207 -0
- py2axum/runtime/dynrt/jose.rs +422 -0
- py2axum/runtime/dynrt/libs.rs +669 -0
- py2axum/runtime/dynrt/mail.rs +537 -0
- py2axum/runtime/dynrt/methods.rs +1941 -0
- py2axum/runtime/dynrt/mod.rs +570 -0
- py2axum/runtime/dynrt/ops.rs +1572 -0
- py2axum/runtime/dynrt/orm.rs +3747 -0
- py2axum/runtime/dynrt/pathio.rs +395 -0
- py2axum/runtime/dynrt/pickle.rs +904 -0
- py2axum/runtime/dynrt/pyd.rs +1706 -0
- py2axum/runtime/dynrt/rds.rs +337 -0
- py2axum/runtime/dynrt/resp.rs +482 -0
- py2axum/runtime/dynrt/rmq.rs +332 -0
- py2axum/runtime/dynrt/stdlib.rs +1526 -0
- py2axum/runtime/dynrt/sysmon.rs +121 -0
- py2axum/runtime/dynrt/tenacity.rs +570 -0
- py2axum/runtime/dynrt/thread.rs +481 -0
- py2axum/runtime/dynrt/types.rs +209 -0
- py2axum/runtime/dynrt/v.rs +790 -0
- py2axum/runtime/dynrt/web.rs +1015 -0
- py2axum/runtime/dynrt/webpush.rs +280 -0
- py2axum/runtime/rt.rs +826 -0
- py2axum-0.1.0.dist-info/METADATA +151 -0
- py2axum-0.1.0.dist-info/RECORD +51 -0
- py2axum-0.1.0.dist-info/WHEEL +4 -0
- py2axum-0.1.0.dist-info/entry_points.txt +2 -0
- py2axum-0.1.0.dist-info/licenses/LICENSE +202 -0
- py2axum-0.1.0.dist-info/licenses/NOTICE +5 -0
py2axum/__init__.py
ADDED
|
File without changes
|
py2axum/__main__.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""py2axum: transpile a FastAPI + SQLAlchemy + Pydantic + aiohttp package to a Rust/axum project.
|
|
2
|
+
|
|
3
|
+
usage: python -m py2axum <python package dir> -o <output dir> [--name crate_name] [--root DIR]
|
|
4
|
+
python -m py2axum <python package dir> --report report.md [--root DIR] (+ report.json)
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from .codegen import TranspileErrors, generate
|
|
13
|
+
from .frontend import Frontend
|
|
14
|
+
from .ir import TranspileError
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main(argv: list[str] | None = None) -> int:
|
|
18
|
+
ap = argparse.ArgumentParser(prog="py2axum", description=__doc__.splitlines()[0])
|
|
19
|
+
ap.add_argument("package", type=Path, help="directory of the FastAPI application package")
|
|
20
|
+
ap.add_argument("-o", "--out", type=Path, help="output directory for the Rust project")
|
|
21
|
+
ap.add_argument("--root", type=Path, default=None,
|
|
22
|
+
help="import root, like sys.path (default: parent of the package)")
|
|
23
|
+
ap.add_argument("--backend", choices=["auto", "typed", "dyn"], default="auto",
|
|
24
|
+
help="typed: static Rust (narrow subset); dyn: dynamic values (real projects); auto: typed, else dyn")
|
|
25
|
+
ap.add_argument("--python-side", action="append", default=[], metavar="PATH|lifespan",
|
|
26
|
+
help="what stays in a Python process next to the binary (raw routes such as /api/v1/mcp, lifespan)")
|
|
27
|
+
ap.add_argument("--report", type=Path, default=None,
|
|
28
|
+
help="coverage report (Markdown + JSON) instead of generating: never stops at the first error")
|
|
29
|
+
ap.add_argument("--name", default=None, help="crate name (default: <package>_axum)")
|
|
30
|
+
ap.add_argument("--no-stream", action="store_true", help="buffer list responses instead of streaming them")
|
|
31
|
+
args = ap.parse_args(argv)
|
|
32
|
+
if args.report:
|
|
33
|
+
from .report import aggregate, build, write
|
|
34
|
+
|
|
35
|
+
result = build(args.package, args.root, stream=not args.no_stream,
|
|
36
|
+
python_side=tuple(args.python_side) or ("lifespan",))
|
|
37
|
+
write(result, args.report)
|
|
38
|
+
agg = aggregate(result["routes"])
|
|
39
|
+
print(f"report {args.report} (+ .json): {agg['traduites']}/{agg['total']} routes translated", file=sys.stderr)
|
|
40
|
+
return 0
|
|
41
|
+
if args.out is None:
|
|
42
|
+
ap.error("-o/--out is required (or --report)")
|
|
43
|
+
|
|
44
|
+
crate = args.name or f"{args.package.resolve().name}_axum"
|
|
45
|
+
typed_error = None
|
|
46
|
+
if args.backend in {"auto", "typed"}:
|
|
47
|
+
try:
|
|
48
|
+
app = Frontend(args.package, args.root).run()
|
|
49
|
+
generate(app, args.out, str(args.package), crate, stream=not args.no_stream)
|
|
50
|
+
print(
|
|
51
|
+
f"generated {args.out}: {len(app.routes)} routes, {len(app.models)} models, {len(app.schemas)} schemas",
|
|
52
|
+
file=sys.stderr,
|
|
53
|
+
)
|
|
54
|
+
return 0
|
|
55
|
+
except (TranspileError, TranspileErrors) as e:
|
|
56
|
+
typed_error = e
|
|
57
|
+
if args.backend == "typed":
|
|
58
|
+
for err in getattr(e, "errors", [e]):
|
|
59
|
+
print(f"error: {err.render()}", file=sys.stderr)
|
|
60
|
+
return 1
|
|
61
|
+
from . import dyn
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
fe = Frontend(args.package, args.root)
|
|
65
|
+
gzip = dyn.prepare(fe, set(args.python_side))
|
|
66
|
+
proj = dyn.generate_project(fe, args.out, str(args.package), crate, gzip=gzip)
|
|
67
|
+
except TranspileError as e:
|
|
68
|
+
print(f"error: {e.render()}", file=sys.stderr)
|
|
69
|
+
return 1
|
|
70
|
+
for n in fe.notes:
|
|
71
|
+
print(f"note: {n}", file=sys.stderr)
|
|
72
|
+
print(
|
|
73
|
+
f"generated {args.out} (dyn backend): {len(proj.fns)} functions, {len(proj.models)} models, "
|
|
74
|
+
f"{len(proj.schemas)} schemas" + (f" — typed backend: {typed_error.render()}" if typed_error and args.backend == "auto" and hasattr(typed_error, "render") else ""),
|
|
75
|
+
file=sys.stderr,
|
|
76
|
+
)
|
|
77
|
+
return 0
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
if __name__ == "__main__":
|
|
81
|
+
sys.exit(main())
|