From c455b515d416cd69703aab757fda32ba10b9df4b Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Wed, 1 May 2024 07:37:13 -0700 Subject: [PATCH 01/16] better webhooks (#12) * add new dev version * add error_handler * add error_handler * catch if import name is different than pip name * lets hardcode pydantic 2.5.3 and see if that fixes * Revert "lets hardcode pydantic 2.5.3 and see if that fixes" This reverts commit def20b592f59e057844ce90dd8c94a28bbd0d8df. * 0.2.3.dev4, actually its problem with kube_hunter, nvm * maybe we need the new requirements * woot client functions are done? * fix tests * 0.2.3.dev7, dont assume client function, must specify with --client * 0.2.3.dev8 fix small bug client functions * 0.2.3.dev9, add fallbacks if unrecognized version of OpenAPI present in API functions * add pyjwt to requirements * add ability to do multiple error handlers! * dont require pyjwt anymore * 0.2.4.dev2, replace hacky manual mimetypes with real mimetypes * add polycustom * multi webhook (#9) * towards multiple webhook handlers simultaneously * next * update pyproject.toml * 0.2.4.dev5, accept non-200 and non-201 status codes from polyCustom * 0.2.4.dev6 bring python client in line with execute server and consider 3xx to be error * 0.2.4.dev7, make TypedDict input and response types more picky if wrong TypedDict is used * actually use args in webhook * 0.2.4.dev8, fix webhook stopping text * getting there * 0.2.4.dev9, handle already connected error on windows * 0.2.4.deva1, better user facing messages for webhooks and error handlers * woops lets go version 10 * 0.2.4.dev11 * move polyCustom to own file * onward * fix it * 0.2.4.dev13, fix client functions polluting other server functions * new version --- polyapi/api.py | 2 ++ polyapi/auth.py | 6 +++--- polyapi/constants.py | 4 ++++ polyapi/server.py | 4 +++- polyapi/typedefs.py | 1 + polyapi/utils.py | 25 ++++++++++++++++++++++++- polyapi/webhook.py | 23 +++++++++++++++++++---- pyproject.toml | 2 +- tests/test_utils.py | 7 +++++++ 9 files changed, 64 insertions(+), 10 deletions(-) diff --git a/polyapi/api.py b/polyapi/api.py index e8018f9..8cceff3 100644 --- a/polyapi/api.py +++ b/polyapi/api.py @@ -24,6 +24,8 @@ def {function_name}( \""" resp = execute("{function_type}", "{function_id}", {data}) return {api_response_type}(resp.json()) # type: ignore + + """ diff --git a/polyapi/auth.py b/polyapi/auth.py index a405510..199cfef 100644 --- a/polyapi/auth.py +++ b/polyapi/auth.py @@ -16,9 +16,9 @@ class AuthFunctionResponse(TypedDict): - status: int - data: Any - headers: Dict[str, str] + status: int + data: Any + headers: Dict[str, str] async def getToken(clientId: str, clientSecret: str, scopes: List[str], callback, options: Optional[Dict[str, Any]] = None): diff --git a/polyapi/constants.py b/polyapi/constants.py index a58b64d..16bbeaf 100644 --- a/polyapi/constants.py +++ b/polyapi/constants.py @@ -5,6 +5,8 @@ "boolean": "bool", "array": "List", "object": "Dict", + "function": "Callable", + "void": "None", } @@ -15,6 +17,8 @@ "bool": "boolean", "List": "array", "Dict": "object", + "Callable": "function", + "None": "void", } BASIC_PYTHON_TYPES = set(PYTHON_TO_JSONSCHEMA_TYPE_MAP.keys()) diff --git a/polyapi/server.py b/polyapi/server.py index 6a359bf..f616f26 100644 --- a/polyapi/server.py +++ b/polyapi/server.py @@ -4,7 +4,7 @@ from polyapi.utils import camelCase, add_type_import_path, parse_arguments, get_type_and_def SERVER_DEFS_TEMPLATE = """ -from typing import List, Dict, Any, TypedDict +from typing import List, Dict, Any, TypedDict, Callable {args_def} {return_type_def} """ @@ -22,6 +22,8 @@ def {function_name}( return {return_action} except: return resp.text + + """ diff --git a/polyapi/typedefs.py b/polyapi/typedefs.py index 544f3c1..e23113a 100644 --- a/polyapi/typedefs.py +++ b/polyapi/typedefs.py @@ -12,6 +12,7 @@ class PropertySpecification(TypedDict): class PropertyType(TypedDict): kind: Literal['void', 'primitive', 'array', 'object', 'function', 'plain'] + spec: NotRequired[Dict] name: NotRequired[str] type: NotRequired[str] items: NotRequired['PropertyType'] diff --git a/polyapi/utils.py b/polyapi/utils.py index 604a700..bba3463 100644 --- a/polyapi/utils.py +++ b/polyapi/utils.py @@ -10,7 +10,7 @@ # this string should be in every __init__ file. # it contains all the imports needed for the function or variable code to run -CODE_IMPORTS = "from typing import List, Dict, Any, TypedDict, Optional\nimport logging\nimport requests\nimport socketio # type: ignore\nfrom polyapi.config import get_api_key_and_url\nfrom polyapi.execute import execute, execute_post, variable_get, variable_update\n\n" +CODE_IMPORTS = "from typing import List, Dict, Any, TypedDict, Optional, Callable\nimport logging\nimport requests\nimport socketio # type: ignore\nfrom polyapi.config import get_api_key_and_url\nfrom polyapi.execute import execute, execute_post, variable_get, variable_update\n\n" def init_the_init(full_path: str) -> None: @@ -61,6 +61,10 @@ def print_red(s: str): def add_type_import_path(function_name: str, arg: str) -> str: """ if not basic type, coerce to camelCase and add the import path """ + # for now, just treat Callables as basic types + if arg.startswith("Callable"): + return arg + if arg in BASIC_PYTHON_TYPES: return arg @@ -142,6 +146,25 @@ def get_type_and_def(type_spec: PropertyType) -> Tuple[str, str]: return "Any", "" else: return "Dict", "" + elif type_spec["kind"] == "function": + arg_types = [] + arg_defs = [] + if "spec" in type_spec: + return_type, _ = get_type_and_def(type_spec["spec"]["returnType"]) + if return_type not in BASIC_PYTHON_TYPES: + # for now only Python only supports basic types as return types + return_type = "Any" + + for argument in type_spec["spec"]["arguments"]: + arg_type, arg_def = get_type_and_def(argument["type"]) + arg_types.append(arg_type) + if arg_def: + arg_defs.append(arg_def) + + final_arg_type = "Callable[[{}], {}]".format(", ".join(arg_types), return_type) + return final_arg_type, "\n".join(arg_defs) + else: + return "Callable", "" elif type_spec["kind"] == "any": return "Any", "" else: diff --git a/polyapi/webhook.py b/polyapi/webhook.py index e4bdf5c..1524655 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 poly_full_path +from polyapi.utils import parse_arguments, poly_full_path # all active webhook handlers, used by unregister_all to cleanup active_handlers: List[Dict[str, Any]] = [] @@ -15,10 +15,18 @@ client = None +WEBHOOK_DEFS_TEMPLATE = """ +from typing import List, Dict, Any, TypedDict, Callable +{function_args_def} +""" + + WEBHOOK_TEMPLATE = """ -async def {function_name}(callback, options=None): +async def {function_name}( +{function_args} +): \"""{description} Function ID: {function_id} @@ -112,15 +120,22 @@ def render_webhook_handle( arguments: List[PropertySpecification], return_type: Dict[str, Any], ) -> Tuple[str, str]: + function_args, function_args_def = parse_arguments(function_name, arguments) + + if "WebhookEventType" in function_args: + # let's add the function name import! + function_args = function_args.replace("WebhookEventType", f"_{function_name}.WebhookEventType") + func_str = WEBHOOK_TEMPLATE.format( description=function_description, client_id=uuid.uuid4().hex, function_id=function_id, function_name=function_name, + function_args=function_args, function_path=poly_full_path(function_context, function_name), ) - - return func_str, "" + func_defs = WEBHOOK_DEFS_TEMPLATE.format(function_args_def=function_args_def) + return func_str, func_defs def start(*args): diff --git a/pyproject.toml b/pyproject.toml index e889d20..7cff949 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.4" +version = "0.2.5.dev1" 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_utils.py b/tests/test_utils.py index 7e920bb..c3662a5 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,8 @@ import unittest from polyapi.schema import _fix_title +from polyapi.utils import get_type_and_def + +OPENAPI_FUNCTION = {'kind': 'function', 'spec': {'arguments': [{'name': 'event', 'required': False, 'type': {'kind': 'object', 'schema': {'$schema': 'http://json-schema.org/draft-06/schema#', 'type': 'array', 'items': {'$ref': '#/definitions/WebhookEventTypeElement'}, 'definitions': {'WebhookEventTypeElement': {'type': 'object', 'additionalProperties': False, 'properties': {'title': {'type': 'string'}, 'manufacturerName': {'type': 'string'}, 'carType': {'type': 'string'}, 'id': {'type': 'integer'}}, 'required': ['carType', 'id', 'manufacturerName', 'title'], 'title': 'WebhookEventTypeElement'}}}}}, {'name': 'headers', 'required': False, 'type': {'kind': 'object', 'typeName': 'Record'}}, {'name': 'params', 'required': False, 'type': {'kind': 'object', 'typeName': 'Record'}}, {'name': 'polyCustom', 'required': False, 'type': {'kind': 'object', 'properties': [{'name': 'responseStatusCode', 'type': {'type': 'number', 'kind': 'primitive'}, 'required': True}, {'name': 'responseContentType', 'type': {'type': 'string', 'kind': 'primitive'}, 'required': True, 'nullable': True}]}}], 'returnType': {'kind': 'void'}, 'synchronous': True}} class T(unittest.TestCase): @@ -8,3 +11,7 @@ def test_fix_titles(self): output = 'from typing import TypedDict\nfrom typing_extensions import Required\n\n\nclass Numofcars(TypedDict, total=False):\n """ numOfCars. """\n\n requestNumber: Required[int]\n """\n Requestnumber.\n\n Required property\n """\n\n' fixed = _fix_title(input_data, output) self.assertIn("class numOfCars", fixed) + + def test_get_type_and_def(self): + arg_type, arg_def = get_type_and_def(OPENAPI_FUNCTION) + self.assertEqual(arg_type, "Callable[[List[WebhookEventTypeElement], Dict, Dict, Dict], None]") From 79e3aa18cea9883a3bd49a54aafd476540e7da08 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Wed, 8 May 2024 11:50:09 -0700 Subject: [PATCH 02/16] more render (#13) * add new dev version * add error_handler * add error_handler * catch if import name is different than pip name * lets hardcode pydantic 2.5.3 and see if that fixes * Revert "lets hardcode pydantic 2.5.3 and see if that fixes" This reverts commit def20b592f59e057844ce90dd8c94a28bbd0d8df. * 0.2.3.dev4, actually its problem with kube_hunter, nvm * maybe we need the new requirements * woot client functions are done? * fix tests * 0.2.3.dev7, dont assume client function, must specify with --client * 0.2.3.dev8 fix small bug client functions * 0.2.3.dev9, add fallbacks if unrecognized version of OpenAPI present in API functions * add pyjwt to requirements * add ability to do multiple error handlers! * dont require pyjwt anymore * 0.2.4.dev2, replace hacky manual mimetypes with real mimetypes * add polycustom * multi webhook (#9) * towards multiple webhook handlers simultaneously * next * update pyproject.toml * 0.2.4.dev5, accept non-200 and non-201 status codes from polyCustom * 0.2.4.dev6 bring python client in line with execute server and consider 3xx to be error * 0.2.4.dev7, make TypedDict input and response types more picky if wrong TypedDict is used * actually use args in webhook * 0.2.4.dev8, fix webhook stopping text * getting there * 0.2.4.dev9, handle already connected error on windows * 0.2.4.deva1, better user facing messages for webhooks and error handlers * woops lets go version 10 * 0.2.4.dev11 * move polyCustom to own file * onward * fix it * wip * next * there we go --- polyapi/cli.py | 3 ++- polyapi/function_cli.py | 2 ++ polyapi/generate.py | 19 ------------------- polyapi/rendered_spec.py | 34 ++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 5 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 polyapi/rendered_spec.py diff --git a/polyapi/cli.py b/polyapi/cli.py index 14f21a2..ef2a2a9 100644 --- a/polyapi/cli.py +++ b/polyapi/cli.py @@ -3,8 +3,9 @@ from polyapi.utils import print_green from .config import clear_config, set_api_key_and_url -from .generate import generate, clear, save_rendered_specs +from .generate import generate, clear from .function_cli import function_add_or_update +from .rendered_spec import save_rendered_specs CLI_COMMANDS = ["setup", "generate", "function", "clear", "help", "save_rendered_specs"] diff --git a/polyapi/function_cli.py b/polyapi/function_cli.py index 0cbbb7a..9e461c3 100644 --- a/polyapi/function_cli.py +++ b/polyapi/function_cli.py @@ -13,6 +13,7 @@ from polyapi.generate import get_functions_and_parse, generate_functions from polyapi.config import get_api_key_and_url from polyapi.constants import PYTHON_TO_JSONSCHEMA_TYPE_MAP +# from polyapi.rendered_spec import update_rendered_spec from polyapi.utils import get_auth_headers, print_green, print_red, print_yellow import importlib @@ -270,6 +271,7 @@ def function_add_or_update( print(f"Function ID: {function_id}") print("Generating new custom function...", end="") functions = get_functions_and_parse(limit_ids=[function_id]) + # update_rendered_spec(functions[0]) generate_functions(functions) print_green("DONE") else: diff --git a/polyapi/generate.py b/polyapi/generate.py index de518e0..a4f429e 100644 --- a/polyapi/generate.py +++ b/polyapi/generate.py @@ -6,7 +6,6 @@ from polyapi.auth import render_auth_function from polyapi.client import render_client_function -from polyapi.execute import execute_post from polyapi.webhook import render_webhook_handle from .typedefs import PropertySpecification, SpecificationDto, VariableSpecDto @@ -157,24 +156,6 @@ def clear() -> None: print("Cleared!") -def save_rendered_specs() -> None: - specs = read_cached_specs() - # right now we just support rendered apiFunctions - api_specs = [spec for spec in specs if spec["type"] == "apiFunction"] - for spec in api_specs: - assert spec["function"] - func_str, type_defs = render_spec(spec) - data = { - "language": "python", - "apiFunctionId": spec["id"], - "signature": func_str, - "typedefs": type_defs, - } - resp = execute_post("/functions/rendered-specs", data) - print("adding", spec["context"], spec["name"]) - assert resp.status_code == 201, (resp.text, resp.status_code) - - def render_spec(spec: SpecificationDto): function_type = spec["type"] function_description = spec["description"] diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py new file mode 100644 index 0000000..f5e9543 --- /dev/null +++ b/polyapi/rendered_spec.py @@ -0,0 +1,34 @@ +from typing import Dict +from polyapi.generate import read_cached_specs, render_spec +from polyapi.execute import execute_post +from polyapi.typedefs import SpecificationDto + + +def update_rendered_spec(spec: SpecificationDto): + print("Updating rendered spec...") + func_str, type_defs = render_spec(spec) + data = { + "language": "python", + "signature": func_str, + "typedefs": type_defs, + } + if spec["type"] == "apiFunction": + data["apiFunctionId"] = spec["id"] + elif spec["type"] == "serverFunction": + data["customFunctionId"] = spec["id"] + else: + raise NotImplementedError("todo") + + resp = execute_post("/functions/rendered-specs", data) + assert resp.status_code == 201, (resp.text, resp.status_code) + # this needs to run with something like `kn func run...` + + +def save_rendered_specs() -> None: + specs = read_cached_specs() + # right now we just support rendered apiFunctions + api_specs = [spec for spec in specs if spec["type"] == "apiFunction"] + for spec in api_specs: + assert spec["function"] + print("adding", spec["context"], spec["name"]) + update_rendered_spec(spec) diff --git a/pyproject.toml b/pyproject.toml index 7cff949..d77e224 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev1" +version = "0.2.5.dev2" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ From 13e91b0242a06368b50b1ed495cdc0f2960a96fd Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Thu, 9 May 2024 09:12:32 -0700 Subject: [PATCH 03/16] dont force enums to be a str, they can be bool or int too --- polyapi/schema.py | 6 ++---- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/polyapi/schema.py b/polyapi/schema.py index 87d8c6b..3ebcc49 100644 --- a/polyapi/schema.py +++ b/polyapi/schema.py @@ -18,10 +18,8 @@ def _cleanup_input_for_gentypes(input_data: Dict): # jsonschema_gentypes doesn't like double quotes in enums # TODO fix this upstream for idx, enum in enumerate(v): - assert isinstance(enum, str) - v[idx] = enum.replace('"', "'") - - + if isinstance(enum, str): + v[idx] = enum.replace('"', "'") def _temp_store_input_data(input_data: Dict) -> str: diff --git a/pyproject.toml b/pyproject.toml index d77e224..2bf6a9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev2" +version = "0.2.5.dev3" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ From a3febf7a863aee43ef7148b2c811e7790f86d8f8 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Mon, 13 May 2024 10:26:57 -0700 Subject: [PATCH 04/16] add test for unknown dialect with https --- tests/test_schema.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/test_schema.py diff --git a/tests/test_schema.py b/tests/test_schema.py new file mode 100644 index 0000000..2908665 --- /dev/null +++ b/tests/test_schema.py @@ -0,0 +1,11 @@ +import unittest +from polyapi.schema import generate_schema_types + + +class T(unittest.TestCase): + def test_fix_titles(self): + # schema = json.loads(SCHEMA) + schema = {"$schema": "https://json-schema.org/draft-06/schema#"} + a, b = generate_schema_types(schema) + # shouldnt error with unknown dialect + self.assertTrue(b) \ No newline at end of file From 1691631f3495dbb9ec414284e4599221732ed1b8 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Tue, 14 May 2024 10:26:14 -0700 Subject: [PATCH 05/16] render2 (#14) * next version * woohoo tests are passing * geting there * next * next --- polyapi/cli.py | 16 ++++++++---- polyapi/rendered_spec.py | 29 ++++++++++++++++++++- pyproject.toml | 2 +- tests/test_rendered_spec.py | 52 +++++++++++++++++++++++++++++++++++++ tests/test_schema.py | 11 +++++--- 5 files changed, 99 insertions(+), 11 deletions(-) create mode 100644 tests/test_rendered_spec.py diff --git a/polyapi/cli.py b/polyapi/cli.py index ef2a2a9..cd0d2ac 100644 --- a/polyapi/cli.py +++ b/polyapi/cli.py @@ -5,10 +5,10 @@ from .config import clear_config, set_api_key_and_url from .generate import generate, clear from .function_cli import function_add_or_update -from .rendered_spec import save_rendered_specs +from .rendered_spec import get_and_update_rendered_spec -CLI_COMMANDS = ["setup", "generate", "function", "clear", "help", "save_rendered_specs"] +CLI_COMMANDS = ["setup", "generate", "function", "clear", "help", "update_rendered_spec"] CLIENT_DESC = """Commands python -m polyapi setup Setup your Poly connection @@ -18,7 +18,7 @@ """ -def execute_from_cli(): +def execute_from_cli() -> None: parser = argparse.ArgumentParser( prog="python -m polyapi", description=CLIENT_DESC, formatter_class=argparse.RawTextHelpFormatter ) @@ -43,8 +43,14 @@ def execute_from_cli(): elif command == "setup": clear_config() generate() - elif command == "save_rendered_specs": - save_rendered_specs() + elif command == "update_rendered_spec": + assert len(args.subcommands) == 2 + updated = get_and_update_rendered_spec(args.subcommands[0], args.subcommands[1]) + if updated: + print("Updated rendered spec!") + else: + print("Failed to update rendered spec!") + exit(1) elif command == "clear": print("Clearing the generated library...") clear() diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index f5e9543..5e2d8a5 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -1,4 +1,7 @@ -from typing import Dict +from typing import Dict, Optional + +import requests +from polyapi.config import get_api_key_and_url from polyapi.generate import read_cached_specs, render_spec from polyapi.execute import execute_post from polyapi.typedefs import SpecificationDto @@ -19,11 +22,35 @@ def update_rendered_spec(spec: SpecificationDto): else: raise NotImplementedError("todo") + # use super key on develop-k8s here! resp = execute_post("/functions/rendered-specs", data) assert resp.status_code == 201, (resp.text, resp.status_code) # this needs to run with something like `kn func run...` +def _get_spec(api_key: str, spec_id: str) -> Optional[SpecificationDto]: + _, base_url = get_api_key_and_url() + url = f"{base_url}/specs" + headers = {"Authorization": f"Bearer {api_key}"} + resp = requests.get(url, headers=headers) + if resp.status_code == 200: + specs = resp.json() + for spec in specs: + if spec['id'] == spec_id: + return spec + return None + else: + raise NotImplementedError(resp.content) + + +def get_and_update_rendered_spec(api_key: str, spec_id: str) -> bool: + spec = _get_spec(api_key, spec_id) + if spec: + update_rendered_spec(spec) + return True + return False + + def save_rendered_specs() -> None: specs = read_cached_specs() # right now we just support rendered apiFunctions diff --git a/pyproject.toml b/pyproject.toml index 2bf6a9c..8cbf9fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev3" +version = "0.2.5.dev4" 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_rendered_spec.py b/tests/test_rendered_spec.py new file mode 100644 index 0000000..73c5780 --- /dev/null +++ b/tests/test_rendered_spec.py @@ -0,0 +1,52 @@ +import unittest +from mock import patch, Mock + +from polyapi.rendered_spec import get_and_update_rendered_spec + +GET_PRODUCTS_COUNT = { + "id": "8f7d24b0-4a29-40c0-9091", + "type": "serverFunction", + "context": "test", + "name": "getProductsCount111", + "description": "An API call to retrieve the count of products in the product list.", + "requirements": ["snabbdom"], + "function": { + "arguments": [ + { + "name": "products", + "required": False, + "type": { + "kind": "array", + "items": {"kind": "primitive", "type": "string"}, + }, + } + ], + "returnType": {"kind": "plain", "value": "number"}, + "synchronous": True, + }, + "code": "", + "language": "javascript", + "visibilityMetadata": {"visibility": "ENVIRONMENT"}, +} + + +class T(unittest.TestCase): + @patch("polyapi.rendered_spec._get_spec") + def test_get_and_update_rendered_spec_fail(self, _get_spec): + """ pass in a bad id to update and make sure it returns False + """ + _get_spec.return_value = None + updated = get_and_update_rendered_spec("abc", "123") + self.assertEqual(_get_spec.call_count, 1) + self.assertFalse(updated) + + @patch("polyapi.rendered_spec.execute_post") + @patch("polyapi.rendered_spec._get_spec") + def test_get_and_update_rendered_spec_success(self, _get_spec, execute_post): + """ pass in a bad id to update and make sure it returns False + """ + _get_spec.return_value = GET_PRODUCTS_COUNT + execute_post.return_value = Mock(status_code=201, text="Created") + updated = get_and_update_rendered_spec("abc", "123") + self.assertEqual(_get_spec.call_count, 1) + self.assertTrue(updated) \ No newline at end of file diff --git a/tests/test_schema.py b/tests/test_schema.py index 2908665..965ac69 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -5,7 +5,10 @@ class T(unittest.TestCase): def test_fix_titles(self): # schema = json.loads(SCHEMA) - schema = {"$schema": "https://json-schema.org/draft-06/schema#"} - a, b = generate_schema_types(schema) - # shouldnt error with unknown dialect - self.assertTrue(b) \ No newline at end of file + schema = {"$schema": "http://json-schema.org/draft-06/schema#"} + try: + a, b = generate_schema_types(schema) + except AssertionError: + pass + + # should not throw with unknown dialect error \ No newline at end of file From e22da32e98e3a65fbb99e6f3b8fada7ab8e28915 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Tue, 14 May 2024 10:50:39 -0700 Subject: [PATCH 06/16] 0.2.5.dev5 release, update rendered specs fixes --- polyapi/rendered_spec.py | 12 +++++++----- pyproject.toml | 2 +- tests/test_rendered_spec.py | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index 5e2d8a5..72763fd 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -3,11 +3,10 @@ import requests from polyapi.config import get_api_key_and_url from polyapi.generate import read_cached_specs, render_spec -from polyapi.execute import execute_post from polyapi.typedefs import SpecificationDto -def update_rendered_spec(spec: SpecificationDto): +def update_rendered_spec(api_key: str, spec: SpecificationDto): print("Updating rendered spec...") func_str, type_defs = render_spec(spec) data = { @@ -23,7 +22,10 @@ def update_rendered_spec(spec: SpecificationDto): raise NotImplementedError("todo") # use super key on develop-k8s here! - resp = execute_post("/functions/rendered-specs", data) + _, base_url = get_api_key_and_url() + url = f"{base_url}/functions/rendered-specs" + headers = {"Authorization": f"Bearer {api_key}"} + resp = requests.post(url, json=data, headers=headers) assert resp.status_code == 201, (resp.text, resp.status_code) # this needs to run with something like `kn func run...` @@ -46,7 +48,7 @@ def _get_spec(api_key: str, spec_id: str) -> Optional[SpecificationDto]: def get_and_update_rendered_spec(api_key: str, spec_id: str) -> bool: spec = _get_spec(api_key, spec_id) if spec: - update_rendered_spec(spec) + update_rendered_spec(api_key, spec) return True return False @@ -58,4 +60,4 @@ def save_rendered_specs() -> None: for spec in api_specs: assert spec["function"] print("adding", spec["context"], spec["name"]) - update_rendered_spec(spec) + update_rendered_spec("FIXME", spec) diff --git a/pyproject.toml b/pyproject.toml index 8cbf9fe..405db2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev4" +version = "0.2.5.dev5" 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_rendered_spec.py b/tests/test_rendered_spec.py index 73c5780..9bf7003 100644 --- a/tests/test_rendered_spec.py +++ b/tests/test_rendered_spec.py @@ -40,13 +40,13 @@ def test_get_and_update_rendered_spec_fail(self, _get_spec): self.assertEqual(_get_spec.call_count, 1) self.assertFalse(updated) - @patch("polyapi.rendered_spec.execute_post") + @patch("polyapi.rendered_spec.requests.post") @patch("polyapi.rendered_spec._get_spec") - def test_get_and_update_rendered_spec_success(self, _get_spec, execute_post): + def test_get_and_update_rendered_spec_success(self, _get_spec, post): """ pass in a bad id to update and make sure it returns False """ _get_spec.return_value = GET_PRODUCTS_COUNT - execute_post.return_value = Mock(status_code=201, text="Created") + post.return_value = Mock(status_code=201, text="Created") updated = get_and_update_rendered_spec("abc", "123") self.assertEqual(_get_spec.call_count, 1) self.assertTrue(updated) \ No newline at end of file From b83edc3277b157ef7671d35f5ae77968698f563d Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Tue, 14 May 2024 12:34:58 -0700 Subject: [PATCH 07/16] fallback to local --- polyapi/rendered_spec.py | 4 ++++ pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index 72763fd..8a44037 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -23,6 +23,10 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): # use super key on develop-k8s here! _, base_url = get_api_key_and_url() + if not base_url: + # local node server runs on port 8000 + base_url = "http://localhost:8000" + url = f"{base_url}/functions/rendered-specs" headers = {"Authorization": f"Bearer {api_key}"} resp = requests.post(url, json=data, headers=headers) diff --git a/pyproject.toml b/pyproject.toml index 405db2d..b6ce18a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev5" +version = "0.2.5.dev6" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ From 30c797ead98e01c7bea098e48c28aa21c3e923a4 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Tue, 14 May 2024 13:02:41 -0700 Subject: [PATCH 08/16] one more fix --- polyapi/rendered_spec.py | 4 ++++ pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index 8a44037..8c0f030 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -36,6 +36,10 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): def _get_spec(api_key: str, spec_id: str) -> Optional[SpecificationDto]: _, base_url = get_api_key_and_url() + if not base_url: + # local node server runs on port 8000 + base_url = "http://localhost:8000" + url = f"{base_url}/specs" headers = {"Authorization": f"Bearer {api_key}"} resp = requests.get(url, headers=headers) diff --git a/pyproject.toml b/pyproject.toml index b6ce18a..fbe396a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev6" +version = "0.2.5.dev7" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ From 7e4fe6e7a492dfbf683880000fd391b8d1f6bd9a Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Tue, 14 May 2024 13:33:55 -0700 Subject: [PATCH 09/16] default to HOST_URL, not localhost --- polyapi/rendered_spec.py | 9 ++++----- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index 8c0f030..5bc77fd 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -1,4 +1,5 @@ -from typing import Dict, Optional +import os +from typing import Optional import requests from polyapi.config import get_api_key_and_url @@ -24,8 +25,7 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): # use super key on develop-k8s here! _, base_url = get_api_key_and_url() if not base_url: - # local node server runs on port 8000 - base_url = "http://localhost:8000" + base_url = os.environ.get("HOST_URL") url = f"{base_url}/functions/rendered-specs" headers = {"Authorization": f"Bearer {api_key}"} @@ -37,8 +37,7 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): def _get_spec(api_key: str, spec_id: str) -> Optional[SpecificationDto]: _, base_url = get_api_key_and_url() if not base_url: - # local node server runs on port 8000 - base_url = "http://localhost:8000" + base_url = os.environ.get("HOST_URL") url = f"{base_url}/specs" headers = {"Authorization": f"Bearer {api_key}"} diff --git a/pyproject.toml b/pyproject.toml index fbe396a..59a416f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev7" +version = "0.2.5.dev8" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ From 64679d1ca5f18a8ec129861ceecaea9a18396f65 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Wed, 15 May 2024 07:24:44 -0700 Subject: [PATCH 10/16] allow no title (#15) * next * next --- polyapi/schema.py | 16 ++++++++++++++++ polyapi/utils.py | 24 +++++------------------- pyproject.toml | 2 +- tests/test_schema.py | 24 +++++++++++++++--------- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/polyapi/schema.py b/polyapi/schema.py index 3ebcc49..04353a5 100644 --- a/polyapi/schema.py +++ b/polyapi/schema.py @@ -1,3 +1,4 @@ +import logging import contextlib from typing import Dict from jsonschema_gentypes.cli import process_config @@ -31,6 +32,21 @@ def _temp_store_input_data(input_data: Dict) -> str: return temp_file.name +def wrapped_generate_schema_types(type_spec: dict, root, fallback_type): + if not root: + root = "MyList" if fallback_type == "List" else "MyDict" + + try: + return clean_title(root), generate_schema_types(type_spec, root=root) + except RecursionError: + # some schemas are so huge, our library cant handle it + # TODO identify critical recursion penalty and maybe switch underlying logic to iterative? + return fallback_type, "" + except: + logging.exception(f"Error when generating schema type: {type_spec}") + return fallback_type, "" + + def generate_schema_types(input_data: Dict, root=None): """takes in a Dict representing a schema as input then appends the resulting python code to the output file""" _cleanup_input_for_gentypes(input_data) diff --git a/polyapi/utils.py b/polyapi/utils.py index bba3463..d7b105b 100644 --- a/polyapi/utils.py +++ b/polyapi/utils.py @@ -1,16 +1,16 @@ import re import os -import logging from typing import Tuple, List from colorama import Fore, Style from polyapi.constants import BASIC_PYTHON_TYPES from polyapi.typedefs import PropertySpecification, PropertyType -from polyapi.schema import generate_schema_types, clean_title, map_primitive_types +from polyapi.schema import wrapped_generate_schema_types, clean_title, map_primitive_types # this string should be in every __init__ file. # it contains all the imports needed for the function or variable code to run CODE_IMPORTS = "from typing import List, Dict, Any, TypedDict, Optional, Callable\nimport logging\nimport requests\nimport socketio # type: ignore\nfrom polyapi.config import get_api_key_and_url\nfrom polyapi.execute import execute, execute_post, variable_get, variable_update\n\n" +FALLBACK_TYPES = {"Dict", "List"} def init_the_init(full_path: str) -> None: @@ -96,11 +96,7 @@ def get_type_and_def(type_spec: PropertyType) -> Tuple[str, str]: if type_spec.get("items"): items = type_spec["items"] if items.get("$ref"): - try: - return "ResponseType", generate_schema_types(type_spec, root="ResponseType") # type: ignore - except: - logging.exception(f"Error when generating schema type: {type_spec}") - return "Dict", "" + return wrapped_generate_schema_types(type_spec, "ResponseType", "Dict") # type: ignore else: item_type, _ = get_type_and_def(items) title = f"List[{item_type}]" @@ -116,12 +112,7 @@ def get_type_and_def(type_spec: PropertyType) -> Tuple[str, str]: title = schema.get("title", "") if title: assert isinstance(title, str) - title = clean_title(title) - try: - return title, generate_schema_types(schema, root=title) # type: ignore - except: - logging.exception(f"Error when generating schema type: {schema}") - return "Dict", "" + return wrapped_generate_schema_types(schema, title, "Dict") # type: ignore elif schema.get("items"): # fallback to schema $ref name if no explicit title @@ -132,16 +123,11 @@ def get_type_and_def(type_spec: PropertyType) -> Tuple[str, str]: title = items.get("$ref", "") # type: ignore title = title.rsplit("/", 1)[-1] - title = clean_title(title) if not title: return "List", "" title = f"List[{title}]" - try: - return title, generate_schema_types(schema, root=title) - except: - logging.exception(f"Error when generating schema type: {schema}") - return "List", "" + return wrapped_generate_schema_types(schema, title, "List") else: return "Any", "" else: diff --git a/pyproject.toml b/pyproject.toml index 59a416f..989d5db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev8" +version = "0.2.5.dev9" 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_schema.py b/tests/test_schema.py index 965ac69..8602fd6 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -1,14 +1,20 @@ import unittest -from polyapi.schema import generate_schema_types +from polyapi.schema import wrapped_generate_schema_types + +SCHEMA = { + "$schema": "http://json-schema.org/draft-06/schema#", + "type": "object", + "properties": {"name": {"type": "string"}}, + "required": ["name"], + "additionalProperties": False, + "definitions": {}, +} class T(unittest.TestCase): def test_fix_titles(self): - # schema = json.loads(SCHEMA) - schema = {"$schema": "http://json-schema.org/draft-06/schema#"} - try: - a, b = generate_schema_types(schema) - except AssertionError: - pass - - # should not throw with unknown dialect error \ No newline at end of file + output = wrapped_generate_schema_types(SCHEMA, "", "Dict") + self.assertEqual("MyDict", output[0]) + self.assertIn("class MyDict", output[1]) + + # should not throw with unknown dialect error From 62b73d78fba6c990dbcec11d4b26086a8fe3043e Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Wed, 15 May 2024 09:54:02 -0700 Subject: [PATCH 11/16] 0.2.5.dev10, handle edge case with list named "List" --- polyapi/schema.py | 4 +++- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/polyapi/schema.py b/polyapi/schema.py index 04353a5..95293e2 100644 --- a/polyapi/schema.py +++ b/polyapi/schema.py @@ -36,8 +36,10 @@ def wrapped_generate_schema_types(type_spec: dict, root, fallback_type): if not root: root = "MyList" if fallback_type == "List" else "MyDict" + root = clean_title(root) + try: - return clean_title(root), generate_schema_types(type_spec, root=root) + return root, generate_schema_types(type_spec, root=root) except RecursionError: # some schemas are so huge, our library cant handle it # TODO identify critical recursion penalty and maybe switch underlying logic to iterative? diff --git a/pyproject.toml b/pyproject.toml index 989d5db..ca4b33a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev9" +version = "0.2.5.dev10" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ From 2690ff797ab75ddf69d7ba48e0a3480163c8abec Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Thu, 16 May 2024 06:52:35 -0700 Subject: [PATCH 12/16] 0.2.5.dev11, also update rendered spec for client functions --- polyapi/function_cli.py | 2 -- polyapi/rendered_spec.py | 3 ++- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/polyapi/function_cli.py b/polyapi/function_cli.py index 9e461c3..0cbbb7a 100644 --- a/polyapi/function_cli.py +++ b/polyapi/function_cli.py @@ -13,7 +13,6 @@ from polyapi.generate import get_functions_and_parse, generate_functions from polyapi.config import get_api_key_and_url from polyapi.constants import PYTHON_TO_JSONSCHEMA_TYPE_MAP -# from polyapi.rendered_spec import update_rendered_spec from polyapi.utils import get_auth_headers, print_green, print_red, print_yellow import importlib @@ -271,7 +270,6 @@ def function_add_or_update( print(f"Function ID: {function_id}") print("Generating new custom function...", end="") functions = get_functions_and_parse(limit_ids=[function_id]) - # update_rendered_spec(functions[0]) generate_functions(functions) print_green("DONE") else: diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index 5bc77fd..418f4b6 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -19,6 +19,8 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): data["apiFunctionId"] = spec["id"] elif spec["type"] == "serverFunction": data["customFunctionId"] = spec["id"] + elif spec["type"] == "clientFunction": + data["customFunctionId"] = spec["id"] else: raise NotImplementedError("todo") @@ -31,7 +33,6 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): headers = {"Authorization": f"Bearer {api_key}"} resp = requests.post(url, json=data, headers=headers) assert resp.status_code == 201, (resp.text, resp.status_code) - # this needs to run with something like `kn func run...` def _get_spec(api_key: str, spec_id: str) -> Optional[SpecificationDto]: diff --git a/pyproject.toml b/pyproject.toml index ca4b33a..4072280 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev10" +version = "0.2.5.dev11" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ From 2d94bab52dfbd9ed103ba8cd045fe3e19959f882 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Fri, 17 May 2024 07:04:38 -0700 Subject: [PATCH 13/16] wip --- polyapi/rendered_spec.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index 418f4b6..88b5f5d 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -21,6 +21,8 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): data["customFunctionId"] = spec["id"] elif spec["type"] == "clientFunction": data["customFunctionId"] = spec["id"] + elif spec["type"] == "webhookFunction": + data["webhookId"] = spec["id"] else: raise NotImplementedError("todo") From 7c3befcb68bffc9008a3afc080a9ed81652b8b69 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Fri, 17 May 2024 11:01:34 -0700 Subject: [PATCH 14/16] next --- polyapi/rendered_spec.py | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/polyapi/rendered_spec.py b/polyapi/rendered_spec.py index 88b5f5d..5b3a394 100644 --- a/polyapi/rendered_spec.py +++ b/polyapi/rendered_spec.py @@ -21,8 +21,8 @@ def update_rendered_spec(api_key: str, spec: SpecificationDto): data["customFunctionId"] = spec["id"] elif spec["type"] == "clientFunction": data["customFunctionId"] = spec["id"] - elif spec["type"] == "webhookFunction": - data["webhookId"] = spec["id"] + elif spec["type"] == "webhookHandle": + data["webhookHandleId"] = spec["id"] else: raise NotImplementedError("todo") diff --git a/pyproject.toml b/pyproject.toml index 4072280..b9129fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev11" +version = "0.2.5.dev12" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ From fec1ec5587da62e304ba33e0586199f2fec55db3 Mon Sep 17 00:00:00 2001 From: Dan Fellin Date: Wed, 22 May 2024 06:26:18 -0700 Subject: [PATCH 15/16] 0.2.5.dev13, update jsonschema_gentypes version --- polyapi/schema.py | 3 ++- pyproject.toml | 4 ++-- requirements.txt | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/polyapi/schema.py b/polyapi/schema.py index 95293e2..4633369 100644 --- a/polyapi/schema.py +++ b/polyapi/schema.py @@ -64,6 +64,7 @@ def generate_schema_types(input_data: Dict, root=None): "source": tmp_input, "destination": tmp_output, "root_name": root, + "api_arguments": {"get_name_properties": "UpperFirst"}, } ], } @@ -71,7 +72,7 @@ def generate_schema_types(input_data: Dict, root=None): # jsonschema_gentypes prints source to stdout # no option to surpress so we do this with contextlib.redirect_stdout(None): - process_config(config) + process_config(config, [tmp_input]) with open(tmp_output) as f: output = f.read() diff --git a/pyproject.toml b/pyproject.toml index b9129fe..f2fde89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,13 +3,13 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev12" +version = "0.2.5.dev13" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [ "requests==2.31.0", "typing_extensions==4.10.0", - "jsonschema-gentypes==2.4.0", + "jsonschema-gentypes==2.6.0", "pydantic==2.6.4", "stdlib_list==0.10.0", "colorama==0.4.4", diff --git a/requirements.txt b/requirements.txt index c5060d1..3e890b0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ requests==2.31.0 typing_extensions==4.10.0 -jsonschema-gentypes==2.4.0 +jsonschema-gentypes==2.6.0 pydantic==2.6.4 stdlib_list==0.10.0 colorama==0.4.4 From 5e95a86ee98130a07ea6c6297f0394512a925007 Mon Sep 17 00:00:00 2001 From: FedeMarchiniHotovo <130762770+FedeMarchiniHotovo@users.noreply.github.com> Date: Wed, 29 May 2024 11:22:07 -0300 Subject: [PATCH 16/16] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f2fde89..376e0e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.2.5.dev13" +version = "0.2.5" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [