polyapi-python 0.1.0.dev2__tar.gz → 0.1.0.dev3__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.
Files changed (31) hide show
  1. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/PKG-INFO +10 -1
  2. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/README.md +10 -1
  3. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/api.py +13 -23
  4. polyapi-python-0.1.0.dev3/polyapi/execute.py +37 -0
  5. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/generate.py +7 -19
  6. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/schema.py +8 -1
  7. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/typedefs.py +18 -2
  8. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/utils.py +15 -1
  9. polyapi-python-0.1.0.dev3/polyapi/variables.py +103 -0
  10. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi_python.egg-info/PKG-INFO +10 -1
  11. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi_python.egg-info/SOURCES.txt +2 -1
  12. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/pyproject.toml +2 -2
  13. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/tests/test_generate.py +15 -11
  14. polyapi-python-0.1.0.dev3/tests/test_variables.py +28 -0
  15. polyapi-python-0.1.0.dev2/polyapi/execute.py +0 -15
  16. polyapi-python-0.1.0.dev2/polyapi/variables.py +0 -86
  17. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/LICENSE +0 -0
  18. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/__init__.py +0 -0
  19. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/__main__.py +0 -0
  20. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/cli.py +0 -0
  21. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/config.py +0 -0
  22. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/constants.py +0 -0
  23. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/exceptions.py +0 -0
  24. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/function_cli.py +0 -0
  25. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi/py.typed +0 -0
  26. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi_python.egg-info/dependency_links.txt +0 -0
  27. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi_python.egg-info/requires.txt +0 -0
  28. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/polyapi_python.egg-info/top_level.txt +0 -0
  29. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/setup.cfg +0 -0
  30. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/tests/test_function_cli.py +0 -0
  31. {polyapi-python-0.1.0.dev2 → polyapi-python-0.1.0.dev3}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyapi-python
3
- Version: 0.1.0.dev2
3
+ Version: 0.1.0.dev3
4
4
  Summary: The PolyAPI Python Client
5
5
  Author-email: Dan Fellin <dan@polyapi.io>
6
6
  License: MIT License
@@ -124,6 +124,11 @@ def bar(n: int) -> Foobar:
124
124
  return Foobar(count=n)
125
125
  ```
126
126
 
127
+ ## Pypi
128
+
129
+ This library is hosted on Pypi. You can find the latest version on the [pypi polyapi-python](https://pypi.org/project/polyapi-python/) project.
130
+
131
+
127
132
  ## Upgrade
128
133
 
129
134
  To upgrade your library to the latest version, pass the upgrade flag.
@@ -147,3 +152,7 @@ To run this library's unit tests, please clone the repo then run:
147
152
  ```bash
148
153
  python -m unittest discover
149
154
  ```
155
+
156
+ ## Support
157
+
158
+ If you run into any issues or want help getting started with this project, please contact support@polyapi.io
@@ -88,6 +88,11 @@ def bar(n: int) -> Foobar:
88
88
  return Foobar(count=n)
89
89
  ```
90
90
 
