polyapi-python 0.1.0.dev14__tar.gz → 0.1.1__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.1.0.dev14/polyapi_python.egg-info → polyapi-python-0.1.1}/PKG-INFO +3 -1
- polyapi-python-0.1.1/polyapi/auth.py +153 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/generate.py +3 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/utils.py +1 -1
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1/polyapi_python.egg-info}/PKG-INFO +3 -1
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi_python.egg-info/requires.txt +2 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/pyproject.toml +2 -2
- polyapi-python-0.1.0.dev14/polyapi/auth.py +0 -80
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/LICENSE +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/README.md +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/__init__.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/__main__.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/api.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/cli.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/config.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/constants.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/exceptions.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/execute.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/function_cli.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/py.typed +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/schema.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/server.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/typedefs.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi/variables.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi_python.egg-info/SOURCES.txt +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi_python.egg-info/dependency_links.txt +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/polyapi_python.egg-info/top_level.txt +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/setup.cfg +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/tests/test_api.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/tests/test_auth.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/tests/test_function_cli.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/tests/test_server.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/tests/test_utils.py +0 -0
- {polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/tests/test_variables.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: polyapi-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: The PolyAPI Python Client
|
|
5
5
|
Author-email: Dan Fellin <dan@polyapi.io>
|
|
6
6
|
License: MIT License
|
|
@@ -34,6 +34,8 @@ Requires-Dist: jsonschema-gentypes
|
|
|
34
34
|
Requires-Dist: pydantic>=2.5.3
|
|
35
35
|
Requires-Dist: stdlib_list
|
|
36
36
|
Requires-Dist: colorama
|
|
37
|
+
Requires-Dist: python-socketio[asyncio_client]
|
|
38
|
+
Requires-Dist: truststore
|
|
37
39
|
|
|
38
40
|
# PolyAPI Python Library
|
|
39
41
|
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
from typing import List, Dict, Any, Tuple
|
|
2
|
+
import uuid
|
|
3
|
+
|
|
4
|
+
from polyapi.typedefs import PropertySpecification
|
|
5
|
+
from polyapi.utils import parse_arguments, get_type_and_def
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
AUTH_DEFS_TEMPLATE = """
|
|
9
|
+
from typing import List, Dict, Any, TypedDict, Optional
|
|
10
|
+
{args_def}
|
|
11
|
+
{return_type_def}
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
GET_TOKEN_TEMPLATE = """
|
|
15
|
+
import asyncio
|
|
16
|
+
import socketio # type: ignore
|
|
17
|
+
import truststore
|
|
18
|
+
truststore.inject_into_ssl()
|
|
19
|
+
from polyapi.config import get_api_key_and_url
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def getToken(clientId: str, clientSecret: str, scopes: List[str], callback, options: Optional[Dict[str, Any]] = None):
|
|
23
|
+
{description}
|
|
24
|
+
eventsClientId = "{client_id}"
|
|
25
|
+
function_id = "{function_id}"
|
|
26
|
+
|
|
27
|
+
options = options or {{}}
|
|
28
|
+
path = "/auth-providers/{function_id}/execute"
|
|
29
|
+
data = {{
|
|
30
|
+
"clientId": clientId,
|
|
31
|
+
"clientSecret": clientSecret,
|
|
32
|
+
"scopes": scopes,
|
|
33
|
+
"audience": options.get("audience"),
|
|
34
|
+
"callbackUrl": options.get("callbackUrl"),
|
|
35
|
+
"userId": options.get("userId"),
|
|
36
|
+
}}
|
|
37
|
+
resp = execute_post(path, data)
|
|
38
|
+
data = resp.json()
|
|
39
|
+
assert resp.status_code == 201, (resp.status_code, resp.content)
|
|
40
|
+
|
|
41
|
+
token = data.get("token")
|
|
42
|
+
url = data.get("url")
|
|
43
|
+
error = data.get("error")
|
|
44
|
+
if token:
|
|
45
|
+
return callback(token, url, error)
|
|
46
|
+
elif url and options.get("autoCloseOnUrl"):
|
|
47
|
+
return callback(token, url, error)
|
|
48
|
+
|
|
49
|
+
timeout = options.get("timeout", 120)
|
|
50
|
+
|
|
51
|
+
api_key, base_url = get_api_key_and_url()
|
|
52
|
+
socket = socketio.AsyncClient()
|
|
53
|
+
await socket.connect(base_url, transports=['websocket'], namespaces=['/events'])
|
|
54
|
+
|
|
55
|
+
async def closeEventHandler():
|
|
56
|
+
nonlocal socket
|
|
57
|
+
if not socket:
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
del socket.handlers['/events']['handleAuthFunctionEvent:{function_id}']
|
|
61
|
+
await socket.emit('unregisterAuthFunctionEventHandler', {{
|
|
62
|
+
"clientID": eventsClientId,
|
|
63
|
+
"functionId": function_id,
|
|
64
|
+
"apiKey": api_key
|
|
65
|
+
}}, namespace="/events")
|
|
66
|
+
await socket.disconnect()
|
|
67
|
+
socket = None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
async def waitUntilTimeout(timeout):
|
|
71
|
+
await asyncio.sleep(timeout)
|
|
72
|
+
await closeEventHandler()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
async def handleEvent(data):
|
|
76
|
+
nonlocal options
|
|
77
|
+
callback(data.get('token'), data.get('url'), data.get('error'))
|
|
78
|
+
if data.get('token') and options.get("autoCloseOnToken", True):
|
|
79
|
+
await closeEventHandler()
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def registerCallback(registered: bool):
|
|
83
|
+
nonlocal socket
|
|
84
|
+
if registered:
|
|
85
|
+
socket.on('handleAuthFunctionEvent:{function_id}', handleEvent, namespace="/events")
|
|
86
|
+
callback(data.get('token'), data.get('url'), data.get('error'))
|
|
87
|
+
|
|
88
|
+
data2 = {{
|
|
89
|
+
"clientID": eventsClientId,
|
|
90
|
+
"functionId": function_id,
|
|
91
|
+
"apiKey": api_key
|
|
92
|
+
}}
|
|
93
|
+
await socket.emit('registerAuthFunctionEventHandler', data2, namespace="/events", callback=registerCallback)
|
|
94
|
+
|
|
95
|
+
# run timeout task in background
|
|
96
|
+
timeout = options.get("timeout", 120)
|
|
97
|
+
timeout_task = asyncio.create_task(waitUntilTimeout(timeout))
|
|
98
|
+
|
|
99
|
+
# cancel timeout task if socket.wait finishes before timeout up
|
|
100
|
+
await socket.wait()
|
|
101
|
+
timeout_task.cancel()
|
|
102
|
+
|
|
103
|
+
return {{"close": closeEventHandler}}
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
REFRESH_TOKEN_TEMPLATE = """
|
|
107
|
+
def refreshToken(token: str) -> str:
|
|
108
|
+
{description}
|
|
109
|
+
url = "/auth-providers/{function_id}/refresh"
|
|
110
|
+
resp = execute_post(url, {{"token": token}})
|
|
111
|
+
assert resp.status_code == 201, (resp.status_code, resp.content)
|
|
112
|
+
return resp.text
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
REVOKE_TOKEN_TEMPLATE = """
|
|
116
|
+
def revokeToken(token: str) -> None:
|
|
117
|
+
{description}
|
|
118
|
+
url = "/auth-providers/{function_id}/revoke"
|
|
119
|
+
resp = execute_post(url, {{"token": token}})
|
|
120
|
+
assert resp.status_code == 201, (resp.status_code, resp.content)
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def render_auth_function(
|
|
125
|
+
function_type: str,
|
|
126
|
+
function_name: str,
|
|
127
|
+
function_id: str,
|
|
128
|
+
function_description: str,
|
|
129
|
+
arguments: List[PropertySpecification],
|
|
130
|
+
return_type: Dict[str, Any],
|
|
131
|
+
) -> Tuple[str, str]:
|
|
132
|
+
""" renders getToken, revokeToken, refreshToken as appropriate
|
|
133
|
+
"""
|
|
134
|
+
args, args_def = parse_arguments(function_name, arguments)
|
|
135
|
+
return_type_name, return_type_def = get_type_and_def(return_type) # type: ignore
|
|
136
|
+
func_type_defs = AUTH_DEFS_TEMPLATE.format(
|
|
137
|
+
args_def=args_def,
|
|
138
|
+
return_type_def=return_type_def,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
func_str = ""
|
|
142
|
+
|
|
143
|
+
if function_description:
|
|
144
|
+
function_description = f'"""{function_description}"""'
|
|
145
|
+
|
|
146
|
+
if function_name == "getToken":
|
|
147
|
+
func_str = GET_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description, client_id=uuid.uuid4().hex)
|
|
148
|
+
elif function_name == "refreshToken":
|
|
149
|
+
func_str = REFRESH_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description)
|
|
150
|
+
elif function_name == "revokeToken":
|
|
151
|
+
func_str = REVOKE_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description)
|
|
152
|
+
|
|
153
|
+
return func_str, func_type_defs
|
|
@@ -9,7 +9,7 @@ from polyapi.schema import generate_schema_types, clean_title, map_primitive_typ
|
|
|
9
9
|
|
|
10
10
|
# this string should be in every __init__ file.
|
|
11
11
|
# it contains all the imports needed for the function or variable code to run
|
|
12
|
-
CODE_IMPORTS = "from typing import List, Dict, Any, TypedDict\nimport requests\nfrom polyapi.execute import execute, execute_post, variable_get, variable_update\n\n"
|
|
12
|
+
CODE_IMPORTS = "from typing import List, Dict, Any, TypedDict, Optional\nimport requests\nfrom polyapi.execute import execute, execute_post, variable_get, variable_update\n\n"
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def init_the_init(full_path: str) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: polyapi-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: The PolyAPI Python Client
|
|
5
5
|
Author-email: Dan Fellin <dan@polyapi.io>
|
|
6
6
|
License: MIT License
|
|
@@ -34,6 +34,8 @@ Requires-Dist: jsonschema-gentypes
|
|
|
34
34
|
Requires-Dist: pydantic>=2.5.3
|
|
35
35
|
Requires-Dist: stdlib_list
|
|
36
36
|
Requires-Dist: colorama
|
|
37
|
+
Requires-Dist: python-socketio[asyncio_client]
|
|
38
|
+
Requires-Dist: truststore
|
|
37
39
|
|
|
38
40
|
# PolyAPI Python Library
|
|
39
41
|
|
|
@@ -3,10 +3,10 @@ requires = ["setuptools>=61.2", "wheel"]
|
|
|
3
3
|
|
|
4
4
|
[project]
|
|
5
5
|
name = "polyapi-python"
|
|
6
|
-
version = "0.1.
|
|
6
|
+
version = "0.1.1"
|
|
7
7
|
description = "The PolyAPI Python Client"
|
|
8
8
|
authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }]
|
|
9
|
-
dependencies = ["requests", "typing_extensions", "jsonschema-gentypes", "pydantic>=2.5.3", "stdlib_list", "colorama"]
|
|
9
|
+
dependencies = ["requests", "typing_extensions", "jsonschema-gentypes", "pydantic>=2.5.3", "stdlib_list", "colorama", "python-socketio[asyncio_client]", "truststore"]
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
license = { file = "LICENSE" }
|
|
12
12
|
requires-python = ">=3.10"
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
from typing import List, Dict, Any, Tuple
|
|
2
|
-
|
|
3
|
-
from polyapi.typedefs import PropertySpecification
|
|
4
|
-
from polyapi.utils import parse_arguments, get_type_and_def
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
AUTH_DEFS_TEMPLATE = """
|
|
8
|
-
from typing import List, Dict, Any, TypedDict
|
|
9
|
-
{args_def}
|
|
10
|
-
{return_type_def}
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
GET_TOKEN_TEMPLATE = """
|
|
14
|
-
def getToken(clientId: str, clientSecret: str, scopes: List[str], callback, options: Dict[str, Any] = None):
|
|
15
|
-
{description}
|
|
16
|
-
# TODO timeout, autoCloseOnUrl, autoCloseOnToken
|
|
17
|
-
options = options or {{}}
|
|
18
|
-
url = "/auth-providers/{function_id}/execute"
|
|
19
|
-
data = {{
|
|
20
|
-
"clientId": clientId,
|
|
21
|
-
"clientSecret": clientSecret,
|
|
22
|
-
"scopes": scopes,
|
|
23
|
-
"audience": options.get("audience"),
|
|
24
|
-
"callbackUrl": options.get("callbackUrl"),
|
|
25
|
-
"userId": options.get("userId"),
|
|
26
|
-
}}
|
|
27
|
-
resp = execute_post(url, data)
|
|
28
|
-
data = resp.json()
|
|
29
|
-
assert resp.status_code == 201, (resp.status_code, resp.content)
|
|
30
|
-
return callback(data.get("token"), data.get("url"), data.get("error"))
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
REFRESH_TOKEN_TEMPLATE = """
|
|
34
|
-
def refreshToken(token: str) -> str:
|
|
35
|
-
{description}
|
|
36
|
-
url = "/auth-providers/{function_id}/refresh"
|
|
37
|
-
resp = execute_post(url, {{"token": token}})
|
|
38
|
-
assert resp.status_code == 201, (resp.status_code, resp.content)
|
|
39
|
-
return resp.text
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
REVOKE_TOKEN_TEMPLATE = """
|
|
43
|
-
def revokeToken(token: str) -> None:
|
|
44
|
-
{description}
|
|
45
|
-
url = "/auth-providers/{function_id}/revoke"
|
|
46
|
-
resp = execute_post(url, {{"token": token}})
|
|
47
|
-
assert resp.status_code == 201, (resp.status_code, resp.content)
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def render_auth_function(
|
|
52
|
-
function_type: str,
|
|
53
|
-
function_name: str,
|
|
54
|
-
function_id: str,
|
|
55
|
-
function_description: str,
|
|
56
|
-
arguments: List[PropertySpecification],
|
|
57
|
-
return_type: Dict[str, Any],
|
|
58
|
-
) -> Tuple[str, str]:
|
|
59
|
-
""" renders getToken, revokeToken, refreshToken as appropriate
|
|
60
|
-
"""
|
|
61
|
-
args, args_def = parse_arguments(function_name, arguments)
|
|
62
|
-
return_type_name, return_type_def = get_type_and_def(return_type) # type: ignore
|
|
63
|
-
func_type_defs = AUTH_DEFS_TEMPLATE.format(
|
|
64
|
-
args_def=args_def,
|
|
65
|
-
return_type_def=return_type_def,
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
func_str = ""
|
|
69
|
-
|
|
70
|
-
if function_description:
|
|
71
|
-
function_description = f'"""{function_description}"""'
|
|
72
|
-
|
|
73
|
-
if function_name == "getToken":
|
|
74
|
-
func_str = GET_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description)
|
|
75
|
-
elif function_name == "refreshToken":
|
|
76
|
-
func_str = REFRESH_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description)
|
|
77
|
-
elif function_name == "revokeToken":
|
|
78
|
-
func_str = REVOKE_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description)
|
|
79
|
-
|
|
80
|
-
return func_str, func_type_defs
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyapi-python-0.1.0.dev14 → polyapi-python-0.1.1}/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
|
|
File without changes
|
|
File without changes
|