def schema_code_from_callable(m: Module, name: str, *, fn: t.Callable[..., t.Any]): spec = fnspec.fnspec(fn) with m.class_(name, "BaseModel"): if spec.doc is not None: m.docstring( f"auto generated class from {spec.__module__}.{spec.name}") if len(spec.parameters) == 0: m.stmt("pass") for name, typ in spec.parameters: kind = spec.kind_of(name) if kind == "args": continue elif kind == "args_defaults": continue elif kind == "kw": m.stmt("{}: {}", name, spec.type_str_of(typ)) elif kind == "kw_defaults": m.stmt("{}: {} = {}", name, spec.type_str_of(typ), spec.default_of(name)) else: raise ValueError(f"invalid kind. name={name}, kind={kind}") return m
def use_gencode(): from codeobject import Module, codeobject @codeobject def ArgumentParser(m: Module, name: str) -> Module: pass m = Module() parser = m.let("parser", ArgumentParser(prog="app.py")) Injector(hello).inject(parser, callback=m.stmt) print(m)
def use_gencode(): from codeobject import Module, codeobject @codeobject def ArgumentParser(m: Module, name: str) -> Module: pass m = Module() parser = m.let("parser", ArgumentParser(prog="app.py")) bind_parser(parser, rec=m.stmt) print(m)
def hello_view(m: Module, name: str) -> Module: m.toplevel.from_("monogusa.web", "runtime") # todo: toplevel? m.stmt('@router.post( "/{}", response_model=runtime.CommandOutput)', hello.__name__) with m.def_(name, f"input: {hello.__name__}", return_type=Hello): if hello.__doc__ is not None: m.docstring(hello.__doc__) with m.with_("runtime.handle() as s"): m.stmt("{}.{}(**input.dict())", "cli", hello.__name__, hello.__name__) m.stmt("return s.dict()") return m
def view_code_from_spec( m: Module, name: str, *, spec: fnspec.FuncSpec, InputSchema: t.Optional[codeobject.Object], ) -> Module: # TODO: DI m.stmt('@router.post("/{}", response_model=runtime.CommandOutput)', spec.name) args = [] if InputSchema is not None: args.append(f"input: {InputSchema}") with m.def_(name, *args, return_type="t.Dict[str, t.Any]"): if spec.doc is not None: m.docstring(spec.doc) with m.with_("runtime.handle() as s"): m.stmt("{}(**input.dict())", spec.fullname) m.stmt("return s.dict()") return m
def hello_with_hello(m: Module, name: str) -> Module: with m.def_(name, return_type=Hello): p = m.let("p", Hello(name="foo", age=20)) m.stmt(p.say("hello")) # type: ignore m.return_(p) return m
with m.def_(name, return_type=Hello): p = m.let("p", Hello(name="foo", age=20)) m.stmt(p.say("hello")) # type: ignore m.return_(p) return m @codeobject.codeobject def hello_view(m: Module, name: str) -> Module: m.toplevel.from_("monogusa.web", "runtime") # todo: toplevel? m.stmt('@router.post( "/{}", response_model=runtime.CommandOutput)', hello.__name__) with m.def_(name, f"input: {hello.__name__}", return_type=Hello): if hello.__doc__ is not None: m.docstring(hello.__doc__) with m.with_("runtime.handle() as s"): m.stmt("{}.{}(**input.dict())", "cli", hello.__name__, hello.__name__) m.stmt("return s.dict()") return m m = Module() m.toplevel = m.submodule() m.sep() m.stmt(Hello) m.stmt(hello_with_hello) m.stmt(hello_view) print(m)
def main(): m = Module(import_unique=True) m.toplevel = m.submodule() m.sep() m.toplevel.import_("typing", as_="t") m.toplevel.from_("pydantic", "BaseModel") m.toplevel.from_("fastapi", "APIRouter", "Depends") m.stmt("router = APIRouter()") m.sep() for fn in [hello, byebye]: spec = fnspec.fnspec(fn) m.toplevel.from_("monogusa.web", "runtime") if fn.__module__ != "__main__": m.toplevel.import_(fn.__module__) InputSchema = None if len(spec.parameters) > 0: InputSchema = codeobject.codeobject(partial(schema_code_from_spec, spec=spec), name=pascalcase(fn.__name__)) m.stmt(InputSchema) view_callable = codeobject.codeobject( partial(view_code_from_spec, spec=spec, InputSchema=InputSchema), name=spec.name, ) m.stmt(view_callable) with m.def_("main", return_type=None): m.from_("monogusa.web", "cli") m.from_("fastapi", "FastAPI") m.stmt("app = FastAPI()") m.stmt("app.include_router(router)") m.stmt("cli.run(app)") print(m)
def use_gencode(): from codeobject import Module m = Module() argparse = m.import_("argparse") with m.def_("create_parser"): parser = m.let("parser", argparse.ArgumentParser(prog="app.py")) subparsers = m.let( "subparsers", parser.add_subparsers(title="subcommands", required=True, dest="subcommand"), ) m.sep() for fn in [hello, byebye]: m.stmt(f"# for {fn.__name__}") sub_parser = m.let( "sub_parser", subparsers.add_parser(fn.__name__, help=UnRepr(f"{fn.__name__}.__doc__")), ) Injector(fn).inject(sub_parser, callback=m.stmt) m.stmt(sub_parser.set_defaults(subcommand=fn)) m.sep() m.return_(parser) print(m)