polyapi-python 0.2.4.dev3__tar.gz → 0.2.4.dev4__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 (38) hide show
  1. {polyapi_python-0.2.4.dev3/polyapi_python.egg-info → polyapi_python-0.2.4.dev4}/PKG-INFO +2 -2
  2. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/error_handler.py +4 -1
  3. polyapi_python-0.2.4.dev4/polyapi/webhook.py +129 -0
  4. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4/polyapi_python.egg-info}/PKG-INFO +2 -2
  5. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/pyproject.toml +2 -2
  6. polyapi_python-0.2.4.dev3/polyapi/webhook.py +0 -92
  7. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/LICENSE +0 -0
  8. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/README.md +0 -0
  9. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/__init__.py +0 -0
  10. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/__main__.py +0 -0
  11. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/api.py +0 -0
  12. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/auth.py +0 -0
  13. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/cli.py +0 -0
  14. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/client.py +0 -0
  15. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/config.py +0 -0
  16. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/constants.py +0 -0
  17. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/exceptions.py +0 -0
  18. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/execute.py +0 -0
  19. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/function_cli.py +0 -0
  20. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/generate.py +0 -0
  21. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/poly_custom.py +0 -0
  22. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/py.typed +0 -0
  23. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/schema.py +0 -0
  24. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/server.py +0 -0
  25. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/typedefs.py +0 -0
  26. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/utils.py +0 -0
  27. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi/variables.py +0 -0
  28. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi_python.egg-info/SOURCES.txt +0 -0
  29. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi_python.egg-info/dependency_links.txt +0 -0
  30. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi_python.egg-info/requires.txt +0 -0
  31. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/polyapi_python.egg-info/top_level.txt +0 -0
  32. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/setup.cfg +0 -0
  33. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/tests/test_api.py +0 -0
  34. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/tests/test_auth.py +0 -0
  35. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/tests/test_function_cli.py +0 -0
  36. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/tests/test_server.py +0 -0
  37. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/tests/test_utils.py +0 -0
  38. {polyapi_python-0.2.4.dev3 → polyapi_python-0.2.4.dev4}/tests/test_variables.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyapi-python
3
- Version: 0.2.4.dev3
4
- Summary: The PolyAPI Python Client
3
+ Version: 0.2.4.dev4
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
 
@@ -6,7 +6,10 @@ from typing import Any, Callable, Dict, List, Optional
6
6
  from polyapi.config import get_api_key_and_url
7
7
 
8
8
 
9
+ # all active webhook handlers, used by unregister_all to cleanup
9
10
  active_handlers: List[Dict[str, Any]] = []
11
+
12
+ # global client shared by all error handlers, will be initialized by webhook.start
10
13
  client = None
11
14
 
12
15
 
