polyapi-python 0.3.9.dev15__tar.gz → 0.3.10__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.3.9.dev15 → polyapi_python-0.3.10}/PKG-INFO +1 -1
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/cli.py +6 -1
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/function_cli.py +2 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/generate.py +3 -3
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/parser.py +6 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/poly_tables.py +16 -1
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/utils.py +2 -2
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi_python.egg-info/PKG-INFO +1 -1
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/pyproject.toml +1 -1
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_tabi.py +3 -9
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/LICENSE +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/README.md +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/__init__.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/__main__.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/api.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/auth.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/client.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/config.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/constants.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/deployables.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/error_handler.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/exceptions.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/execute.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/poly_schemas.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/prepare.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/py.typed +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/rendered_spec.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/schema.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/server.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/sync.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/typedefs.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/variables.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi/webhook.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi_python.egg-info/SOURCES.txt +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi_python.egg-info/dependency_links.txt +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi_python.egg-info/requires.txt +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/polyapi_python.egg-info/top_level.txt +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/setup.cfg +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_api.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_auth.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_deployables.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_generate.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_parser.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_rendered_spec.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_schema.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_server.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_utils.py +0 -0
- {polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/tests/test_variables.py +0 -0
|
@@ -113,11 +113,13 @@ def execute_from_cli():
|
|
|
113
113
|
fn_add_parser.add_argument("--execution-api-key", required=False, default="", help="API key for execution (for server functions only).")
|
|
114
114
|
fn_add_parser.add_argument("--disable-ai", "--skip-generate", action="store_true", help="Pass --disable-ai skip AI generation of missing descriptions")
|
|
115
115
|
fn_add_parser.add_argument("--generate-contexts", type=str, help="Server function only – only include certain contexts to speed up function execution")
|
|
116
|
+
fn_add_parser.add_argument("--visibility", type=str, default="environment", help="Specifies the visibility of a function. Options: PUBLIC, TENANT, ENVIRONMENT. Case insensitive")
|
|
116
117
|
|
|
117
118
|
def add_function(args):
|
|
118
119
|
initialize_config()
|
|
119
120
|
logs_enabled = args.logs == "enabled" if args.logs else None
|
|
120
121
|
err = ""
|
|
122
|
+
visibility = args.visibility.upper()
|
|
121
123
|
if args.server and args.client:
|
|
122
124
|
err = "Specify either `--server` or `--client`. Found both."
|
|
123
125
|
elif not args.server and not args.client:
|
|
@@ -126,6 +128,8 @@ def execute_from_cli():
|
|
|
126
128
|
err = "Option `logs` is only for server functions (--server)."
|
|
127
129
|
elif args.generate_contexts and not args.server:
|
|
128
130
|
err = "Option `generate-contexts` is only for server functions (--server)."
|
|
131
|
+
elif visibility not in ["PUBLIC", "TENANT", "ENVIRONMENT"]:
|
|
132
|
+
err = "Invalid visiblity argument, visibility must be one of ['PUBLIC', 'TENANT', 'ENVIRONMENT']"
|
|
129
133
|
|
|
130
134
|
if err:
|
|
131
135
|
print_red("ERROR")
|
|
@@ -142,7 +146,8 @@ def execute_from_cli():
|
|
|
142
146
|
logs_enabled=logs_enabled,
|
|
143
147
|
generate=not args.disable_ai,
|
|
144
148
|
execution_api_key=args.execution_api_key,
|
|
145
|
-
generate_contexts=args.generate_contexts
|
|
149
|
+
generate_contexts=args.generate_contexts,
|
|
150
|
+
visibility=visibility
|
|
146
151
|
)
|
|
147
152
|
|
|
148
153
|
fn_add_parser.set_defaults(command=add_function)
|
|
@@ -25,6 +25,7 @@ def function_add_or_update(
|
|
|
25
25
|
server: bool,
|
|
26
26
|
logs_enabled: Optional[bool],
|
|
27
27
|
generate_contexts: Optional[str],
|
|
28
|
+
visibility: Optional[str],
|
|
28
29
|
generate: bool = True,
|
|
29
30
|
execution_api_key: str = ""
|
|
30
31
|
):
|
|
@@ -55,6 +56,7 @@ def function_add_or_update(
|
|
|
55
56
|
"description": description or parsed["types"]["description"],
|
|
56
57
|
"code": code,
|
|
57
58
|
"language": "python",
|
|
59
|
+
"visibility": visibility or "ENVIRONMENT",
|
|
58
60
|
"returnType": get_jsonschema_type(return_type),
|
|
59
61
|
"arguments": [{**p, "key": p["name"], "type": get_jsonschema_type(p["type"])} for p in parsed["types"]["params"]],
|
|
60
62
|
"logsEnabled": logs_enabled,
|
|
@@ -503,7 +503,7 @@ def add_function_file(
|
|
|
503
503
|
# Read current __init__.py content if it exists
|
|
504
504
|
init_content = ""
|
|
505
505
|
if os.path.exists(init_path):
|
|
506
|
-
with open(init_path, "r") as f:
|
|
506
|
+
with open(init_path, "r", encoding='utf-8') as f:
|
|
507
507
|
init_content = f.read()
|
|
508
508
|
|
|
509
509
|
# Prepare new content to append to __init__.py
|
|
@@ -511,12 +511,12 @@ def add_function_file(
|
|
|
511
511
|
|
|
512
512
|
# Use temporary files for atomic writes
|
|
513
513
|
# Write to __init__.py atomically
|
|
514
|
-
with tempfile.NamedTemporaryFile(mode="w", delete=False, dir=full_path, suffix=".tmp") as temp_init:
|
|
514
|
+
with tempfile.NamedTemporaryFile(mode="w", delete=False, dir=full_path, suffix=".tmp", encoding='utf-8') as temp_init:
|
|
515
515
|
temp_init.write(new_init_content)
|
|
516
516
|
temp_init_path = temp_init.name
|
|
517
517
|
|
|
518
518
|
# Write to function file atomically
|
|
519
|
-
with tempfile.NamedTemporaryFile(mode="w", delete=False, dir=full_path, suffix=".tmp") as temp_func:
|
|
519
|
+
with tempfile.NamedTemporaryFile(mode="w", delete=False, dir=full_path, suffix=".tmp", encoding='utf-8') as temp_func:
|
|
520
520
|
temp_func.write(func_type_defs)
|
|
521
521
|
temp_func_path = temp_func.name
|
|
522
522
|
|
|
@@ -464,6 +464,12 @@ def parse_function_code(code: str, name: Optional[str] = "", context: Optional[s
|
|
|
464
464
|
if node.name == self._name:
|
|
465
465
|
# Parse docstring which may contain param types and descriptions
|
|
466
466
|
self._extract_docstring_from_function(node)
|
|
467
|
+
|
|
468
|
+
if node.args.kwonlyargs:
|
|
469
|
+
print_red("ERROR")
|
|
470
|
+
print("Function signature has keyword-only arguments (after `*`). Please use only positional arguments.")
|
|
471
|
+
sys.exit(1)
|
|
472
|
+
|
|
467
473
|
function_args = [arg for arg in node.args.args]
|
|
468
474
|
docstring_params = deployable["types"]["params"]
|
|
469
475
|
parsed_params = []
|
|
@@ -6,6 +6,21 @@ from polyapi.utils import add_import_to_init, init_the_init
|
|
|
6
6
|
from polyapi.typedefs import TableSpecDto
|
|
7
7
|
from polyapi.constants import JSONSCHEMA_TO_PYTHON_TYPE_MAP
|
|
8
8
|
|
|
9
|
+
def scrub(data) -> Dict[str, Any]:
|
|
10
|
+
if (not data or not isinstance(data, (Dict, List))): return data
|
|
11
|
+
if isinstance(data, List):
|
|
12
|
+
return [scrub(item) for item in data]
|
|
13
|
+
else:
|
|
14
|
+
temp = {}
|
|
15
|
+
secrets = ["x_api_key", "x-api-key", "access_token", "access-token", "authorization", "api_key", "api-key", "apikey", "accesstoken", "token", "password", "key"]
|
|
16
|
+
for key, value in data.items():
|
|
17
|
+
if isinstance(value, (Dict, List)):
|
|
18
|
+
temp[key] = scrub(data[key])
|
|
19
|
+
elif key.lower() in secrets:
|
|
20
|
+
temp[key] = '********'
|
|
21
|
+
else:
|
|
22
|
+
temp[key] = data[key]
|
|
23
|
+
return temp
|
|
9
24
|
|
|
10
25
|
def scrub_keys(e: Exception) -> Dict[str, Any]:
|
|
11
26
|
"""
|
|
@@ -16,7 +31,7 @@ def scrub_keys(e: Exception) -> Dict[str, Any]:
|
|
|
16
31
|
"error": str(e),
|
|
17
32
|
"type": type(e).__name__,
|
|
18
33
|
"message": str(e),
|
|
19
|
-
"args": getattr(e, 'args', None)
|
|
34
|
+
"args": scrub(getattr(e, 'args', None))
|
|
20
35
|
}
|
|
21
36
|
|
|
22
37
|
|
|
@@ -24,7 +24,7 @@ def init_the_init(full_path: str, code_imports: Optional[str] = None) -> None:
|
|
|
24
24
|
if not os.path.exists(init_path):
|
|
25
25
|
if code_imports is None:
|
|
26
26
|
code_imports = CODE_IMPORTS
|
|
27
|
-
with open(init_path, "w") as f:
|
|
27
|
+
with open(init_path, "w", encoding='utf-8') as f:
|
|
28
28
|
f.write(code_imports)
|
|
29
29
|
|
|
30
30
|
|
|
@@ -33,7 +33,7 @@ def add_import_to_init(full_path: str, next: str, code_imports: Optional[str] =
|
|
|
33
33
|
init_the_init(full_path, code_imports=code_imports)
|
|
34
34
|
|
|
35
35
|
init_path = os.path.join(full_path, "__init__.py")
|
|
36
|
-
with open(init_path, "a+") as f:
|
|
36
|
+
with open(init_path, "a+", encoding='utf-8') as f:
|
|
37
37
|
import_stmt = "from . import {}\n".format(next)
|
|
38
38
|
f.seek(0)
|
|
39
39
|
lines = f.readlines()
|
|
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"]
|
|
|
3
3
|
|
|
4
4
|
[project]
|
|
5
5
|
name = "polyapi-python"
|
|
6
|
-
version = "0.3.
|
|
6
|
+
version = "0.3.10"
|
|
7
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 = [
|
|
@@ -38,9 +38,6 @@ MyTableColumns = Literal["id","createdAt","updatedAt","name","age","active","opt
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
from typing_extensions import Required
|
|
42
|
-
|
|
43
|
-
|
|
44
41
|
class MyTableRow(TypedDict, total=False):
|
|
45
42
|
id: Required[str]
|
|
46
43
|
""" Required property """
|
|
@@ -60,7 +57,7 @@ class MyTableRow(TypedDict, total=False):
|
|
|
60
57
|
active: Required[bool]
|
|
61
58
|
""" Required property """
|
|
62
59
|
|
|
63
|
-
optional:
|
|
60
|
+
optional: dict[str, Any]
|
|
64
61
|
|
|
65
62
|
|
|
66
63
|
|
|
@@ -350,9 +347,6 @@ MyTableColumns = Literal["id","createdAt","updatedAt","data"]
|
|
|
350
347
|
|
|
351
348
|
|
|
352
349
|
|
|
353
|
-
from typing_extensions import Required
|
|
354
|
-
|
|
355
|
-
|
|
356
350
|
class MyTableRow(TypedDict, total=False):
|
|
357
351
|
id: Required[str]
|
|
358
352
|
""" Required property """
|
|
@@ -370,8 +364,8 @@ class MyTableRow(TypedDict, total=False):
|
|
|
370
364
|
|
|
371
365
|
class _MyTableRowdata(TypedDict, total=False):
|
|
372
366
|
foo: str
|
|
373
|
-
nested:
|
|
374
|
-
other:
|
|
367
|
+
nested: list["_MyTableRowdatanesteditem"]
|
|
368
|
+
other: str | int | float | dict[str, Any] | list[Any] | bool | None
|
|
375
369
|
"""
|
|
376
370
|
x-poly-ref:
|
|
377
371
|
path: some.other.Schema
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyapi_python-0.3.9.dev15 → polyapi_python-0.3.10}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|