91
+ ## Pypi
92
+
93
+ This library is hosted on Pypi. You can find the latest version on the [pypi polyapi-python](https://pypi.org/project/polyapi-python/) project.
94
+
95
+
91
96
  ## Upgrade
92
97
 
93
98
  To upgrade your library to the latest version, pass the upgrade flag.
@@ -110,4 +115,8 @@ To run this library's unit tests, please clone the repo then run:
110
115
 
111
116
  ```bash
112
117
  python -m unittest discover
113
- ```
118
+ ```
119
+
120
+ ## Support
121
+
122
+ If you run into any issues or want help getting started with this project, please contact support@polyapi.io
@@ -1,10 +1,10 @@
1
1
  import os
2
2
  from typing import Any, Dict, List, Tuple
3
3
 
4
- from polyapi.constants import BASIC_PYTHON_TYPES, JSONSCHEMA_TO_PYTHON_TYPE_MAP
4
+ from polyapi.constants import BASIC_PYTHON_TYPES
5
5
  from polyapi.typedefs import PropertySpecification, PropertyType
6
- from polyapi.utils import append_init, camelCase
7
- from polyapi.schema import generate_schema_types, clean_title
6
+ from polyapi.utils import add_import_to_init, camelCase, init_the_init
7
+ from polyapi.schema import generate_schema_types, clean_title, map_primitive_types
8
8
 
9
9
  # map the function type from the spec type to the function execute type
10
10
  TEMPLATE_FUNCTION_TYPE_MAP = {
@@ -47,21 +47,16 @@ def {function_name}(
47
47
  """
48
48
 
49
49
 
50
- def _map_primitive_types(type_: str) -> str:
51
- # Define your mapping logic here
52
- return JSONSCHEMA_TO_PYTHON_TYPE_MAP.get(type_, "Any")
53
-
54
-
55
50
  def _get_type(type_spec: PropertyType) -> Tuple[str, str]:
56
51
  if type_spec["kind"] == "plain":
57
52
  value = type_spec["value"]
58
53
  if value.endswith("[]"):
59
- primitive = _map_primitive_types(value[:-2])
54
+ primitive = map_primitive_types(value[:-2])
60
55
  return f"List[{primitive}]", ""
61
56
  else:
62
- return _map_primitive_types(value), ""
57
+ return map_primitive_types(value), ""
63
58
  elif type_spec["kind"] == "primitive":
64
- return _map_primitive_types(type_spec["type"]), ""
59
+ return map_primitive_types(type_spec["type"]), ""
65
60
  elif type_spec["kind"] == "array":
66
61
  if type_spec.get("items"):
67
62
  items = type_spec["items"]
@@ -141,9 +136,10 @@ def _add_type_import_path(function_name: str, arg: str) -> str:
141
136
  return arg
142
137
  else:
143
138
  if '"' in sub:
144
- return f'List[_{function_name}.{camelCase(sub)}]'
145
- else:
139
+ sub = sub.replace('"', "")
146
140
  return f'List["_{function_name}.{camelCase(sub)}"]'
141
+ else:
142
+ return f'List[_{function_name}.{camelCase(sub)}]'
147
143
 
148
144
  return f'_{function_name}.{camelCase(arg)}'
149
145
 
@@ -221,8 +217,7 @@ def add_function_file(
221
217
  return_type: Dict[str, Any],
222
218
  ):
223
219
  # first lets add the import to the __init__
224
- init_path = os.path.join(full_path, "__init__.py")
225
- _init_the_init(init_path)
220
+ init_the_init(full_path)
226
221
 
227
222
  func_str, func_type_defs = render_function(
228
223
  function_type,
@@ -233,6 +228,7 @@ def add_function_file(
233
228
  return_type,
234
229
  )
235
230
 
231
+ init_path = os.path.join(full_path, "__init__.py")
236
232
  with open(init_path, "a") as f:
237
233
  f.write(f"\n\nfrom . import _{function_name}\n\n{func_str}")
238
234
 
@@ -242,12 +238,6 @@ def add_function_file(
242
238
  f.write(func_type_defs)
243
239
 
244
240
 
245
- def _init_the_init(init_path: str) -> None:
246
- if not os.path.exists(init_path):
247
- with open(init_path, "w") as f:
248
- f.write("from typing import List, Dict, Any, TypedDict\nfrom polyapi.execute import execute\nfrom polyapi.exceptions import PolyApiException\n")
249
-
250
-
251
241
  def create_function(
252
242
  function_type: str,
253
243
  path: str,
@@ -279,8 +269,8 @@ def create_function(
279
269
  # append to __init__.py file if nested folders
280
270
  next = folders[idx + 1] if idx + 2 < len(folders) else ""
281
271
  if next:
282
- _init_the_init(os.path.join(full_path, "__init__.py"))
283
- append_init(full_path, next)
272
+ init_the_init(full_path)
273
+ add_import_to_init(full_path, next)
284
274
 
285
275
 
286
276
  def generate_api(api_functions: List) -> None:
@@ -0,0 +1,37 @@
1
+ import requests
2
+ from requests import Response
3
+ from polyapi.config import get_api_key_and_url
4
+ from polyapi.exceptions import PolyApiException
5
+
6
+
7
+ def execute(function_type, function_id, data) -> Response:
8
+ api_key, api_url = get_api_key_and_url()
9
+ headers = {"Authorization": f"Bearer {api_key}"}
10
+ url = f"{api_url}/functions/{function_type}/{function_id}/execute"
11
+ resp = requests.post(url, json=data, headers=headers)
12
+ if resp.status_code != 200 and resp.status_code != 201:
13
+ error_content = resp.content.decode("utf-8", errors="ignore")
14
+ raise PolyApiException(f"{resp.status_code}: {error_content}")
15
+ return resp
16
+
17
+
18
+ def variable_get(variable_id: str) -> Response:
19
+ api_key, base_url = get_api_key_and_url()
20
+ headers = {"Authorization": f"Bearer {api_key}"}
21
+ url = f"{base_url}/variables/{variable_id}/value"
22
+ resp = requests.get(url, headers=headers)
23
+ if resp.status_code != 200 and resp.status_code != 201:
24
+ error_content = resp.content.decode("utf-8", errors="ignore")
25
+ raise PolyApiException(f"{resp.status_code}: {error_content}")
26
+ return resp
27
+
28
+
29
+ def variable_update(variable_id: str, value) -> Response:
30
+ api_key, base_url = get_api_key_and_url()
31
+ headers = {"Authorization": f"Bearer {api_key}"}
32
+ url = f"{base_url}/variables/{variable_id}/value"
33
+ resp = requests.patch(url, data={"value": value}, headers=headers)
34
+ if resp.status_code != 200 and resp.status_code != 201:
35
+ error_content = resp.content.decode("utf-8", errors="ignore")
36
+ raise PolyApiException(f"{resp.status_code}: {error_content}")
37
+ return resp
@@ -4,7 +4,7 @@ import os
4
4
  import shutil
5
5
  from typing import Any, Dict, List, Tuple
6
6
 
7
- from .typedefs import PropertySpecification
7
+ from .typedefs import PropertySpecification, VariableSpecDto
8
8
  from .utils import get_auth_headers
9
9
  from .api import generate_api
10
10
  from .variables import generate_variables
@@ -81,31 +81,19 @@ def get_functions_and_parse():
81
81
  return functions
82
82
 
83
83
 
84
- def get_variables_and_parse() -> List[Tuple[str, str, bool]]:
85
- raw = get_variables()
86
- variables = parse_variables(raw)
87
- return variables
88
-
89
-
90
- def get_variables():
84
+ def get_variables() -> List[VariableSpecDto]:
91
85
  api_key, api_url = get_api_key_and_url()
92
86
  headers = {"Authorization": f"Bearer {api_key}"}
93
- url = f"{api_url}/variables"
87
+ # TODO do some caching so this and get_functions just do 1 function call
88
+ url = f"{api_url}/specs"
94
89
  resp = requests.get(url, headers=headers)
95
90
  if resp.status_code == 200:
96
- return resp.json()
91
+ specs = resp.json()
92
+ return [spec for spec in specs if spec['type'] == "serverVariable"]
97
93
  else:
98
94
  raise NotImplementedError(resp.content)
99
95
 
100
96
 
101
- def parse_variables(variables: List) -> List[Tuple[str, str, bool]]:
102
- rv = []
103
- for v in variables:
104
- path = f"vari.{v['context']}.{v['name']}"
105
- rv.append((path, v["id"], v["secret"]))
106
- return rv
107
-
108
-
109
97
  def remove_old_library():
110
98
  currdir = os.path.dirname(os.path.abspath(__file__))
111
99
  path = os.path.join(currdir, "poly")
@@ -131,7 +119,7 @@ def generate() -> None:
131
119
  )
132
120
  exit()
133
121
 
134
- variables = get_variables_and_parse()
122
+ variables = get_variables()
135
123
  if variables:
136
124
  generate_variables(variables)
137
125
 
@@ -5,6 +5,8 @@ from jsonschema_gentypes import configuration
5
5
  import tempfile
6
6
  import json
7
7
 
8
+ from polyapi.constants import JSONSCHEMA_TO_PYTHON_TYPE_MAP
9
+
8
10
 
9
11
  def _cleanup_input_for_gentypes(input_data: Dict):
10
12
  """ cleanup input_data in place to make it more suitable for jsonschema_gentypes
@@ -83,4 +85,9 @@ def clean_title(title: str) -> str:
83
85
  # certain reserved words cant be titles, let's replace them
84
86
  if title == "List":
85
87
  title = "List_"
86
- return title
88
+ return title
89
+
90
+
91
+ def map_primitive_types(type_: str) -> str:
92
+ # Define your mapping logic here
93
+ return JSONSCHEMA_TO_PYTHON_TYPE_MAP.get(type_, "Any")
@@ -32,6 +32,22 @@ class SpecificationDto(TypedDict):
32
32
  context: str
33
33
  name: str
34
34
  description: str
35
+ # function is none if this is actually VariableSpecDto
35
36
  function: FunctionSpecification | None
36
- # variables have variable: {"secret": boolean} and NO function
37
- type: Literal['apiFunction', 'customFunction', 'serverFunction', 'authFunction', 'webhookHandle', 'serverVariable']
37
+ type: Literal['apiFunction', 'customFunction', 'serverFunction', 'authFunction', 'webhookHandle', 'serverVariable']
38
+
39
+
40
+ class VariableSpecification(TypedDict):
41
+ environmentId: str
42
+ value: Any
43
+ valueType: PropertyType
44
+ secret: bool
45
+
46
+
47
+ class VariableSpecDto(TypedDict):
48
+ id: str
49
+ context: str
50
+ name: str
51
+ description: str
52
+ variable: VariableSpecification
53
+ type: Literal['serverVariable']
@@ -2,7 +2,21 @@ import re
2
2
  import os
3
3
 
4
4
 
5
- def append_init(full_path: str, next: str) -> None:
5
+ # this string should be in every __init__ file.
6
+ # it contains all the imports needed for the function or variable code to run
7
+ CODE_IMPORTS = "from typing import List, Dict, Any, TypedDict\nfrom polyapi.execute import execute, variable_get, variable_update\n\n"
8
+
9
+
10
+ def init_the_init(full_path: str) -> None:
11
+ init_path = os.path.join(full_path, "__init__.py")
12
+ if not os.path.exists(init_path):
13
+ with open(init_path, "w") as f:
14
+ f.write(CODE_IMPORTS)
15
+
16
+
17
+ def add_import_to_init(full_path: str, next: str) -> None:
18
+ init_the_init(full_path)
19
+
6
20
  init_path = os.path.join(full_path, "__init__.py")
7
21
  with open(init_path, "a+") as f:
8
22
  import_stmt = "from . import {}\n".format(next)
@@ -0,0 +1,103 @@
1
+ import os
2
+ from typing import List
3
+
4
+ from polyapi.schema import map_primitive_types
5
+ from polyapi.typedefs import PropertyType, VariableSpecDto
6
+ from polyapi.utils import add_import_to_init, init_the_init
7
+
8
+
9
+ # GET is only included if the variable is not a secret
10
+ GET_TEMPLATE = """
11
+ @staticmethod
12
+ def get() -> {variable_type}:
13
+ resp = variable_get("{variable_id}")
14
+ return resp.text
15
+ """
16
+
17
+
18
+ TEMPLATE = """
19
+ class {variable_name}:{get_method}
20
+ @staticmethod
21
+ def update(value: {variable_type}):
22
+ resp = variable_update("{variable_id}", value)
23
+ return resp.json()
24
+
25
+ @staticmethod
26
+ def inject(path=None) -> {variable_type}:
27
+ return {{
28
+ "type": "PolyVariable",
29
+ "id": "{variable_id}",
30
+ "path": path,
31
+ }} # type: ignore"""
32
+
33
+
34
+ def generate_variables(variables: List[VariableSpecDto]):
35
+ for variable in variables:
36
+ create_variable(variable)
37
+ print("Variables generated!")
38
+
39
+
40
+ def render_variable(variable: VariableSpecDto):
41
+ variable_type = _get_variable_type(variable["variable"]["valueType"])
42
+ get_method = (
43
+ ""
44
+ if variable["variable"]["secret"]
45
+ else GET_TEMPLATE.format(
46
+ variable_id=variable["id"], variable_type=variable_type
47
+ )
48
+ )
49
+ return TEMPLATE.format(
50
+ variable_name=variable["name"],
51
+ variable_id=variable["id"],
52
+ variable_type=variable_type,
53
+ get_method=get_method,
54
+ )
55
+
56
+
57
+ def _get_variable_type(type_spec: PropertyType) -> str:
58
+ # simplified version of _get_type from api.py
59
+ if type_spec["kind"] == "plain":
60
+ value = type_spec["value"]
61
+ if value.endswith("[]"):
62
+ primitive = map_primitive_types(value[:-2])
63
+ return f"List[{primitive}]"
64
+ else:
65
+ return map_primitive_types(value)
66
+ elif type_spec["kind"] == "primitive":
67
+ return map_primitive_types(type_spec["type"])
68
+ elif type_spec["kind"] == "array":
69
+ return "List"
70
+ elif type_spec["kind"] == "void":
71
+ return "None"
72
+ elif type_spec["kind"] == "object":
73
+ return "Dict"
74
+ elif type_spec["kind"] == "any":
75
+ return "Any"
76
+ else:
77
+ return "Any"
78
+
79
+
80
+ def create_variable(variable: VariableSpecDto) -> None:
81
+ folders = ["vari"]
82
+ if variable["context"]:
83
+ folders += variable["context"].split(".")
84
+
85
+ # build up the full_path by adding all the folders
86
+ full_path = os.path.join(os.path.dirname(os.path.abspath(__file__)))
87
+
88
+ for idx, folder in enumerate(folders):
89
+ full_path = os.path.join(full_path, folder)
90
+ if not os.path.exists(full_path):
91
+ os.makedirs(full_path)
92
+ next = folders[idx + 1] if idx + 1 < len(folders) else None
93
+ if next:
94
+ add_import_to_init(full_path, next)
95
+
96
+ add_variable_to_init(full_path, variable)
97
+
98
+
99
+ def add_variable_to_init(full_path: str, variable: VariableSpecDto):
100
+ init_the_init(full_path)
101
+ init_path = os.path.join(full_path, "__init__.py")
102
+ with open(init_path, "a") as f:
103
+ f.write(render_variable(variable) + "\n\n")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyapi-python
3
- Version: 0.1.0.dev2
3
+ Version: 0.1.0.dev3
4
4
  Summary: The PolyAPI Python Client
5
5
  Author-email: Dan Fellin <dan@polyapi.io>
6
6
  License: MIT License
@@ -124,6 +124,11 @@ def bar(n: int) -> Foobar:
124
124
  return Foobar(count=n)
125
125
  ```
126
126
 
127
+ ## Pypi
128
+
129
+ This library is hosted on Pypi. You can find the latest version on the [pypi polyapi-python](https://pypi.org/project/polyapi-python/) project.
130
+
131
+
127
132
  ## Upgrade
128
133
 
129
134
  To upgrade your library to the latest version, pass the upgrade flag.
@@ -147,3 +152,7 @@ To run this library's unit tests, please clone the repo then run:
147
152
  ```bash
148
153
  python -m unittest discover
149
154
  ```
155
+
156
+ ## Support
157
+
158
+ If you run into any issues or want help getting started with this project, please contact support@polyapi.io
@@ -23,4 +23,5 @@ polyapi_python.egg-info/requires.txt
23
23
  polyapi_python.egg-info/top_level.txt
24
24
  tests/test_function_cli.py
25
25
  tests/test_generate.py
26
- tests/test_utils.py
26
+ tests/test_utils.py
27
+ tests/test_variables.py
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"]
3
3
 
4
4
  [project]
5
5
  name = "polyapi-python"
6
- version = "0.1.0.dev2"
6
+ version = "0.1.0.dev3"
7
7
  description = "The PolyAPI Python Client"
8
8
  authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }]
