diff --git a/polyapi/cli.py b/polyapi/cli.py index cd0d2ac..43e4a2d 100644 --- a/polyapi/cli.py +++ b/polyapi/cli.py @@ -27,6 +27,7 @@ def execute_from_cli() -> None: parser.add_argument("--client", action="store_true", help="Pass --client when adding function to add a client function.") parser.add_argument("--server", action="store_true", help="Pass --server when adding function to add a server function.") parser.add_argument("--logs", action="store_true", help="Pass --logs when adding function if you want to store and see the function logs.") + parser.add_argument("--skip-generate", action="store_true", help="Pass --skip-generate to skip generating the library after adding a function.") parser.add_argument("command", choices=CLI_COMMANDS) parser.add_argument("subcommands", nargs="*") args = parser.parse_args() @@ -44,8 +45,8 @@ def execute_from_cli() -> None: clear_config() generate() elif command == "update_rendered_spec": - assert len(args.subcommands) == 2 - updated = get_and_update_rendered_spec(args.subcommands[0], args.subcommands[1]) + assert len(args.subcommands) == 1 + updated = get_and_update_rendered_spec(args.subcommands[0]) if updated: print("Updated rendered spec!") else: @@ -55,4 +56,4 @@ def execute_from_cli() -> None: print("Clearing the generated library...") clear() elif command == "function": - function_add_or_update(args.context, args.description, args.client, args.server, args.logs, args.subcommands) + function_add_or_update(args.context, args.description, args.client, args.server, args.logs, args.subcommands, not args.skip_generate) diff --git a/polyapi/function_cli.py b/polyapi/function_cli.py index 0cbbb7a..8d84e09 100644 --- a/polyapi/function_cli.py +++ b/polyapi/function_cli.py @@ -207,6 +207,7 @@ def function_add_or_update( server: bool, logs_enabled: bool, subcommands: List, + generate: bool = True, ): parser = argparse.ArgumentParser() parser.add_argument("subcommand", choices=["add"]) @@ -268,10 +269,11 @@ def function_add_or_update( print_green("DEPLOYED") function_id = resp.json()["id"] print(f"Function ID: {function_id}") - print("Generating new custom function...", end="") - functions = get_functions_and_parse(limit_ids=[function_id]) - generate_functions(functions) - print_green("DONE") + if generate: + print("Generating new custom function...", end="") + functions = get_functions_and_parse(limit_ids=[function_id]) + generate_functions(functions) + print_green("DONE") else: print("Error adding function.") print(resp.status_code) diff --git a/polyapi/generate.py b/polyapi/generate.py index a4f429e..d004c6f 100644 --- a/polyapi/generate.py +++ b/polyapi/generate.py @@ -11,7 +11,7 @@ from .typedefs import PropertySpecification, SpecificationDto, VariableSpecDto from .api import render_api_function from .server import render_server_function -from .utils import add_import_to_init, get_auth_headers, init_the_init +from .utils import add_import_to_init, get_auth_headers, init_the_init, to_func_namespace from .variables import generate_variables from .config import get_api_key_and_url, initialize_config @@ -232,10 +232,10 @@ def add_function_file( # add function to init init_path = os.path.join(full_path, "__init__.py") with open(init_path, "a") as f: - f.write(f"\n\nfrom . import _{function_name}\n\n{func_str}") + f.write(f"\n\nfrom . import {to_func_namespace(function_name)}\n\n{func_str}") # add type_defs to underscore file - file_path = os.path.join(full_path, f"_{function_name}.py") + file_path = os.path.join(full_path, f"{to_func_namespace(function_name)}.py") with open(file_path, "w") as f: f.write(func_type_defs) diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index 5b3a394..7de7cad 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -7,7 +7,7 @@ from polyapi.typedefs import SpecificationDto -def update_rendered_spec(api_key: str, spec: SpecificationDto): +def update_rendered_spec(spec: SpecificationDto): print("Updating rendered spec...") func_str, type_defs = render_spec(spec) data = { @@ -27,9 +27,7 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): raise NotImplementedError("todo") # use super key on develop-k8s here! - _, base_url = get_api_key_and_url() - if not base_url: - base_url = os.environ.get("HOST_URL") + api_key, base_url = get_api_key_and_url() url = f"{base_url}/functions/rendered-specs" headers = {"Authorization": f"Bearer {api_key}"} @@ -37,11 +35,8 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): assert resp.status_code == 201, (resp.text, resp.status_code) -def _get_spec(api_key: str, spec_id: str) -> Optional[SpecificationDto]: - _, base_url = get_api_key_and_url() - if not base_url: - base_url = os.environ.get("HOST_URL") - +def _get_spec(spec_id: str) -> Optional[SpecificationDto]: + api_key, base_url = get_api_key_and_url() url = f"{base_url}/specs" headers = {"Authorization": f"Bearer {api_key}"} resp = requests.get(url, headers=headers) @@ -55,10 +50,10 @@ def _get_spec(api_key: str, spec_id: str) -> Optional[SpecificationDto]: raise NotImplementedError(resp.content) -def get_and_update_rendered_spec(api_key: str, spec_id: str) -> bool: - spec = _get_spec(api_key, spec_id) +def get_and_update_rendered_spec(spec_id: str) -> bool: + spec = _get_spec(spec_id) if spec: - update_rendered_spec(api_key, spec) + update_rendered_spec(spec) return True return False @@ -70,4 +65,4 @@ def save_rendered_specs() -> None: for spec in api_specs: assert spec["function"] print("adding", spec["context"], spec["name"]) - update_rendered_spec("FIXME", spec) + update_rendered_spec(spec) diff --git a/polyapi/utils.py b/polyapi/utils.py index d7b105b..3349ff6 100644 --- a/polyapi/utils.py +++ b/polyapi/utils.py @@ -75,11 +75,11 @@ def add_type_import_path(function_name: str, arg: str) -> str: else: if '"' in sub: sub = sub.replace('"', "") - return f'List["_{function_name}.{camelCase(sub)}"]' + return f'List["{to_func_namespace(function_name)}.{camelCase(sub)}"]' else: - return f'List[_{function_name}.{camelCase(sub)}]' + return f'List[{to_func_namespace(function_name)}.{camelCase(sub)}]' - return f'_{function_name}.{camelCase(arg)}' + return f'{to_func_namespace(function_name)}.{camelCase(arg)}' def get_type_and_def(type_spec: PropertyType) -> Tuple[str, str]: @@ -183,4 +183,18 @@ def poly_full_path(context, name) -> str: path = context + "." + name else: path = name - return f"poly.{path}" \ No newline at end of file + return f"poly.{path}" + + +RESERVED_TYPES = {"List", "Dict", "Any", "Optional", "Callable"} + + +def to_func_namespace(s: str) -> str: + """ convert a function name to some function namespace + by default it is + """ + rv = s[0].upper() + s[1:] + if rv in RESERVED_TYPES: + return "_" + rv + else: + return rv \ No newline at end of file diff --git a/polyapi/webhook.py b/polyapi/webhook.py index 1524655..855c300 100644 --- a/polyapi/webhook.py +++ b/polyapi/webhook.py @@ -6,7 +6,7 @@ from polyapi.config import get_api_key_and_url from polyapi.typedefs import PropertySpecification -from polyapi.utils import parse_arguments, poly_full_path +from polyapi.utils import parse_arguments, poly_full_path, to_func_namespace # all active webhook handlers, used by unregister_all to cleanup active_handlers: List[Dict[str, Any]] = [] @@ -124,7 +124,7 @@ def render_webhook_handle( if "WebhookEventType" in function_args: # let's add the function name import! - function_args = function_args.replace("WebhookEventType", f"_{function_name}.WebhookEventType") + function_args = function_args.replace("WebhookEventType", f"{to_func_namespace(function_name)}.WebhookEventType") func_str = WEBHOOK_TEMPLATE.format( description=function_description, diff --git a/pyproject.toml b/pyproject.toml index 376e0e1..a7c2740 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5" +version = "0.2.6" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ diff --git a/tests/test_api.py b/tests/test_api.py index eb05c7b..ceba99c 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,6 +1,7 @@ import unittest from polyapi.api import render_api_function +from polyapi.utils import to_func_namespace ACCUWEATHER = { "id": "f7588018-2364-4586-b60d", @@ -235,7 +236,7 @@ def test_render_function_accuweather(self): ) self.assertIn(ACCUWEATHER["id"], func_str) self.assertIn("locationId: int,", func_str) - self.assertIn(f"-> _{name}.{name}Response", func_str) + self.assertIn(f"-> {to_func_namespace(name)}.{name}Response", func_str) def test_render_function_zillow(self): name = ZILLOW["name"] @@ -249,7 +250,7 @@ def test_render_function_zillow(self): ) self.assertIn(ZILLOW["id"], func_str) self.assertIn("locationId: int,", func_str) - self.assertIn(f"-> _{name}.{name}Response", func_str) + self.assertIn(f"-> {to_func_namespace(name)}.{name}Response", func_str) def test_render_function_twilio_api(self): name = TWILIO["name"] @@ -264,7 +265,7 @@ def test_render_function_twilio_api(self): self.assertIn(TWILIO["id"], func_str) self.assertIn("conversationSID: str", func_str) self.assertIn("authToken: str", func_str) - self.assertIn(f"-> _{name}.{name}Response", func_str) + self.assertIn(f"-> {to_func_namespace(name)}.{name}Response", func_str) def test_render_function_twilio_get_details(self): # same test but try it as a serverFunction rather than an apiFunction @@ -278,6 +279,6 @@ def test_render_function_twilio_get_details(self): TWILIO_GET_DETAILS["function"]["returnType"], ) self.assertIn(TWILIO_GET_DETAILS["id"], func_str) - self.assertIn(f"-> _{name}.{name}Response", func_str) + self.assertIn(f"-> {to_func_namespace(name)}.{name}Response", func_str) self.assertIn("class SubresourceUris", func_type_defs) # self.assertIn('Required["SubresourceUris"]', func_type_defs) diff --git a/tests/test_auth.py b/tests/test_auth.py index ed626d8..6d399f7 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -136,4 +136,3 @@ def test_render_get_token(self): self.assertIn(GET_TOKEN["id"], func_str) # self.assertIn("conversationSID: str", func_str) # self.assertIn("authToken: str", func_str) - # self.assertIn(f"-> _{name}.ResponseType", func_str) diff --git a/tests/test_server.py b/tests/test_server.py index d08bea6..c767d2d 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -1,5 +1,7 @@ import unittest +from polyapi.utils import to_func_namespace + from .test_api import TWILIO from polyapi.server import render_server_function @@ -45,7 +47,7 @@ def test_render_function_twilio_server(self): self.assertIn(TWILIO["id"], func_str) self.assertIn("conversationSID: str", func_str) self.assertIn("authToken: str", func_str) - self.assertIn(f"-> _{name}.ResponseType", func_str) + self.assertIn(f"-> {to_func_namespace(name)}.ResponseType", func_str) def test_render_function_get_products_count(self): return_type = GET_PRODUCTS_COUNT["function"]["returnType"]