@@ -47,7 +50,7 @@ async def on(
47
50
  print(f"starting error handler for {path}...")
48
51
 
49
52
  if not client:
50
- raise Exception("Client not initialized. Please call error_handler.prepare() first.")
53
+ raise Exception("Client not initialized. Abort!")
51
54
 
52
55
  api_key, _ = get_api_key_and_url()
53
56
  handler_id = None
@@ -0,0 +1,129 @@
1
+ import asyncio
2
+ import socketio # type: ignore
3
+ import uuid
4
+ from typing import Any, Dict, List, Tuple
5
+
6
+ from polyapi.config import get_api_key_and_url
7
+ from polyapi.typedefs import PropertySpecification
8
+
9
+ # all active webhook handlers, used by unregister_all to cleanup
10
+ active_handlers: List[Dict[str, Any]] = []
11
+
12
+ # global client shared by all webhooks, will be initialized by webhook.start
13
+ client = None
14
+
15
+
16
+ WEBHOOK_TEMPLATE = """
17
+
18
+
19
+ async def {function_name}(callback, options=None):
20
+ \"""{description}
21
+
22
+ Function ID: {function_id}
23
+ \"""
24
+ from polyapi.webhook import client, active_handlers
25
+
26
+ print("Starting webhook for {function_name}...")
27
+
28
+ if not client:
29
+ raise Exception("Client not initialized. Abort!")
30
+
31
+ options = options or {{}}
32
+ eventsClientId = "{client_id}"
33
+ function_id = "{function_id}"
34
+
35
+ api_key, base_url = get_api_key_and_url()
36
+
37
+ def registerCallback(registered: bool):
38
+ if registered:
39
+ client.on('handleWebhookEvent:{function_id}', handleEvent, namespace="/events")
40
+ else:
41
+ print("Could not set register webhook event handler for {function_id}")
42
+
43
+ async def handleEvent(data):
44
+ nonlocal api_key
45
+ nonlocal options
46
+ polyCustom = {{}}
47
+ resp = callback(data.get("body"), data.get("headers"), data.get("params"), polyCustom)
48
+ if options.get("waitForResponse"):
49
+ await client.emit('setWebhookListenerResponse', {{
50
+ "webhookHandleID": function_id,
51
+ "apiKey": api_key,
52
+ "clientID": eventsClientId,
53
+ "executionId": data.get("executionId"),
54
+ "response": {{
55
+ "data": resp,
56
+ "statusCode": polyCustom.get("responseStatusCode", 200),
57
+ "contentType": polyCustom.get("responseContentType", None),
58
+ }},
59
+ }}, namespace="/events")
60
+
61
+ data = {{
62
+ "clientID": eventsClientId,
63
+ "webhookHandleID": function_id,
64
+ "apiKey": api_key,
65
+ "waitForResponse": options.get("waitForResponse"),
66
+ }}
67
+ await client.emit('registerWebhookEventHandler', data, namespace="/events", callback=registerCallback)
68
+ active_handlers.append({{"clientID": eventsClientId, "webhookHandleID": function_id, "apiKey": api_key}})
69
+ """
70
+
71
+
72
+ async def get_client_and_connect():
73
+ _, base_url = get_api_key_and_url()
74
+ global client
75
+ client = socketio.AsyncClient()
76
+ await client.connect(base_url, transports=["websocket"], namespaces=["/events"])
77
+
78
+
79
+ async def unregister(data: Dict[str, Any]):
80
+ print(f"stopping error handler for '{data['webhookHandleID']}'...")
81
+ assert client
82
+ await client.emit(
83
+ "unregisterWebhookEventHandler",
84
+ {
85
+ "clientID": data["clientID"],
86
+ "webhookHandleID": data["webhookHandleID"],
87
+ "apiKey": data["apiKey"],
88
+ },
89
+ "/events",
90
+ )
91
+
92
+
93
+ async def unregister_all():
94
+ _, base_url = get_api_key_and_url()
95
+ # need to reconnect because maybe socketio client disconnected after Ctrl+C?
96
+ await client.connect(base_url, transports=["websocket"], namespaces=["/events"])
97
+ await asyncio.gather(*[unregister(handler) for handler in active_handlers])
98
+
99
+
100
+ def render_webhook_handle(
101
+ function_type: str,
102
+ function_name: str,
103
+ function_id: str,
104
+ function_description: str,
105
+ arguments: List[PropertySpecification],
106
+ return_type: Dict[str, Any],
107
+ ) -> Tuple[str, str]:
108
+ func_str = WEBHOOK_TEMPLATE.format(
109
+ description=function_description,
110
+ client_id=uuid.uuid4().hex,
111
+ function_id=function_id,
112
+ function_name=function_name,
113
+ )
114
+
115
+ return func_str, ""
116
+
117
+
118
+ def start(*args):
119
+ loop = asyncio.get_event_loop()
120
+ loop.run_until_complete(get_client_and_connect())
121
+ asyncio.gather(*args)
122
+
123
+ try:
124
+ loop.run_forever()
125
+ except KeyboardInterrupt:
126
+ pass
127
+ finally:
128
+ loop.run_until_complete(unregister_all())
129
+ loop.stop()
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyapi-python
3
- Version: 0.2.4.dev3
4
- Summary: The PolyAPI Python Client
3
+ Version: 0.2.4.dev4
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
 
@@ -3,8 +3,8 @@ requires = ["setuptools>=61.2", "wheel"]
3
3
 
4
4
  [project]
5
5
  name = "polyapi-python"
6
- version = "0.2.4.dev3"
7
- description = "The PolyAPI Python Client"
6
+ version = "0.2.4.dev4"
7
+ description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers"
8
8
  authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }]
9
9
  dependencies = [
10
10
  "requests==2.31.0",
@@ -1,92 +0,0 @@
1
- import uuid
2
- from typing import Any, Dict, List, Tuple
3
-
4
- from polyapi.typedefs import PropertySpecification
5
-
6
- WEBHOOK_TEMPLATE = """
7
- import asyncio
8
-
9
-
10
- def {function_name}(callback, options=None):
11
- \"""{description}
12
-
13
- Function ID: {function_id}
14
- \"""
15
- options = options or {{}}
16
- eventsClientId = "{client_id}"
17
- function_id = "{function_id}"
18
-
19
- api_key, base_url = get_api_key_and_url()
20
-
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,
65
- "webhookHandleID": function_id,
66
- "apiKey": api_key
67
- }}, namespace="/events")
68
-
69
- await socket.wait()
70
-
71
- return closeEventHandler
72
-
73
- return asyncio.run(_inner())
74
- """
75
-
76
-
77
- def render_webhook_handle(
78
- function_type: str,
79
- function_name: str,
80
- function_id: str,
81
- function_description: str,
82
- arguments: List[PropertySpecification],
83
- return_type: Dict[str, Any],
84
- ) -> Tuple[str, str]:
85
- func_str = WEBHOOK_TEMPLATE.format(
86
- description=function_description,
87
- client_id=uuid.uuid4().hex,
88
- function_id=function_id,
89
- function_name=function_name,
90
- )
91
-
92
- return func_str, ""