9
9
  dependencies = ["requests", "typing_extensions", "jsonschema-gentypes", "pydantic>=2.5.3", "stdlib_list"]
@@ -19,4 +19,4 @@ packages = ["polyapi"]
19
19
 
20
20
  [tools.setuptools.packages.find]
21
21
  include = ["polyapi"]
22
- exclude = ["polyapi/poly*", "polyapi/vari*", "polyapi/.config.env"] # exclude the generated libraries from builds
22
+ exclude = ["polyapi/poly*", "polyapi/vari*", "polyapi/.config.env"] # exclude the generated libraries from builds
@@ -155,9 +155,10 @@ GET_PRODUCTS_COUNT = {
155
155
 
156
156
  class T(unittest.TestCase):
157
157
  def test_render_function_accuweather(self):
158
- func_str = render_function(
158
+ name = ACCUWEATHER["name"]
159
+ func_str, _ = render_function(
159
160
  ACCUWEATHER["type"],
160
- ACCUWEATHER["name"],
161
+ name,
161
162
  ACCUWEATHER["id"],
162
163
  ACCUWEATHER["description"],
163
164
  ACCUWEATHER["function"]["arguments"],
@@ -165,12 +166,13 @@ class T(unittest.TestCase):
165
166
  )
166
167
  self.assertIn(ACCUWEATHER["id"], func_str)
167
168
  self.assertIn("locationId: int,", func_str)
168
- self.assertIn("-> ApiFunctionResponse", func_str)
169
+ self.assertIn(f"-> _{name}.{name}Response", func_str)
169
170
 
170
171
  def test_render_function_zillow(self):
171
- func_str = render_function(
172
+ name = ZILLOW['name']
173
+ func_str, _ = render_function(
172
174
  ZILLOW["type"],
173
- ZILLOW["name"],
175
+ name,
174
176
  ZILLOW["id"],
175
177
  ZILLOW["description"],
176
178
  ZILLOW["function"]["arguments"],
@@ -178,10 +180,11 @@ class T(unittest.TestCase):
178
180
  )
179
181
  self.assertIn(ZILLOW["id"], func_str)
180
182
  self.assertIn("locationId: int,", func_str)
181
- self.assertIn("-> ApiFunctionResponse", func_str)
183
+ self.assertIn(f"-> _{name}.{name}Response", func_str)
182
184
 
183
185
  def test_render_function_twilio_api(self):
184
- func_str = render_function(
186
+ name = TWILIO['name']
187
+ func_str, _ = render_function(
185
188
  TWILIO["type"],
186
189
  TWILIO["name"],
187
190
  TWILIO["id"],
@@ -192,11 +195,12 @@ class T(unittest.TestCase):
192
195
  self.assertIn(TWILIO["id"], func_str)
193
196
  self.assertIn("conversationSID: str", func_str)
194
197
  self.assertIn("authToken: str", func_str)
195
- self.assertIn("-> ApiFunctionResponse", func_str)
198
+ self.assertIn(f"-> _{name}.{name}Response", func_str)
196
199
 
197
200
  def test_render_function_twilio_server(self):
198
201
  # same test but try it as a serverFunction rather than an apiFunction
199
- func_str = render_function(
202
+ name = TWILIO['name']
203
+ func_str, _ = render_function(
200
204
  "serverFunction",
201
205
  TWILIO["name"],
202
206
  TWILIO["id"],
@@ -207,11 +211,11 @@ class T(unittest.TestCase):
207
211
  self.assertIn(TWILIO["id"], func_str)
208
212
  self.assertIn("conversationSID: str", func_str)
209
213
  self.assertIn("authToken: str", func_str)
210
- self.assertIn("-> ResponseType", func_str)
214
+ self.assertIn(f"-> _{name}.ResponseType", func_str)
211
215
 
212
216
  def test_render_function_get_products_count(self):
213
217
  return_type = GET_PRODUCTS_COUNT["function"]["returnType"]
214
- func_str = render_function(
218
+ func_str, _ = render_function(
215
219
  GET_PRODUCTS_COUNT["type"],
216
220
  GET_PRODUCTS_COUNT["name"],
217
221
  GET_PRODUCTS_COUNT["id"],
@@ -0,0 +1,28 @@
1
+ import unittest
2
+ from polyapi.variables import render_variable
3
+
4
+ EXAMPLE = {
5
+ "type": "serverVariable",
6
+ "id": "181238j18231j",
7
+ "name": "test",
8
+ "context": "my3",
9
+ "description": "a test variable",
10
+ "visibilityMetadata": {
11
+ "visibility": "ENVIRONMENT"
12
+ },
13
+ "variable": {
14
+ "environmentId": "123818231",
15
+ "secret": False,
16
+ "valueType": {
17
+ "kind": "primitive",
18
+ "type": "string"
19
+ },
20
+ "value": "some mock value"
21
+ }
22
+ }
23
+
24
+
25
+ class T(unittest.TestCase):
26
+ def test_render_variable(self):
27
+ variable_str = render_variable(EXAMPLE)
28
+ self.assertIn("class test", variable_str)
@@ -1,15 +0,0 @@
1
- import requests
2
- from requests import Response
3
- from polyapi.config import get_api_key_and_url
4
- from polyapi.exceptions import PolyApiException
5
-
6
-
7
- def execute(function_type, function_id, data) -> Response:
8
- api_key, api_url = get_api_key_and_url()
9
- headers = {"Authorization": f"Bearer {api_key}"}
10
- url = f"{api_url}/functions/{function_type}/{function_id}/execute"
11
- resp = requests.post(url, json=data, headers=headers)
12
- if resp.status_code != 200 and resp.status_code != 201:
13
- error_content = resp.content.decode("utf-8", errors="ignore")
14
- raise PolyApiException(f"{resp.status_code}: {error_content}")
15
- return resp
@@ -1,86 +0,0 @@
1
- import os
2
-
3
- from polyapi.utils import append_init
4
-
5
-
6
- TEMPLATE = """
7
- import requests
8
- from polyapi.config import get_api_key_and_url
9
- from polyapi.exceptions import PolyApiException
10
-
11
-
12
- class {variable_name}:
13
- @staticmethod
14
- def get():
15
- secret = {secret}
16
- if secret:
17
- raise ValueError('Cannot access secret variable from client. Use .inject() instead within Poly function.')
18
- else:
19
- api_key, base_url = get_api_key_and_url()
20
- headers = {{"Authorization": f"Bearer {{api_key}}"}}
21
- url = f"{{base_url}}/variables/{variable_id}/value"
22
- resp = requests.get(url, headers=headers)
23
- if resp.status_code != 200 and resp.status_code != 201:
24
- raise PolyApiException(f"{{resp.status_code}}: {{resp.content}}")
25
- return resp.text
26
-
27
- @staticmethod
28
- def update(value):
29
- api_key, base_url = get_api_key_and_url()
30
- headers = {{"Authorization": f"Bearer {{api_key}}"}}
31
- url = f"{{base_url}}/variables/{variable_id}"
32
- resp = requests.patch(url, data={{"value": value}}, headers=headers)
33
- if resp.status_code != 200 and resp.status_code != 201:
34
- raise PolyApiException(f"{{resp.status_code}}: {{resp.content}}")
35
- return resp.json()
36
-
37
- def inject(path=None):
38
- return {{
39
- "type": "PolyVariable",
40
- "id": "{variable_id}",
41
- "path": path,
42
- }}
43
- """
44
-
45
-
46
- def generate_variables(variables):
47
- for variable in variables:
48
- create_variable(*variable)
49
- print("Variables generated!")
50
-
51
-
52
- def add_variable_file(full_path: str, variable_name: str, variable_id: str, secret: str):
53
- # first lets add the import to the __init__
54
- init_path = os.path.join(full_path, "__init__.py")
55
- with open(init_path, "a") as f:
56
- f.write(f"from ._{variable_name} import {variable_name}\n")
57
-
58
- # now lets add the code!
59
- file_path = os.path.join(full_path, f"_{variable_name}.py")
60
- with open(file_path, "w") as f:
61
- f.write(
62
- TEMPLATE.format(
63
- variable_name=variable_name,
64
- variable_id=variable_id,
65
- secret=secret,
66
- )
67
- )
68
-
69
-
70
- def create_variable(path: str, variable_id: str, secret: str) -> None:
71
- full_path = os.path.dirname(os.path.abspath(__file__))
72
-
73
- folders = path.split(".")
74
- for idx, folder in enumerate(folders):
75
- if idx + 1 == len(folders):
76
- variable_name = folder
77
- add_variable_file(full_path, variable_name, variable_id, secret)
78
- else:
79
- full_path = os.path.join(full_path, folder)
80
- if not os.path.exists(full_path):
81
- os.makedirs(full_path)
82
-
83
- # append to __init__.py file if nested folders
84
- next = folders[idx + 1] if idx + 2 < len(folders) else ""
85
- if next:
86
- append_init(full_path, next)