diff --git a/.gitignore b/.gitignore index 49ae8f4..135534e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ -.env -.env* -.venv/ -.venv/* +*env +*venv .DS_Store # Pip diff --git a/polyapi/cli.py b/polyapi/cli.py index 347dc1a..7299841 100644 --- a/polyapi/cli.py +++ b/polyapi/cli.py @@ -45,10 +45,12 @@ def setup(args): # Generate command generate_parser = subparsers.add_parser("generate", help="Generates Poly library") generate_parser.add_argument("--no-types", action="store_true", help="Generate SDK without type definitions") + generate_parser.add_argument("--contexts", type=str, required=False, help="Contexts to generate") def generate_command(args): initialize_config() - generate(no_types=args.no_types) + contexts = args.contexts.split(",") if args.contexts else None + generate(contexts=contexts, no_types=args.no_types) generate_parser.set_defaults(command=generate_command) @@ -69,6 +71,7 @@ def generate_command(args): fn_add_parser.add_argument("--logs", choices=["enabled", "disabled"], default=None, help="Enable or disable logs for the function.") fn_add_parser.add_argument("--execution-api-key", required=False, default="", help="API key for execution (for server functions only).") fn_add_parser.add_argument("--disable-ai", "--skip-generate", action="store_true", help="Pass --disable-ai skip AI generation of missing descriptions") + fn_add_parser.add_argument("--generate-contexts", type=str, help="Server function only – only include certain contexts to speed up function execution") def add_function(args): initialize_config() @@ -80,6 +83,8 @@ def add_function(args): err = "You must specify `--server` or `--client`." elif logs_enabled and not args.server: err = "Option `logs` is only for server functions (--server)." + elif args.generate_contexts and not args.server: + err = "Option `generate-contexts` is only for server functions (--server)." if err: print_red("ERROR") @@ -95,7 +100,8 @@ def add_function(args): server=args.server, logs_enabled=logs_enabled, generate=not args.disable_ai, - execution_api_key=args.execution_api_key + execution_api_key=args.execution_api_key, + generate_contexts=args.generate_contexts ) fn_add_parser.set_defaults(command=add_function) diff --git a/polyapi/config.py b/polyapi/config.py index 2d8dedf..4b0e856 100644 --- a/polyapi/config.py +++ b/polyapi/config.py @@ -3,7 +3,7 @@ import configparser from typing import Tuple -from polyapi.utils import is_valid_polyapi_url, is_valid_uuid, print_green, print_yellow +from polyapi.utils import is_valid_polyapi_url, print_green, print_yellow # cached values API_KEY = None @@ -78,8 +78,6 @@ def initialize_config(force=False): errors = [] if not is_valid_polyapi_url(url): errors.append(f"{url} is not a valid Poly API Base URL") - if not is_valid_uuid(key): - errors.append(f"{key} is not a valid Poly App Key or User Key") if errors: print_yellow("\n".join(errors)) sys.exit(1) diff --git a/polyapi/function_cli.py b/polyapi/function_cli.py index bc836fa..b888d08 100644 --- a/polyapi/function_cli.py +++ b/polyapi/function_cli.py @@ -24,6 +24,7 @@ def function_add_or_update( client: bool, server: bool, logs_enabled: Optional[bool], + generate_contexts: Optional[str], generate: bool = True, execution_api_key: str = "" ): @@ -59,6 +60,9 @@ def function_add_or_update( "logsEnabled": logs_enabled, } + if generate_contexts: + data["generateContexts"] = generate_contexts.split(",") + if server and parsed["dependencies"]: print_yellow( "\nPlease note that deploying your functions will take a few minutes because it makes use of libraries other than polyapi." @@ -87,7 +91,8 @@ def function_add_or_update( function_id = resp.json()["id"] print(f"Function ID: {function_id}") if generate: - generate_library() + contexts=generate_contexts.split(",") if generate_contexts else None + generate_library(contexts=contexts) else: print("Error adding function.") print(resp.status_code) diff --git a/polyapi/generate.py b/polyapi/generate.py index cfc6cfa..20b9b36 100644 --- a/polyapi/generate.py +++ b/polyapi/generate.py @@ -2,7 +2,7 @@ import requests import os import shutil -from typing import List, Tuple, cast +from typing import List, Optional, Tuple, cast from .auth import render_auth_function from .client import render_client_function @@ -36,12 +36,16 @@ path:''' -def get_specs(no_types: bool = False) -> List: +def get_specs(contexts=Optional[List[str]], no_types: bool = False) -> List: api_key, api_url = get_api_key_and_url() assert api_key headers = get_auth_headers(api_key) url = f"{api_url}/specs" params = {"noTypes": str(no_types).lower()} + + if contexts: + params["contexts"] = contexts + resp = requests.get(url, headers=headers, params=params) if resp.status_code == 200: return resp.json() @@ -197,11 +201,12 @@ def remove_old_library(): shutil.rmtree(path) -def generate(no_types: bool = False) -> None: - print("Generating Poly Python SDK...", end="", flush=True) +def generate(contexts: Optional[List[str]], no_types: bool = False) -> None: + generate_msg = f"Generating Poly Python SDK for contexts ${contexts}..." if contexts else "Generating Poly Python SDK..." + print(generate_msg, end="", flush=True) remove_old_library() - specs = get_specs(no_types=no_types) + specs = get_specs(no_types=no_types, contexts=contexts) cache_specs(specs) limit_ids: List[str] = [] # useful for narrowing down generation to a single function to debug diff --git a/polyapi/utils.py b/polyapi/utils.py index e09383d..642ec51 100644 --- a/polyapi/utils.py +++ b/polyapi/utils.py @@ -2,6 +2,7 @@ import re import os import uuid +from urllib.parse import urlparse from typing import Tuple, List from colorama import Fore, Style from polyapi.constants import BASIC_PYTHON_TYPES @@ -261,21 +262,16 @@ def rewrite_arg_name(s: str): def is_valid_polyapi_url(_url: str): + # in dev allow localhost (and 127.0.0.1) over http *or* https + parsed = urlparse(_url) + if parsed.scheme in ("http", "https") and parsed.hostname in ("localhost", "127.0.0.1"): + return True + # Join the subdomains into a pattern subdomain_pattern = "|".join(valid_subdomains) pattern = rf"^https://({subdomain_pattern})\.polyapi\.io$" return re.match(pattern, _url) is not None - -def is_valid_uuid(uuid_string, version=4): - try: - uuid_obj = uuid.UUID(uuid_string, version=version) - except ValueError: - return False - - return str(uuid_obj) == uuid_string - - def return_type_already_defined_in_args(return_type_name: str, args_def: str) -> bool: """ Checks if the return_type_name preceded optionally by 'class ' and followed by ' =' exists in args_def. diff --git a/pyproject.toml b/pyproject.toml index 0df59df..8b3e587 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.2", "wheel"] [project] name = "polyapi-python" -version = "0.3.4.dev2" +version = "0.3.5.dev0" description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers" authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }] dependencies = [