polyapi-python 0.0.22__tar.gz → 0.0.24__tar.gz
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.
- {polyapi-python-0.0.22/polyapi_python.egg-info → polyapi-python-0.0.24}/PKG-INFO +1 -1
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/api.py +26 -21
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/cli.py +5 -2
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/generate.py +35 -9
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/schema.py +8 -1
- {polyapi-python-0.0.22 → polyapi-python-0.0.24/polyapi_python.egg-info}/PKG-INFO +1 -1
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/pyproject.toml +11 -1
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/LICENSE +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/README.md +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/__init__.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/__main__.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/config.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/constants.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/exceptions.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/function_cli.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/py.typed +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/typedefs.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/utils.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi/variables.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi_python.egg-info/SOURCES.txt +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi_python.egg-info/dependency_links.txt +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi_python.egg-info/requires.txt +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi_python.egg-info/top_level.txt +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/setup.cfg +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/tests/test_function_cli.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/tests/test_generate.py +0 -0
- {polyapi-python-0.0.22 → polyapi-python-0.0.24}/tests/test_utils.py +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import Any, Dict, List, Tuple
|
|
3
|
+
|
|
3
4
|
from polyapi.constants import JSONSCHEMA_TO_PYTHON_TYPE_MAP
|
|
4
5
|
from polyapi.typedefs import PropertySpecification, PropertyType
|
|
5
6
|
from polyapi.utils import append_init, camelCase
|
|
6
|
-
from polyapi.schema import generate_schema_types
|
|
7
|
+
from polyapi.schema import generate_schema_types, clean_title
|
|
7
8
|
|
|
8
9
|
# map the function type from the spec type to the function execute type
|
|
9
10
|
TEMPLATE_FUNCTION_TYPE_MAP = {
|
|
@@ -25,7 +26,8 @@ def {function_name}({args}) -> {return_type_name}:
|
|
|
25
26
|
data = {data}
|
|
26
27
|
resp = requests.post(url, json=data, headers=headers)
|
|
27
28
|
if resp.status_code != 200 and resp.status_code != 201:
|
|
28
|
-
|
|
29
|
+
error_content = resp.content.decode("utf-8", errors="ignore")
|
|
30
|
+
raise PolyApiException(f"{{resp.status_code}}: {{error_content}}")
|
|
29
31
|
|
|
30
32
|
return {return_action}
|
|
31
33
|
"""
|
|
@@ -50,7 +52,8 @@ def {function_name}({args}) -> ApiFunctionResponse:
|
|
|
50
52
|
data = {data}
|
|
51
53
|
resp = requests.post(url, json=data, headers=headers)
|
|
52
54
|
if resp.status_code != 200 and resp.status_code != 201:
|
|
53
|
-
|
|
55
|
+
error_content = resp.content.decode("utf-8", errors="ignore")
|
|
56
|
+
raise PolyApiException(f"{{resp.status_code}}: {{error_content}}")
|
|
54
57
|
return ApiFunctionResponse(resp.json())
|
|
55
58
|
"""
|
|
56
59
|
|
|
@@ -71,15 +74,15 @@ def _get_type(type_spec: PropertyType) -> Tuple[str, str]:
|
|
|
71
74
|
elif type_spec["kind"] == "primitive":
|
|
72
75
|
return _map_primitive_types(type_spec["type"]), ""
|
|
73
76
|
elif type_spec["kind"] == "array":
|
|
74
|
-
# TODO needs to be more general
|
|
75
77
|
if type_spec.get("items"):
|
|
76
78
|
items = type_spec["items"]
|
|
77
79
|
if items.get("$ref"):
|
|
78
80
|
return "ResponseType", generate_schema_types(type_spec, root="ResponseType") # type: ignore
|
|
79
81
|
else:
|
|
80
82
|
item_type, _ = _get_type(items)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
title = f"List[{item_type}]"
|
|
84
|
+
title = clean_title(title)
|
|
85
|
+
return title, ""
|
|
83
86
|
else:
|
|
84
87
|
return "List", ""
|
|
85
88
|
elif type_spec["kind"] == "void":
|
|
@@ -88,25 +91,27 @@ def _get_type(type_spec: PropertyType) -> Tuple[str, str]:
|
|
|
88
91
|
if type_spec.get("schema"):
|
|
89
92
|
schema = type_spec["schema"]
|
|
90
93
|
title = schema.get("title", "")
|
|
91
|
-
if
|
|
94
|
+
if title:
|
|
95
|
+
assert isinstance(title, str)
|
|
96
|
+
title = clean_title(title)
|
|
97
|
+
return title, generate_schema_types(schema, root=title) # type: ignore
|
|
98
|
+
elif schema.get("items"):
|
|
92
99
|
# fallback to schema $ref name if no explicit title
|
|
93
|
-
# TODO fix type
|
|
94
100
|
items = schema.get("items") # type: ignore
|
|
95
|
-
|
|
96
|
-
# figure out what it is and fix!
|
|
97
|
-
return "Any", ""
|
|
98
|
-
|
|
99
|
-
title = items.get("title")
|
|
101
|
+
title = items.get("title", "") # type: ignore
|
|
100
102
|
if not title:
|
|
101
103
|
# title is actually a reference to another schema
|
|
102
|
-
title = items.get("$ref", "")
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
title = items.get("$ref", "") # type: ignore
|
|
105
|
+
|
|
106
|
+
title = title.rsplit("/", 1)[-1]
|
|
107
|
+
title = clean_title(title)
|
|
108
|
+
if not title:
|
|
109
|
+
return "List", ""
|
|
110
|
+
|
|
111
|
+
title = f'List[{title}]'
|
|
112
|
+
return title, generate_schema_types(schema, root=title)
|
|
113
|
+
else:
|
|
114
|
+
return "Any", ""
|
|
110
115
|
else:
|
|
111
116
|
return "Dict", ""
|
|
112
117
|
elif type_spec["kind"] == "any":
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
import argparse
|
|
3
|
-
from .generate import generate
|
|
3
|
+
from .generate import generate, clear
|
|
4
4
|
from .function_cli import function_add_or_update
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
CLI_COMMANDS = ["generate", "function", "help"]
|
|
7
|
+
CLI_COMMANDS = ["generate", "clear", "function", "help"]
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def execute_from_cli():
|
|
@@ -25,5 +25,8 @@ def execute_from_cli():
|
|
|
25
25
|
elif command == "generate":
|
|
26
26
|
print("Generating...")
|
|
27
27
|
generate()
|
|
28
|
+
elif command == "clear":
|
|
29
|
+
print("Clearing the generated library...")
|
|
30
|
+
clear()
|
|
28
31
|
elif command == "function":
|
|
29
32
|
function_add_or_update(args.context, args.description, args.server, args.logs, args.subcommands)
|
|
@@ -23,18 +23,30 @@ def get_specs() -> List:
|
|
|
23
23
|
raise NotImplementedError(resp.content)
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def parse_specs(
|
|
26
|
+
def parse_specs(
|
|
27
|
+
specs: List,
|
|
28
|
+
) -> List[Tuple[str, str, str, List[PropertySpecification], Dict[str, Any]]]:
|
|
27
29
|
api_functions = []
|
|
28
30
|
for spec in specs:
|
|
29
|
-
if spec[
|
|
31
|
+
if spec["type"] != "apiFunction" and spec["type"] != "serverFunction":
|
|
30
32
|
# for now we only support api and server functions
|
|
31
33
|
continue
|
|
32
34
|
|
|
33
|
-
function_type = spec[
|
|
35
|
+
function_type = spec["type"]
|
|
34
36
|
function_name = f"poly.{spec['context']}.{spec['name']}"
|
|
35
|
-
function_id = spec[
|
|
36
|
-
arguments: List[PropertySpecification] = [
|
|
37
|
-
|
|
37
|
+
function_id = spec["id"]
|
|
38
|
+
arguments: List[PropertySpecification] = [
|
|
39
|
+
arg for arg in spec["function"]["arguments"]
|
|
40
|
+
]
|
|
41
|
+
api_functions.append(
|
|
42
|
+
(
|
|
43
|
+
function_type,
|
|
44
|
+
function_name,
|
|
45
|
+
function_id,
|
|
46
|
+
arguments,
|
|
47
|
+
spec["function"]["returnType"],
|
|
48
|
+
)
|
|
49
|
+
)
|
|
38
50
|
return api_functions
|
|
39
51
|
|
|
40
52
|
|
|
@@ -65,7 +77,7 @@ def parse_variables(variables: List) -> List[Tuple[str, str, bool]]:
|
|
|
65
77
|
rv = []
|
|
66
78
|
for v in variables:
|
|
67
79
|
path = f"vari.{v['context']}.{v['name']}"
|
|
68
|
-
rv.append((path, v[
|
|
80
|
+
rv.append((path, v["id"], v["secret"]))
|
|
69
81
|
return rv
|
|
70
82
|
|
|
71
83
|
|
|
@@ -93,9 +105,23 @@ def generate() -> None:
|
|
|
93
105
|
full_path = os.path.join(full_path, "poly")
|
|
94
106
|
if not os.path.exists(full_path):
|
|
95
107
|
os.makedirs(full_path)
|
|
96
|
-
print(
|
|
108
|
+
print(
|
|
109
|
+
"No functions exist yet in this tenant! Empty library initialized. Let's add some functions!"
|
|
110
|
+
)
|
|
97
111
|
exit()
|
|
98
112
|
|
|
99
113
|
variables = get_variables_and_parse()
|
|
100
114
|
if variables:
|
|
101
|
-
generate_variables(variables)
|
|
115
|
+
generate_variables(variables)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def clear() -> None:
|
|
119
|
+
base = os.path.dirname(os.path.abspath(__file__))
|
|
120
|
+
poly_path = os.path.join(base, "poly")
|
|
121
|
+
if os.path.exists(poly_path):
|
|
122
|
+
shutil.rmtree(poly_path)
|
|
123
|
+
|
|
124
|
+
vari_path = os.path.join(base, "vari")
|
|
125
|
+
if os.path.exists(vari_path):
|
|
126
|
+
shutil.rmtree(vari_path)
|
|
127
|
+
print("Cleared!")
|
|
@@ -72,4 +72,11 @@ def _fix_title(input_data, output) -> str:
|
|
|
72
72
|
output = _fix_title(v, output)
|
|
73
73
|
elif k == "title":
|
|
74
74
|
output = output.replace(f"class {v.title()}", f"class {v}")
|
|
75
|
-
return output
|
|
75
|
+
return output
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def clean_title(title: str) -> str:
|
|
79
|
+
""" used by library generation, sometimes functions can be added with spaces in the title
|
|
80
|
+
or other nonsense. fix them!
|
|
81
|
+
"""
|
|
82
|
+
return title.replace(" ", "")
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.2", "wheel"]
|
|
3
|
+
|
|
1
4
|
[project]
|
|
2
5
|
name = "polyapi-python"
|
|
3
|
-
version = "0.0.
|
|
6
|
+
version = "0.0.24"
|
|
4
7
|
description = "The PolyAPI Python Client"
|
|
5
8
|
authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }]
|
|
6
9
|
dependencies = ["requests", "typing_extensions", "jsonschema-gentypes", "pydantic>=2.5.3", "stdlib_list"]
|
|
@@ -10,3 +13,10 @@ requires-python = ">=3.10"
|
|
|
10
13
|
|
|
11
14
|
[project.urls]
|
|
12
15
|
Homepage = "https://github.com/polyapi/polyapi-python"
|
|
16
|
+
|
|
17
|
+
[tool.setuptools]
|
|
18
|
+
packages = ["polyapi"]
|
|
19
|
+
|
|
20
|
+
[tools.setuptools.packages.find]
|
|
21
|
+
include = ["polyapi"]
|
|
22
|
+
exclude = ["polyapi/poly*", "polyapi/vari*"] # exclude the generated libraries from builds
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyapi-python-0.0.22 → polyapi-python-0.0.24}/polyapi_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|