Skip to content

Commit

Permalink
feat: python sdk generator
Browse files Browse the repository at this point in the history
  • Loading branch information
BigJk committed Feb 10, 2024
1 parent 29ff65b commit a39dce3
Show file tree
Hide file tree
Showing 7 changed files with 989 additions and 0 deletions.
50 changes: 50 additions & 0 deletions cmd/sdk_gen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"flag"
"fmt"
"github.com/BigJk/snd/database/memory"
"github.com/BigJk/snd/server"
"os"
"time"
)

var supportedLanguages = map[string]bool{
"python": true,
}

func main() {
lang := flag.String("lang", "python", "The language to generate the SDK for.")
out := flag.String("out", "snd_api.py", "The output file for the SDK.")
flag.Parse()

if !supportedLanguages[*lang] {
panic(fmt.Sprintf("Unsupported language: %s", *lang))
}

fmt.Println("Starting S&D server to fetch functions...")
server, err := server.New(memory.New())
if err != nil {
panic(err)
}

go func() {
_ = server.Start("127.0.0.1:7123")
}()

time.Sleep(time.Second)
fmt.Println("Shutting down server...")

var source string
switch *lang {
case "python":
source = pythonSDK()
}

fmt.Println("Writing SDK to file...")
if err := os.WriteFile(*out, []byte(source), 0666); err != nil {
panic(err)
}

fmt.Println("Wrote: ", *out)
}
110 changes: 110 additions & 0 deletions cmd/sdk_gen/python.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

import (
"fmt"
"github.com/BigJk/snd/rpc/bind"
"github.com/iancoleman/strcase"
"strings"
)

const pythonAPIHeader = `import requests
# This class is a simple Python SDK for the Sales & Dungeon API.
# It is automatically generated from the API definition.
#
# Requires the requests library to be installed.
# python -m pip install requests
class SndAPI:
def __init__(self, base_url):
"""
Initialize the Sales & Dungeon API class with the base URL of the API.
Parameters:
- base_url (str): The base URL of the API. Most likely "http://127.0.0.1:7123"
"""
self.base_url = base_url
def _make_request(self, endpoint, method='GET', params=None):
url = f"{self.base_url}/{endpoint}"
if method == 'GET':
response = requests.get(url, params=params)
elif method == 'POST':
response = requests.post(url, json=params)
elif method == 'DELETE':
response = requests.delete(url, json=params)
else:
raise ValueError(f"Unsupported HTTP method: {method}")
if response.status_code == 200:
return response.json()
else:
response.raise_for_status()
`

func pythonArgType(argType string) string {
slice := strings.HasSuffix(argType, "[]")
if slice {
argType = argType[:len(argType)-2]
}

typeName := ""
switch argType {
case "string":
typeName = "str"
case "int":
typeName = "int"
case "float":
typeName = "float"
case "bool":
typeName = "bool"
case "interface{}":
typeName = "dict"
default:
typeName = strings.Replace(argType, "snd.", "", -1)
}

if slice {
return fmt.Sprintf("list of %s", typeName)
}
return typeName
}

func pythonDefineFunction(function bind.Function) string {
args := make([]string, len(function.Args))
for i, _ := range function.Args {
args[i] = fmt.Sprintf("arg%d", i)
}

parameters := make([]string, len(function.Args))
for i, arg := range function.Args {
parameters[i] = fmt.Sprintf(" - %s (%s): parameter", args[i], pythonArgType(arg))
}

snakeName := strcase.ToSnake(function.Name)
snakeName = strings.Replace(snakeName, "5_e", "5e", -1)

return fmt.Sprintf(` def %s(self, %s):
"""
Perform an action using the %s API endpoint.
Parameters:
%s
"""
endpoint = "api/%s"
return self._make_request(endpoint, method='POST', params=[%s])`, snakeName, strings.Join(args, ", "), function.Name, strings.Join(parameters, "\n"), function.Name, strings.Join(args, ", "))
}

func pythonSDK() string {
functions := bind.Functions()
functionsStr := make([]string, len(functions))
i := 0
for _, function := range functions {
functionsStr[i] = pythonDefineFunction(function)
i++
}

return fmt.Sprintf("%s\n%s", pythonAPIHeader, strings.Join(functionsStr, "\n\n"))
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ require (
github.com/golang/snappy v0.0.3 // indirect
github.com/google/flatbuffers v1.12.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.12.3 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ github.com/google/gousb v1.1.2/go.mod h1:GGWUkK0gAXDzxhwrzetW592aOmkkqSGcj5KLEgm
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
Expand Down
5 changes: 5 additions & 0 deletions sdk/python/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import snd_sdk

api = snd_sdk.SndAPI("http://127.0.0.1:7123")
response = api.get_templates()
print(response[0]['name'])
Loading

0 comments on commit a39dce3

Please sign in to comment.