From 0943472bc4f766860e5e4cde0ef1f005a9ad13dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Sima=CC=83o?= Date: Sat, 20 Feb 2021 04:58:09 -0300 Subject: [PATCH] added python cli gen --- src/loader.go | 5 ++ src/main.go | 10 +++ src/processPyClientOutput.go | 150 +++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 src/processPyClientOutput.go diff --git a/src/loader.go b/src/loader.go index bfe55d1..637cc06 100644 --- a/src/loader.go +++ b/src/loader.go @@ -197,6 +197,11 @@ func addFunction(a *ast.FuncDecl) { ResType: resType, Raw: md["RAW"] == "true", } + + if fn.Path == "" { + fn.Path = "/" + strings.ToLower(a.Name.Name) + } + api.Methods[a.Name.Name] = &fn } diff --git a/src/main.go b/src/main.go index 1225445..135ecfc 100644 --- a/src/main.go +++ b/src/main.go @@ -22,6 +22,10 @@ var CLI struct { Src string `arg help:"Source Dir"` Dst string `arg help:"Dst file"` } `cmd help:"Gens Go Cli impl"` + Pycli struct { + Src string `arg help:"Source Dir"` + Dst string `arg help:"Dst file"` + } `cmd help:"Gens Python Cli impl"` Ts struct { Src string `arg help:"Source Dir"` Dst string `arg help:"Dst file"` @@ -64,6 +68,12 @@ func main() { processor = func() error { return processGoClientOutput(CLI.Gocli.Dst) } + case "pycli ": + log.Printf("Gen Python Client") + src = CLI.Pycli.Src + processor = func() error { + return processPyClientOutput(CLI.Pycli.Dst) + } case "ts ": log.Printf("Gen TS Client") src = CLI.Ts.Src diff --git a/src/processPyClientOutput.go b/src/processPyClientOutput.go new file mode 100644 index 0000000..b5d654d --- /dev/null +++ b/src/processPyClientOutput.go @@ -0,0 +1,150 @@ +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "strings" +) + +func processPyClientOutput(f string) error { + + var tstypemapper map[string]string = make(map[string]string) + var exceptionaltypemapper map[string]string = make(map[string]string) + exceptionaltypemapper["[]byte"] = "str" + exceptionaltypemapper["[]string"] = "List[str]" + + tstypemapper["string"] = "str" + tstypemapper["time.Time"] = "int" + tstypemapper["primitive.ObjectID"] = "str" + tstypemapper["time.Duration"] = "int" + tstypemapper["int"] = "int" + tstypemapper["int32"] = "int" + tstypemapper["int64"] = "int" + tstypemapper["float"] = "float" + tstypemapper["float64"] = "float" + tstypemapper["uint8"] = "int" + tstypemapper["uint16"] = "int" + tstypemapper["uint32"] = "int" + tstypemapper["error"] = "Exception" + tstypemapper["bool"] = "bool" + tstypemapper["interface{}"] = "dict" + tstypemapper["bson.M"] = "dict" + + _typeName := func(m *APIParamType) string { + if m.IsArray { + return "List[" + m.Typename + "]" + } + return m.Typename + } + + b := bytes.Buffer{} + + b.WriteString("from dataclasses import dataclass\n") + b.WriteString("import requests\n") + b.WriteString("import json\n") + b.WriteString("from typing import List\n") + + b.WriteString("#region Base\n") + b.WriteString(fmt.Sprintf(` + +__ctx = {"apibase":"%s"} + + +def SetAPIBase(s: str): + __ctx["apibase"] = s + + +def GetAPIBase() -> str: + return __ctx["apibase"] + + +def SetCookie(s: str): + __ctx["cookie"] = s + + +def GetCookie() -> str: + return __ctx["cookie"] + + +def InvokeTxt(path: str, method: str, body) -> str: + headers = {"Content-type": "application/json", "Cookie": "dc="+GetCookie()} + fpath = GetAPIBase() + path + r = requests.request(method, fpath, json=body, headers=headers) + return r.text + + +def InvokeJSON(path: str, method: str, body) -> dict: + return json.loads(InvokeTxt(path, method, body)) + +`, api.BasePath)) + b.WriteString("#endregion\n\n") + b.WriteString("#region Types\n") + for k, v := range api.Types { + if v.Desc != "" { + //b.WriteString(fmt.Sprintf("/**\n%s*/\n", v.Desc)) + } + if len(v.Fields) < 1 { + b.WriteString(fmt.Sprintf("@ dataclass\nclass %s :\n\tpass\n\n", k)) + } else { + b.WriteString(fmt.Sprintf("@ dataclass\nclass %s :\n", k)) + var ftype string + var ok bool + for kf, f := range v.Fields { + ftype, ok = exceptionaltypemapper[f.String()] + if ok { + log.Printf("Mapped exceptional type: %s ==> %s", f.String(), ftype) + } + + if !ok { + if f.Array { + ftype, ok = tstypemapper["[]"+f.Type] + } else { + ftype, ok = tstypemapper[f.Type] + } + } + + if !ok { + ftype = f.Type + } + if f.Map { + //fm, ok := tstypemapper[f.Mapkey] + //if !ok { + // fm = f.Mapkey + //} + //fv, ok := tstypemapper[f.Mapval] + //if !ok { + // fv = f.Mapval + //} + //ftype = "{[s:" + fm + "]:" + fv + "}" + ftype = "dict" + } + + if f.Desc != "" { + //b.WriteString(fmt.Sprintf("\t/**\n%s*/\n", f.Desc)) + } + b.WriteString(fmt.Sprintf("\t%s: %s\n", strings.ToLower(kf), ftype)) + } + + b.WriteString(fmt.Sprintf("\n\n")) + } + } + b.WriteString("#endregion\n\n") + b.WriteString("#region Methods\n") + for k, m := range api.Methods { + if m.Desc != "" { + //b.WriteString(fmt.Sprintf("/**\n%s*/\n", m.Desc)) + } + + b.WriteString(fmt.Sprintf("def %s(req:%s)-> %s:\n", k, _typeName(m.ReqType), _typeName(m.ResType))) + b.WriteString(fmt.Sprintf("\treturn InvokeJSON(\"%s\",\"%s\",req)\n", m.Path, m.Verb)) + b.WriteString(fmt.Sprintf("\n\n")) + //} + + } + b.WriteString("#endregion\n") + + err := ioutil.WriteFile(f, b.Bytes(), 0600) + return err +}