polyapi-python 0.3.15__tar.gz → 0.3.16.dev1__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.15/polyapi_python.egg-info → polyapi_python-0.3.16.dev1}/PKG-INFO +1 -1
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/generate.py +5 -3
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/utils.py +11 -5
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1/polyapi_python.egg-info}/PKG-INFO +1 -1
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/pyproject.toml +1 -1
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_api.py +5 -5
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_generate.py +46 -2
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_server.py +3 -3
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/LICENSE +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/README.md +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/__init__.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/__main__.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/api.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/auth.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/cli.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/cli_constants.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/client.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/config.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/constants.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/deployables.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/error_handler.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/exceptions.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/execute.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/function_cli.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/http_client.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/parser.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/poly_schemas.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/poly_tables.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/prepare.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/py.typed +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/rendered_spec.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/schema.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/server.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/sync.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/typedefs.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/variables.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/webhook.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi_python.egg-info/SOURCES.txt +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi_python.egg-info/dependency_links.txt +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi_python.egg-info/requires.txt +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi_python.egg-info/top_level.txt +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/setup.cfg +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_async_proof.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_auth.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_deployables.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_parser.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_poly_custom.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_rendered_spec.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_schema.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_tabi.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_utils.py +0 -0
- {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_variables.py +0 -0
|
@@ -16,7 +16,7 @@ from .webhook import render_webhook_handle
|
|
|
16
16
|
from .typedefs import PropertySpecification, SchemaSpecDto, SpecificationDto, VariableSpecDto, TableSpecDto
|
|
17
17
|
from .api import render_api_function
|
|
18
18
|
from .server import render_server_function
|
|
19
|
-
from .utils import add_import_to_init, get_auth_headers, init_the_init, print_green, to_func_namespace
|
|
19
|
+
from .utils import add_import_to_init, get_auth_headers, init_the_init, print_green, to_func_namespace, to_type_module_alias
|
|
20
20
|
from .variables import generate_variables
|
|
21
21
|
from .poly_tables import generate_tables
|
|
22
22
|
from . import http_client
|
|
@@ -506,8 +506,10 @@ def add_function_file(
|
|
|
506
506
|
with open(init_path, "r", encoding='utf-8') as f:
|
|
507
507
|
init_content = f.read()
|
|
508
508
|
|
|
509
|
-
#
|
|
510
|
-
|
|
509
|
+
# Import the generated type module under a private alias so PascalCase function
|
|
510
|
+
# names do not shadow their own module symbol in __init__.py.
|
|
511
|
+
type_module_alias = to_type_module_alias(function_name)
|
|
512
|
+
new_init_content = init_content + f"\n\nfrom . import {func_namespace} as {type_module_alias}\n\n{func_str}"
|
|
511
513
|
|
|
512
514
|
# Use temporary files for atomic writes
|
|
513
515
|
# Write to __init__.py atomically
|
|
@@ -71,11 +71,17 @@ def print_red(s: str):
|
|
|
71
71
|
print(Fore.RED + s + Style.RESET_ALL)
|
|
72
72
|
|
|
73
73
|
|
|
74
|
+
def to_type_module_alias(function_name: str) -> str:
|
|
75
|
+
"""Return the internal alias used for a function's generated type module."""
|
|
76
|
+
return f"_{to_func_namespace(function_name)}_types"
|
|
77
|
+
|
|
78
|
+
|
|
74
79
|
def add_type_import_path(function_name: str, arg: str) -> str:
|
|
75
80
|
"""if not basic type, coerce to camelCase and add the import path"""
|
|
76
81
|
# from now, we start qualifying non-basic types :))
|
|
77
82
|
# e.g. Callable[[EmailAddress, Dict, Dict, Dict], None]
|
|
78
83
|
# becomes Callable[[Set_profile_email.EmailAddress, Dict, Dict, Dict], None]
|
|
84
|
+
type_module_alias = to_type_module_alias(function_name)
|
|
79
85
|
|
|
80
86
|
if arg.startswith("Callable"):
|
|
81
87
|
inner = arg[len("Callable["):-1] # strip outer Callable[...]
|
|
@@ -84,7 +90,7 @@ def add_type_import_path(function_name: str, arg: str) -> str:
|
|
|
84
90
|
for p in parts:
|
|
85
91
|
clean = p.strip("[] ")
|
|
86
92
|
if clean and clean not in BASIC_PYTHON_TYPES:
|
|
87
|
-
replacement = f"{
|
|
93
|
+
replacement = f"{type_module_alias}.{camelCase(clean)}"
|
|
88
94
|
p = p.replace(clean, replacement)
|
|
89
95
|
qualified.append(p)
|
|
90
96
|
return "Callable[" + ",".join(qualified) + "]"
|
|
@@ -100,11 +106,11 @@ def add_type_import_path(function_name: str, arg: str) -> str:
|
|
|
100
106
|
else:
|
|
101
107
|
if '"' in sub:
|
|
102
108
|
sub = sub.replace('"', "")
|
|
103
|
-
return f'List["{
|
|
109
|
+
return f'List["{type_module_alias}.{camelCase(sub)}"]'
|
|
104
110
|
else:
|
|
105
|
-
return f"List[{
|
|
111
|
+
return f"List[{type_module_alias}.{camelCase(sub)}]"
|
|
106
112
|
|
|
107
|
-
return f"{
|
|
113
|
+
return f"{type_module_alias}.{camelCase(arg)}"
|
|
108
114
|
|
|
109
115
|
|
|
110
116
|
def get_type_and_def(
|
|
@@ -352,4 +358,4 @@ def return_type_already_defined_in_args(return_type_name: str, args_def: str) ->
|
|
|
352
358
|
basic_match = bool(re.search(basic_pattern, args_def, re.MULTILINE))
|
|
353
359
|
class_pattern = rf"^class {re.escape(return_type_name)}\(TypedDict"
|
|
354
360
|
class_match = bool(re.search(class_pattern, args_def, re.MULTILINE))
|
|
355
|
-
return basic_match or class_match
|
|
361
|
+
return basic_match or class_match
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "polyapi-python"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.16.dev1"
|
|
8
8
|
description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers"
|
|
9
9
|
authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }]
|
|
10
10
|
dependencies = [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import unittest
|
|
2
2
|
|
|
3
3
|
from polyapi.api import render_api_function
|
|
4
|
-
from polyapi.utils import
|
|
4
|
+
from polyapi.utils import to_type_module_alias
|
|
5
5
|
|
|
6
6
|
ACCUWEATHER = {
|
|
7
7
|
"id": "f7588018-2364-4586-b60d",
|
|
@@ -236,7 +236,7 @@ class T(unittest.TestCase):
|
|
|
236
236
|
)
|
|
237
237
|
self.assertIn(ACCUWEATHER["id"], func_str)
|
|
238
238
|
self.assertIn("locationId: int,", func_str)
|
|
239
|
-
self.assertIn(f"-> {
|
|
239
|
+
self.assertIn(f"-> {to_type_module_alias(name)}.{name}Response", func_str)
|
|
240
240
|
|
|
241
241
|
def test_render_function_zillow(self):
|
|
242
242
|
name = ZILLOW["name"]
|
|
@@ -250,7 +250,7 @@ class T(unittest.TestCase):
|
|
|
250
250
|
)
|
|
251
251
|
self.assertIn(ZILLOW["id"], func_str)
|
|
252
252
|
self.assertIn("locationId: int,", func_str)
|
|
253
|
-
self.assertIn(f"-> {
|
|
253
|
+
self.assertIn(f"-> {to_type_module_alias(name)}.{name}Response", func_str)
|
|
254
254
|
|
|
255
255
|
def test_render_function_twilio_api(self):
|
|
256
256
|
name = TWILIO["name"]
|
|
@@ -265,7 +265,7 @@ class T(unittest.TestCase):
|
|
|
265
265
|
self.assertIn(TWILIO["id"], func_str)
|
|
266
266
|
self.assertIn("conversationSID: str", func_str)
|
|
267
267
|
self.assertIn("authToken: str", func_str)
|
|
268
|
-
self.assertIn(f"-> {
|
|
268
|
+
self.assertIn(f"-> {to_type_module_alias(name)}.{name}Response", func_str)
|
|
269
269
|
|
|
270
270
|
def test_render_function_twilio_get_details(self):
|
|
271
271
|
# same test but try it as a serverFunction rather than an apiFunction
|
|
@@ -279,6 +279,6 @@ class T(unittest.TestCase):
|
|
|
279
279
|
TWILIO_GET_DETAILS["function"]["returnType"],
|
|
280
280
|
)
|
|
281
281
|
self.assertIn(TWILIO_GET_DETAILS["id"], func_str)
|
|
282
|
-
self.assertIn(f"-> {
|
|
282
|
+
self.assertIn(f"-> {to_type_module_alias(name)}.{name}Response", func_str)
|
|
283
283
|
self.assertIn("class SubresourceUris", func_type_defs)
|
|
284
284
|
# self.assertIn('Required["SubresourceUris"]', func_type_defs)
|
|
@@ -2,9 +2,11 @@ import unittest
|
|
|
2
2
|
import os
|
|
3
3
|
import shutil
|
|
4
4
|
import importlib.util
|
|
5
|
+
import tempfile
|
|
5
6
|
from unittest.mock import patch, MagicMock
|
|
6
|
-
from polyapi.
|
|
7
|
-
from polyapi.
|
|
7
|
+
from polyapi.typedefs import SpecificationDto
|
|
8
|
+
from polyapi.utils import get_type_and_def, rewrite_reserved, to_type_module_alias
|
|
9
|
+
from polyapi.generate import render_spec, create_empty_schemas_module, generate_functions, create_function, add_function_file
|
|
8
10
|
from polyapi.poly_schemas import generate_schemas, create_schema
|
|
9
11
|
from polyapi.variables import generate_variables, create_variable
|
|
10
12
|
|
|
@@ -660,3 +662,45 @@ def test_nested_function() -> schemas.api.v1.user.profile:
|
|
|
660
662
|
# The failed function directory should not exist
|
|
661
663
|
func_dir = os.path.join(context_dir, "failing_function")
|
|
662
664
|
self.assertFalse(os.path.exists(func_dir))
|
|
665
|
+
|
|
666
|
+
def test_add_function_file_aliases_pascal_case_type_module(self):
|
|
667
|
+
spec: SpecificationDto = {
|
|
668
|
+
"id": "test-func-id",
|
|
669
|
+
"name": "CreateAJsonPost",
|
|
670
|
+
"context": "test_context",
|
|
671
|
+
"type": "apiFunction",
|
|
672
|
+
"description": "Test function",
|
|
673
|
+
"language": "python",
|
|
674
|
+
"function": {
|
|
675
|
+
"arguments": [],
|
|
676
|
+
"returnType": {
|
|
677
|
+
"kind": "object",
|
|
678
|
+
"schema": {
|
|
679
|
+
"type": "object",
|
|
680
|
+
"properties": {
|
|
681
|
+
"id": {"type": "integer"},
|
|
682
|
+
},
|
|
683
|
+
"required": ["id"],
|
|
684
|
+
"title": "ReturnType",
|
|
685
|
+
},
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
691
|
+
add_function_file(temp_dir, spec["name"], spec)
|
|
692
|
+
|
|
693
|
+
init_path = os.path.join(temp_dir, "__init__.py")
|
|
694
|
+
with open(init_path, "r", encoding="utf-8") as file:
|
|
695
|
+
init_content = file.read()
|
|
696
|
+
|
|
697
|
+
type_module_alias = to_type_module_alias(spec["name"])
|
|
698
|
+
self.assertIn(
|
|
699
|
+
f"from . import {spec['name']} as {type_module_alias}",
|
|
700
|
+
init_content,
|
|
701
|
+
)
|
|
702
|
+
self.assertIn(f"def {spec['name']}(", init_content)
|
|
703
|
+
self.assertIn(
|
|
704
|
+
f"-> {type_module_alias}.{spec['name']}Response",
|
|
705
|
+
init_content,
|
|
706
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import unittest
|
|
2
2
|
|
|
3
|
-
from polyapi.utils import
|
|
3
|
+
from polyapi.utils import to_type_module_alias
|
|
4
4
|
|
|
5
5
|
from .test_api import TWILIO
|
|
6
6
|
from polyapi.server import render_server_function
|
|
@@ -81,7 +81,7 @@ class T(unittest.TestCase):
|
|
|
81
81
|
self.assertIn(TWILIO["id"], func_str)
|
|
82
82
|
self.assertIn("conversationSID: str", func_str)
|
|
83
83
|
self.assertIn("authToken: str", func_str)
|
|
84
|
-
self.assertIn(f"-> {
|
|
84
|
+
self.assertIn(f"-> {to_type_module_alias(name)}.ResponseType", func_str)
|
|
85
85
|
|
|
86
86
|
def test_render_function_get_products_count(self):
|
|
87
87
|
return_type = GET_PRODUCTS_COUNT["function"]["returnType"]
|
|
@@ -116,4 +116,4 @@ class T(unittest.TestCase):
|
|
|
116
116
|
|
|
117
117
|
# stay_date: Required[str]
|
|
118
118
|
# """ Required property """'''
|
|
119
|
-
# self.assertIn(expected_return_type, func_str)
|
|
119
|
+
# self.assertIn(expected_return_type, func_str)
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/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
|