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.
Files changed (52) hide show
  1. {polyapi_python-0.3.15/polyapi_python.egg-info → polyapi_python-0.3.16.dev1}/PKG-INFO +1 -1
  2. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/generate.py +5 -3
  3. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/utils.py +11 -5
  4. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1/polyapi_python.egg-info}/PKG-INFO +1 -1
  5. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/pyproject.toml +1 -1
  6. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_api.py +5 -5
  7. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_generate.py +46 -2
  8. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_server.py +3 -3
  9. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/LICENSE +0 -0
  10. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/README.md +0 -0
  11. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/__init__.py +0 -0
  12. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/__main__.py +0 -0
  13. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/api.py +0 -0
  14. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/auth.py +0 -0
  15. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/cli.py +0 -0
  16. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/cli_constants.py +0 -0
  17. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/client.py +0 -0
  18. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/config.py +0 -0
  19. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/constants.py +0 -0
  20. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/deployables.py +0 -0
  21. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/error_handler.py +0 -0
  22. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/exceptions.py +0 -0
  23. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/execute.py +0 -0
  24. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/function_cli.py +0 -0
  25. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/http_client.py +0 -0
  26. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/parser.py +0 -0
  27. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/poly_schemas.py +0 -0
  28. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/poly_tables.py +0 -0
  29. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/prepare.py +0 -0
  30. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/py.typed +0 -0
  31. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/rendered_spec.py +0 -0
  32. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/schema.py +0 -0
  33. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/server.py +0 -0
  34. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/sync.py +0 -0
  35. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/typedefs.py +0 -0
  36. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/variables.py +0 -0
  37. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi/webhook.py +0 -0
  38. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi_python.egg-info/SOURCES.txt +0 -0
  39. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi_python.egg-info/dependency_links.txt +0 -0
  40. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi_python.egg-info/requires.txt +0 -0
  41. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/polyapi_python.egg-info/top_level.txt +0 -0
  42. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/setup.cfg +0 -0
  43. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_async_proof.py +0 -0
  44. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_auth.py +0 -0
  45. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_deployables.py +0 -0
  46. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_parser.py +0 -0
  47. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_poly_custom.py +0 -0
  48. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_rendered_spec.py +0 -0
  49. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_schema.py +0 -0
  50. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_tabi.py +0 -0
  51. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_utils.py +0 -0
  52. {polyapi_python-0.3.15 → polyapi_python-0.3.16.dev1}/tests/test_variables.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polyapi-python
3
- Version: 0.3.15
3
+ Version: 0.3.16.dev1
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
@@ -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
- # Prepare new content to append to __init__.py
510
- new_init_content = init_content + f"\n\nfrom . import {func_namespace}\n\n{func_str}"
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"{to_func_namespace(function_name)}.{camelCase(clean)}"
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["{to_func_namespace(function_name)}.{camelCase(sub)}"]'
109
+ return f'List["{type_module_alias}.{camelCase(sub)}"]'
104
110
  else:
105
- return f"List[{to_func_namespace(function_name)}.{camelCase(sub)}]"
111
+ return f"List[{type_module_alias}.{camelCase(sub)}]"
106
112
 
107
- return f"{to_func_namespace(function_name)}.{camelCase(arg)}"
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polyapi-python
3
- Version: 0.3.15
3
+ Version: 0.3.16.dev1
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "polyapi-python"
7
- version = "0.3.15"
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 to_func_namespace
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"-> {to_func_namespace(name)}.{name}Response", func_str)
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"-> {to_func_namespace(name)}.{name}Response", func_str)
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"-> {to_func_namespace(name)}.{name}Response", func_str)
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"-> {to_func_namespace(name)}.{name}Response", func_str)
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.utils import get_type_and_def, rewrite_reserved
7
- from polyapi.generate import render_spec, create_empty_schemas_module, generate_functions, create_function
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 to_func_namespace
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"-> {to_func_namespace(name)}.ResponseType", func_str)
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)