polyapi-python 0.2.3.dev9__py3-none-any.whl → 0.2.4__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  import sys
3
3
  import truststore
4
+ from typing import Dict, Any
4
5
  truststore.inject_into_ssl()
5
6
  from .cli import CLI_COMMANDS
6
7
 
@@ -11,4 +12,12 @@ if len(sys.argv) > 1 and sys.argv[1] not in CLI_COMMANDS:
11
12
  currdir = os.path.dirname(os.path.abspath(__file__))
12
13
  if not os.path.isdir(os.path.join(currdir, "poly")):
13
14
  print("No 'poly' found. Please run 'python3 -m polyapi generate' to generate the 'poly' library for your tenant.")
14
- sys.exit(1)
15
+ sys.exit(1)
16
+
17
+
18
+ polyCustom: Dict[str, Any] = {
19
+ "executionId": None,
20
+ "executionApiKey": None,
21
+ "responseStatusCode": 200,
22
+ "responseContentType": None,
23
+ }
polyapi/client.py CHANGED
@@ -10,6 +10,22 @@ from typing import List, Dict, Any, TypedDict
10
10
  """
11
11
 
12
12
 
13
+ def _wrap_code_in_try_except(code: str) -> str:
14
+ """ this is necessary because client functions with imports will blow up ALL server functions,
15
+ even if they don't use them.
16
+ because the server function will try to load all client functions when loading the library
17
+ """
18
+ prefix = """logger = logging.getLogger("poly")
19
+ try:
20
+ """
21
+ suffix = """except ImportError as e:
22
+ logger.debug(e)"""
23
+
24
+ lines = code.split("\n")
25
+ code = "\n ".join(lines)
26
+ return "".join([prefix, code, "\n", suffix])
27
+
28
+
13
29
  def render_client_function(
14
30
  function_name: str,
15
31
  code: str,
@@ -22,4 +38,7 @@ def render_client_function(
22
38
  args_def=args_def,
23
39
  return_type_def=return_type_def,
24
40
  )
41
+
42
+ code = _wrap_code_in_try_except(code)
43
+
25
44
  return code + "\n\n", func_type_defs
polyapi/error_handler.py CHANGED
@@ -1,52 +1,85 @@
1
1
  import asyncio
2
2
  import copy
3
3
  import socketio # type: ignore
4
- from typing import Any, Callable, Dict, Optional
4
+ from socketio.exceptions import ConnectionError # type: ignore
5
+ from typing import Any, Callable, Dict, List, Optional
5
6
 
6
7
  from polyapi.config import get_api_key_and_url
7
8
 
8
9
 
9
- local_error_handlers: Dict[str, Any] = {}
10
+ # all active webhook handlers, used by unregister_all to cleanup
11
+ active_handlers: List[Dict[str, Any]] = []
10
12
 
13
+ # global client shared by all error handlers, will be initialized by webhook.start
14
+ client = None
11
15
 
12
- def on(path: str, callback: Callable, options: Optional[Dict[str, Any]] = None) -> Callable:
13
- assert not local_error_handlers
14
- socket = socketio.AsyncClient()
15
- api_key, base_url = get_api_key_and_url()
16
16
 
17
- async def _inner():
18
- await socket.connect(base_url, transports=["websocket"], namespaces=["/events"])
17
+ def prepare():
18
+ loop = asyncio.get_event_loop()
19
+ loop.run_until_complete(get_client_and_connect())
20
+ print("Client initialized!")
19
21
 
20
- handler_id = None
21
- data = copy.deepcopy(options or {})
22
- data["path"] = path
23
- data["apiKey"] = api_key
24
22
 
25
- def registerCallback(id: int):
26
- nonlocal handler_id, socket
27
- handler_id = id
28
- socket.on(f"handleError:{handler_id}", callback, namespace="/events")
29
23
 
30
- await socket.emit("registerErrorHandler", data, "/events", registerCallback)
31
- if local_error_handlers.get(path):
32
- local_error_handlers[path].append(callback)
33
- else:
34
- local_error_handlers[path] = [callback]
24
+ async def get_client_and_connect():
25
+ _, base_url = get_api_key_and_url()
26
+ global client
27
+ client = socketio.AsyncClient()
28
+ await client.connect(base_url, transports=["websocket"], namespaces=["/events"])
35
29
 
36
- async def unregister():
37
- nonlocal handler_id, socket
38
- if handler_id and socket:
39
- await socket.emit(
40
- "unregisterErrorHandler",
41
- {"id": handler_id, "path": path, "apiKey": api_key},
42
- namespace="/events",
43
- )
44
30
 
45
- if local_error_handlers.get(path):
46
- local_error_handlers[path].remove(callback)
31
+ async def unregister(data: Dict[str, Any]):
32
+ print(f"Stopping error handler for {data['path']}...")
33
+ assert client
34
+ await client.emit(
35
+ "unregisterErrorHandler",
36
+ data,
37
+ "/events",
38
+ )
47
39
 
48
- await socket.wait()
49
40
 
50
- return unregister
41
+ async def unregister_all():
42
+ _, base_url = get_api_key_and_url()
43
+ # need to reconnect because maybe socketio client disconnected after Ctrl+C?
44
+ try:
45
+ await client.connect(base_url, transports=["websocket"], namespaces=["/events"])
46
+ except ConnectionError:
47
+ pass
48
+ await asyncio.gather(*[unregister(handler) for handler in active_handlers])
51
49
 
52
- return asyncio.run(_inner())
50
+
51
+ async def on(
52
+ path: str, callback: Callable, options: Optional[Dict[str, Any]] = None
53
+ ) -> None:
54
+ print(f"Starting error handler for {path}...")
55
+
56
+ if not client:
57
+ raise Exception("Client not initialized. Abort!")
58
+
59
+ api_key, _ = get_api_key_and_url()
60
+ handler_id = None
61
+ data = copy.deepcopy(options or {})
62
+ data["path"] = path
63
+ data["apiKey"] = api_key
64
+
65
+ def registerCallback(id: int):
66
+ nonlocal handler_id
67
+ handler_id = id
68
+ client.on(f"handleError:{handler_id}", callback, namespace="/events")
69
+ active_handlers.append({"path": path, "id": handler_id, "apiKey": api_key})
70
+
71
+ await client.emit("registerErrorHandler", data, "/events", registerCallback)
72
+
73
+
74
+ def start(*args):
75
+ loop = asyncio.get_event_loop()
76
+ loop.run_until_complete(get_client_and_connect())
77
+ asyncio.gather(*args)
78
+
79
+ try:
80
+ loop.run_forever()
81
+ except KeyboardInterrupt:
82
+ pass
83
+ finally:
84
+ loop.run_until_complete(unregister_all())
85
+ loop.stop()
polyapi/execute.py CHANGED
@@ -11,7 +11,9 @@ def execute(function_type, function_id, data) -> Response:
11
11
  headers = {"Authorization": f"Bearer {api_key}"}
12
12
  url = f"{api_url}/functions/{function_type}/{function_id}/execute"
13
13
  resp = requests.post(url, json=data, headers=headers)
14
- if resp.status_code != 200 and resp.status_code != 201:
14
+ # print(resp.status_code)
15
+ # print(resp.headers["content-type"])
16
+ if resp.status_code < 200 or resp.status_code >= 300:
15
17
  error_content = resp.content.decode("utf-8", errors="ignore")
16
18
  raise PolyApiException(f"{resp.status_code}: {error_content}")
17
19
  return resp
polyapi/function_cli.py CHANGED
@@ -4,6 +4,7 @@ import json
4
4
  import types
5
5
  import sys
6
6
  from typing import Dict, List, Mapping, Optional, Tuple
7
+ from typing import _TypedDictMeta as BaseTypedDict # type: ignore
7
8
  from typing_extensions import _TypedDictMeta # type: ignore
8
9
  import requests
9
10
  from stdlib_list import stdlib_list
@@ -18,9 +19,18 @@ import importlib
18
19
 
19
20
  # these libraries are already installed in the base docker image
20
21
  # and shouldnt be included in additional requirements
21
- BASE_REQUIREMENTS = {"polyapi", "requests", "typing_extensions", "jsonschema-gentypes", "pydantic", "cloudevents"}
22
- all_stdlib_symbols = stdlib_list('.'.join([str(v) for v in sys.version_info[0:2]]))
23
- BASE_REQUIREMENTS.update(all_stdlib_symbols) # dont need to pip install stuff in the python standard library
22
+ BASE_REQUIREMENTS = {
23
+ "polyapi",
24
+ "requests",
25
+ "typing_extensions",
26
+ "jsonschema-gentypes",
27
+ "pydantic",
28
+ "cloudevents",
29
+ }
30
+ all_stdlib_symbols = stdlib_list(".".join([str(v) for v in sys.version_info[0:2]]))
31
+ BASE_REQUIREMENTS.update(
32
+ all_stdlib_symbols
33
+ ) # dont need to pip install stuff in the python standard library
24
34
 
25
35
 
26
36
  def _get_schemas(code: str) -> List[Dict]:
@@ -28,7 +38,14 @@ def _get_schemas(code: str) -> List[Dict]:
28
38
  user_code = types.SimpleNamespace()
29
39
  exec(code, user_code.__dict__)
30
40
  for name, obj in user_code.__dict__.items():
31
- if (
41
+ if isinstance(obj, BaseTypedDict):
42
+ print_red("ERROR")
43
+ print_red("\nERROR DETAILS: ")
44
+ print(
45
+ "It looks like you have used TypedDict in a custom function. Please use `from typing_extensions import TypedDict` instead. The `typing_extensions` version is more powerful and better allows us to provide rich types for your function."
46
+ )
47
+ sys.exit(1)
48
+ elif (
32
49
  isinstance(obj, type)
33
50
  and isinstance(obj, _TypedDictMeta)
34
51
  and name != "TypedDict"
@@ -76,6 +93,13 @@ def get_python_type_from_ast(expr: ast.expr) -> str:
76
93
  if name == "List":
77
94
  slice = getattr(expr.slice, "id", "Any")
78
95
  return f"List[{slice}]"
96
+ elif name == "Dict":
97
+ if expr.slice and isinstance(expr.slice, ast.Tuple):
98
+ key = get_python_type_from_ast(expr.slice.dims[0])
99
+ value = get_python_type_from_ast(expr.slice.dims[1])
100
+ return f"Dict[{key}, {value}]"
101
+ else:
102
+ return "Dict"
79
103
  return "Any"
80
104
  else:
81
105
  return "Any"
@@ -104,7 +128,9 @@ def _get_type(expr: ast.expr | None, schemas: List[Dict]) -> Tuple[str, Dict | N
104
128
  return json_type, _get_type_schema(json_type, python_type, schemas)
105
129
 
106
130
 
107
- def _get_req_name_if_not_in_base(n: Optional[str], pip_name_lookup: Mapping[str, List[str]]) -> Optional[str]:
131
+ def _get_req_name_if_not_in_base(
132
+ n: Optional[str], pip_name_lookup: Mapping[str, List[str]]
133
+ ) -> Optional[str]:
108
134
  if not n:
109
135
  return None
110
136
 
@@ -175,7 +201,12 @@ def _func_already_exists(context: str, function_name: str) -> bool:
175
201
 
176
202
 
177
203
  def function_add_or_update(
178
- context: str, description: str, client: bool, server: bool, logs_enabled: bool, subcommands: List
204
+ context: str,
205
+ description: str,
206
+ client: bool,
207
+ server: bool,
208
+ logs_enabled: bool,
209
+ subcommands: List,
179
210
  ):
180
211
  parser = argparse.ArgumentParser()
181
212
  parser.add_argument("subcommand", choices=["add"])
@@ -191,16 +222,15 @@ def function_add_or_update(
191
222
  code = f.read()
192
223
 
193
224
  # OK! let's parse the code and generate the arguments
194
- (
195
- arguments,
196
- return_type,
197
- return_type_schema,
198
- requirements
199
- ) = _parse_code(code, args.function_name)
225
+ (arguments, return_type, return_type_schema, requirements) = _parse_code(
226
+ code, args.function_name
227
+ )
200
228
 
201
229
  if not return_type:
202
230
  print_red("ERROR")
203
- print(f"Function {args.function_name} not found as top-level function in {args.filename}")
231
+ print(
232
+ f"Function {args.function_name} not found as top-level function in {args.filename}"
233
+ )
204
234
  sys.exit(1)
205
235
 
206
236
  data = {
@@ -216,7 +246,9 @@ def function_add_or_update(
216
246
  }
217
247
 
218
248
  if server and requirements:
219
- print_yellow('\nPlease note that deploying your functions will take a few minutes because it makes use of libraries other than polyapi.')
249
+ print_yellow(
250
+ "\nPlease note that deploying your functions will take a few minutes because it makes use of libraries other than polyapi."
251
+ )
220
252
  data["requirements"] = requirements
221
253
 
222
254
  api_key, api_url = get_api_key_and_url()
polyapi/generate.py CHANGED
@@ -176,6 +176,7 @@ def render_spec(spec: SpecificationDto):
176
176
  function_type = spec["type"]
177
177
  function_description = spec["description"]
178
178
  function_name = spec["name"]
179
+ function_context = spec["context"]
179
180
  function_id = spec["id"]
180
181
 
181
182
  arguments: List[PropertySpecification] = []
@@ -223,6 +224,7 @@ def render_spec(spec: SpecificationDto):
223
224
  elif function_type == "webhookHandle":
224
225
  func_str, func_type_defs = render_webhook_handle(
225
226
  function_type,
227
+ function_context,
226
228
  function_name,
227
229
  function_id,
228
230
  function_description,
polyapi/server.py CHANGED
@@ -18,7 +18,10 @@ def {function_name}(
18
18
  Function ID: {function_id}
19
19
  \"""
20
20
  resp = execute("{function_type}", "{function_id}", {data})
21
- return {return_action}
21
+ try:
22
+ return {return_action}
23
+ except:
24
+ return resp.text
22
25
  """
23
26
 
24
27
 
@@ -54,14 +57,6 @@ def render_server_function(
54
57
  def _get_server_return_action(return_type_name: str) -> str:
55
58
  if return_type_name == "str":
56
59
  return_action = "resp.text"
57
- elif return_type_name == "Any":
58
- return_action = "resp.text"
59
- elif return_type_name == "int":
60
- return_action = "int(resp.text.replace('(int) ', ''))"
61
- elif return_type_name == "float":
62
- return_action = "float(resp.text.replace('(float) ', ''))"
63
- elif return_type_name == "bool":
64
- return_action = "False if resp.text == 'False' else True"
65
60
  else:
66
61
  return_action = "resp.json()"
67
62
  return return_action
polyapi/utils.py CHANGED
@@ -10,7 +10,7 @@ from polyapi.schema import generate_schema_types, clean_title, map_primitive_typ
10
10
 
11
11
  # this string should be in every __init__ file.
12
12
  # it contains all the imports needed for the function or variable code to run
13
- CODE_IMPORTS = "from typing import List, Dict, Any, TypedDict, Optional\nimport requests\nimport socketio # type: ignore\nfrom polyapi.config import get_api_key_and_url\nfrom polyapi.execute import execute, execute_post, variable_get, variable_update\n\n"
13
+ CODE_IMPORTS = "from typing import List, Dict, Any, TypedDict, Optional\nimport logging\nimport requests\nimport socketio # type: ignore\nfrom polyapi.config import get_api_key_and_url\nfrom polyapi.execute import execute, execute_post, variable_get, variable_update\n\n"
14
14
 
15
15
 
16
16
  def init_the_init(full_path: str) -> None:
@@ -165,4 +165,13 @@ def parse_arguments(function_name: str, arguments: List[PropertySpecification])
165
165
  arg_string += f", # {description}\n"
166
166
  else:
167
167
  arg_string += ",\n"
168
- return arg_string.rstrip("\n"), "\n\n".join(args_def)
168
+ return arg_string.rstrip("\n"), "\n\n".join(args_def)
169
+
170
+
171
+ def poly_full_path(context, name) -> str:
172
+ """get the functions path as it will be exposed in the poly library"""
173
+ if context:
174
+ path = context + "." + name
175
+ else:
176
+ path = name
177
+ return f"poly.{path}"
polyapi/webhook.py CHANGED
@@ -1,81 +1,111 @@
1
+ import asyncio
2
+ import socketio # type: ignore
3
+ from socketio.exceptions import ConnectionError # type: ignore
1
4
  import uuid
2
5
  from typing import Any, Dict, List, Tuple
3
6
 
7
+ from polyapi.config import get_api_key_and_url
4
8
  from polyapi.typedefs import PropertySpecification
9
+ from polyapi.utils import poly_full_path
10
+
11
+ # all active webhook handlers, used by unregister_all to cleanup
12
+ active_handlers: List[Dict[str, Any]] = []
13
+
14
+ # global client shared by all webhooks, will be initialized by webhook.start
15
+ client = None
16
+
5
17
 
6
18
  WEBHOOK_TEMPLATE = """
7
- import asyncio
8
19
 
9
20
 
10
- def {function_name}(callback, options=None):
21
+ async def {function_name}(callback, options=None):
11
22
  \"""{description}
12
23
 
13
24
  Function ID: {function_id}
14
25
  \"""
26
+ from polyapi.webhook import client, active_handlers
27
+
28
+ print("Starting webhook handler for {function_path}...")
29
+
30
+ if not client:
31
+ raise Exception("Client not initialized. Abort!")
32
+
15
33
  options = options or {{}}
16
34
  eventsClientId = "{client_id}"
17
35
  function_id = "{function_id}"
18
36
 
19
37
  api_key, base_url = get_api_key_and_url()
20
38
 
21
- async def _inner():
22
- socket = socketio.AsyncClient()
23
- await socket.connect(base_url, transports=['websocket'], namespaces=['/events'])
24
-
25
- def registerCallback(registered: bool):
26
- nonlocal socket
27
- if registered:
28
- socket.on('handleWebhookEvent:{function_id}', handleEvent, namespace="/events")
29
- else:
30
- print("Could not set register webhook event handler for {function_id}")
31
-
32
- async def handleEvent(data):
33
- nonlocal api_key
34
- nonlocal options
35
- polyCustom = {{}}
36
- resp = await callback(data.get("body"), data.get("headers"), data.get("params"), polyCustom)
37
- if options.get("waitForResponse"):
38
- await socket.emit('setWebhookListenerResponse', {{
39
- "webhookHandleID": function_id,
40
- "apiKey": api_key,
41
- "clientID": eventsClientId,
42
- "executionId": data.get("executionId"),
43
- "response": {{
44
- "data": resp,
45
- "statusCode": polyCustom.get("responseStatusCode", 200),
46
- "contentType": polyCustom.get("responseContentType", None),
47
- }},
48
- }}, namespace="/events")
49
-
50
- data = {{
51
- "clientID": eventsClientId,
52
- "webhookHandleID": function_id,
53
- "apiKey": api_key,
54
- "waitForResponse": options.get("waitForResponse"),
55
- }}
56
- await socket.emit('registerWebhookEventHandler', data, namespace="/events", callback=registerCallback)
57
-
58
- async def closeEventHandler():
59
- nonlocal socket
60
- if not socket:
61
- return
62
-
63
- await socket.emit('unregisterWebhookEventHandler', {{
64
- "clientID": eventsClientId,
39
+ def registerCallback(registered: bool):
40
+ if registered:
41
+ client.on('handleWebhookEvent:{function_id}', handleEvent, namespace="/events")
42
+ else:
43
+ print("Could not set register webhook event handler for {function_id}")
44
+
45
+ async def handleEvent(data):
46
+ nonlocal api_key
47
+ nonlocal options
48
+ polyCustom = {{}}
49
+ resp = callback(data.get("body"), data.get("headers"), data.get("params"), polyCustom)
50
+ if options.get("waitForResponse"):
51
+ await client.emit('setWebhookListenerResponse', {{
65
52
  "webhookHandleID": function_id,
66
- "apiKey": api_key
53
+ "apiKey": api_key,
54
+ "clientID": eventsClientId,
55
+ "executionId": data.get("executionId"),
56
+ "response": {{
57
+ "data": resp,
58
+ "statusCode": polyCustom.get("responseStatusCode", 200),
59
+ "contentType": polyCustom.get("responseContentType", None),
60
+ }},
67
61
  }}, namespace="/events")
68
62
 
69
- await socket.wait()
63
+ data = {{
64
+ "clientID": eventsClientId,
65
+ "webhookHandleID": function_id,
66
+ "apiKey": api_key,
67
+ "waitForResponse": options.get("waitForResponse"),
68
+ }}
69
+ await client.emit('registerWebhookEventHandler', data, namespace="/events", callback=registerCallback)
70
+ active_handlers.append({{"clientID": eventsClientId, "webhookHandleID": function_id, "apiKey": api_key, "path": "{function_path}"}})
71
+ """
70
72
 
71
- return closeEventHandler
72
73
 
73
- return asyncio.run(_inner())
74
- """
74
+ async def get_client_and_connect():
75
+ _, base_url = get_api_key_and_url()
76
+ global client
77
+ client = socketio.AsyncClient()
78
+ await client.connect(base_url, transports=["websocket"], namespaces=["/events"])
79
+
80
+
81
+ async def unregister(data: Dict[str, Any]):
82
+ print(f"Stopping webhook handler for {data['path']}...")
83
+ assert client
84
+ await client.emit(
85
+ "unregisterWebhookEventHandler",
86
+ {
87
+ "clientID": data["clientID"],
88
+ "webhookHandleID": data["webhookHandleID"],
89
+ "apiKey": data["apiKey"],
90
+ },
91
+ "/events",
92
+ )
93
+
94
+
95
+ async def unregister_all():
96
+ _, base_url = get_api_key_and_url()
97
+ # maybe need to reconnect because maybe socketio client disconnected after Ctrl+C?
98
+ # feels like Linux disconnects but Windows stays connected
99
+ try:
100
+ await client.connect(base_url, transports=["websocket"], namespaces=["/events"])
101
+ except ConnectionError:
102
+ pass
103
+ await asyncio.gather(*[unregister(handler) for handler in active_handlers])
75
104
 
76
105
 
77
106
  def render_webhook_handle(
78
107
  function_type: str,
108
+ function_context: str,
79
109
  function_name: str,
80
110
  function_id: str,
81
111
  function_description: str,
@@ -87,6 +117,21 @@ def render_webhook_handle(
87
117
  client_id=uuid.uuid4().hex,
88
118
  function_id=function_id,
89
119
  function_name=function_name,
120
+ function_path=poly_full_path(function_context, function_name),
90
121
  )
91
122
 
92
- return func_str, ""
123
+ return func_str, ""
124
+
125
+
126
+ def start(*args):
127
+ loop = asyncio.get_event_loop()
128
+ loop.run_until_complete(get_client_and_connect())
129
+ asyncio.gather(*args)
130
+
131
+ try:
132
+ loop.run_forever()
133
+ except KeyboardInterrupt:
134
+ pass
135
+ finally:
136
+ loop.run_until_complete(unregister_all())
137
+ loop.stop()
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyapi-python
3
- Version: 0.2.3.dev9
4
- Summary: The PolyAPI Python Client
3
+ Version: 0.2.4
4
+ Summary: The Python Client for PolyAPI, the IPaaS by Developers for Developers
5
5
  Author-email: Dan Fellin <dan@polyapi.io>
6
6
  License: MIT License
7
7
 
@@ -0,0 +1,25 @@
1
+ polyapi/__init__.py,sha256=5iujRodfgRyLxT-zY0L3xax3rKRvfSt4NZlZYKOz03w,608
2
+ polyapi/__main__.py,sha256=V4zhAh_YGxno5f_KSrlkELxcuDh9bR3WSd0n-2r-qQQ,93
3
+ polyapi/api.py,sha256=Pq_OT8egmtlzMjovN5GGZXWnF5oWMkrgR0rmrzJ6ifM,1861
4
+ polyapi/auth.py,sha256=p2KSLt6q52t9gnqPmgXTOQ2_lmdFilZkIoGmQrRTPLQ,5330
5
+ polyapi/cli.py,sha256=xlKH4cSmSo7eXbyXCLWyL4rXM1QFsltC_MxoxMPgt6I,2187
6
+ polyapi/client.py,sha256=w15XOABkwdL4V4r2iWY_nypzLjvoKVuux8jUKbA16pQ,1329
7
+ polyapi/config.py,sha256=S8TU10upy5OW1_vX-CqQTJD-ZOB6329aMjiUCmukfUI,2292
8
+ polyapi/constants.py,sha256=NGjso6K5rGnE8TGdrXmdEfvvr-HI3DTVGwOYiWO68LM,511
9
+ polyapi/error_handler.py,sha256=I_e0iz6VM23FLVQWJljxs2NGcl_OODbi43OcbnqBlp8,2398
10
+ polyapi/exceptions.py,sha256=Zh7i7eCUhDuXEdUYjatkLFTeZkrx1BJ1P5ePgbJ9eIY,89
11
+ polyapi/execute.py,sha256=kXnvlNQ7nz9cRlV2_5gXH09UCmyiDP5zi3wiAw0uDuk,1943
12
+ polyapi/function_cli.py,sha256=F0cb5MGcmFvspgwxptWq_2e50X5NNno0B0p8Vgu_oNI,9129
13
+ polyapi/generate.py,sha256=fNEBy3ALEu4m1GEEcly-5u-Y1i3G6EWMKKgCyBBJsqc,8568
14
+ polyapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ polyapi/schema.py,sha256=1a7nIO867Xy3bagmPUNdYMxtS5OoCAv8oKIbYgj55dk,2957
16
+ polyapi/server.py,sha256=iXUR1Kd5TnWK-V5qHhvFvQuHx-3IcTv8WChXVY5Mbog,1882
17
+ polyapi/typedefs.py,sha256=a5WfHaAvjeql3y1iA3_SkpUztTbKvS5bPqkVxkCvr9E,1459
18
+ polyapi/utils.py,sha256=9dFboLurZwBBtFZxXBDNri4QvSJAyZhkNUWK5LZh6ME,6180
19
+ polyapi/variables.py,sha256=d36-trnfTL_8m2NkorMiImb4O3UrJbiFV38CHxV5i0A,4200
20
+ polyapi/webhook.py,sha256=KidW6J1R4pWsgJ9duPiG-kzO8S28zfVyPhSn8ypD30Y,4325
21
+ polyapi_python-0.2.4.dist-info/LICENSE,sha256=Hi0kDr56Dsy0uYIwNt4r9G7tI8x8miXRTlyvbeplCP8,1068
22
+ polyapi_python-0.2.4.dist-info/METADATA,sha256=kKKRqtXYD-PhlLUa0GZoAXACMsUsOtq3gcMsZuOcrjM,4862
23
+ polyapi_python-0.2.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
24
+ polyapi_python-0.2.4.dist-info/top_level.txt,sha256=CEFllOnzowci_50RYJac-M54KD2IdAptFsayVVF_f04,8
25
+ polyapi_python-0.2.4.dist-info/RECORD,,
@@ -1,25 +0,0 @@
1
- polyapi/__init__.py,sha256=VRAaN5WZPDmj7AnprtJ3szHXWlqWInKXBfEmfpyXTK8,434
2
- polyapi/__main__.py,sha256=V4zhAh_YGxno5f_KSrlkELxcuDh9bR3WSd0n-2r-qQQ,93
3
- polyapi/api.py,sha256=Pq_OT8egmtlzMjovN5GGZXWnF5oWMkrgR0rmrzJ6ifM,1861
4
- polyapi/auth.py,sha256=p2KSLt6q52t9gnqPmgXTOQ2_lmdFilZkIoGmQrRTPLQ,5330
5
- polyapi/cli.py,sha256=xlKH4cSmSo7eXbyXCLWyL4rXM1QFsltC_MxoxMPgt6I,2187
6
- polyapi/client.py,sha256=8k50Vwg9HnmHHTyfKH1vfMJqF0jnnVMsWuWI9AfASkM,761
7
- polyapi/config.py,sha256=S8TU10upy5OW1_vX-CqQTJD-ZOB6329aMjiUCmukfUI,2292
8
- polyapi/constants.py,sha256=NGjso6K5rGnE8TGdrXmdEfvvr-HI3DTVGwOYiWO68LM,511
9
- polyapi/error_handler.py,sha256=vl6ZBtsHmC3eu13IMpmZEXBTDJbrPrzmViBCCrEspd4,1621
10
- polyapi/exceptions.py,sha256=Zh7i7eCUhDuXEdUYjatkLFTeZkrx1BJ1P5ePgbJ9eIY,89
11
- polyapi/execute.py,sha256=06XWTxGJqtsDiLY10RjRebIMFRfhtAIMmBRbuWu3e8A,1873
12
- polyapi/function_cli.py,sha256=KkFvnGSSCwYPMV4cX4yMQmXKyLtgYR64Fz5BfjGv3qY,8230
13
- polyapi/generate.py,sha256=O1lb7rLsce7tItIrMx1EbWzRlAKKOp-7upNM80cMmMw,8499
14
- polyapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- polyapi/schema.py,sha256=1a7nIO867Xy3bagmPUNdYMxtS5OoCAv8oKIbYgj55dk,2957
16
- polyapi/server.py,sha256=mcbH8pG16fFMiFL52wdii0217ZLsznQnElAFEvXZ7IA,2211
17
- polyapi/typedefs.py,sha256=a5WfHaAvjeql3y1iA3_SkpUztTbKvS5bPqkVxkCvr9E,1459
18
- polyapi/utils.py,sha256=UD3uV3kzt2w23zxAdHCUROhdvtdO44KCJIpqnFwEhqE,5937
19
- polyapi/variables.py,sha256=d36-trnfTL_8m2NkorMiImb4O3UrJbiFV38CHxV5i0A,4200
20
- polyapi/webhook.py,sha256=A89eNnYcVpVe9doJPDLfscIhF-C7Q2AI3vu-SzGxMBg,2923
21
- polyapi_python-0.2.3.dev9.dist-info/LICENSE,sha256=Hi0kDr56Dsy0uYIwNt4r9G7tI8x8miXRTlyvbeplCP8,1068
22
- polyapi_python-0.2.3.dev9.dist-info/METADATA,sha256=3pEducW3Aaun4Vy6JgbJ1SksuPLLbWSMXAlYPyg--4A,4823
23
- polyapi_python-0.2.3.dev9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
24
- polyapi_python-0.2.3.dev9.dist-info/top_level.txt,sha256=CEFllOnzowci_50RYJac-M54KD2IdAptFsayVVF_f04,8
25
- polyapi_python-0.2.3.dev9.dist-info/RECORD,,