Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion polyapi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def setup(args):
set_api_key_and_url(args.url, args.api_key)
else:
initialize_config(force=True)
# setup command should have default cache values
from .config import cache_generate_args
cache_generate_args(contexts=None, names=None, function_ids=None, no_types=False)
generate()

setup_parser.set_defaults(command=setup)
Expand All @@ -46,11 +49,34 @@ def setup(args):
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")
generate_parser.add_argument("--names", type=str, required=False, help="Resource names to generate (comma-separated)")
generate_parser.add_argument("--function-ids", type=str, required=False, help="Function IDs to generate (comma-separated)")
Comment on lines +52 to +53
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. 👍


def generate_command(args):
from .config import cache_generate_args

initialize_config()

contexts = args.contexts.split(",") if args.contexts else None
generate(contexts=contexts, no_types=args.no_types)
names = args.names.split(",") if args.names else None
function_ids = args.function_ids.split(",") if args.function_ids else None
no_types = args.no_types

# overwrite all cached values with the values passed in from the command line
final_contexts = contexts
final_names = names
final_function_ids = function_ids
final_no_types = no_types

# cache the values used for this explicit generate command
cache_generate_args(
contexts=final_contexts,
names=final_names,
function_ids=final_function_ids,
no_types=final_no_types
)

generate(contexts=final_contexts, names=final_names, function_ids=final_function_ids, no_types=final_no_types)

generate_parser.set_defaults(command=generate_command)

Expand Down
70 changes: 69 additions & 1 deletion polyapi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
MTLS_CERT_PATH = None
MTLS_KEY_PATH = None
MTLS_CA_PATH = None
LAST_GENERATE_CONTEXTS = None
LAST_GENERATE_NAMES = None
LAST_GENERATE_FUNCTION_IDS = None
LAST_GENERATE_NO_TYPES = None


def get_config_file_path() -> str:
Expand Down Expand Up @@ -55,6 +59,16 @@ def get_api_key_and_url() -> Tuple[str | None, str | None]:
MTLS_CERT_PATH = config.get("polyapi", "mtls_cert_path", fallback=None)
MTLS_KEY_PATH = config.get("polyapi", "mtls_key_path", fallback=None)
MTLS_CA_PATH = config.get("polyapi", "mtls_ca_path", fallback=None)

# Read and cache generate command arguments
global LAST_GENERATE_CONTEXTS, LAST_GENERATE_NAMES, LAST_GENERATE_FUNCTION_IDS, LAST_GENERATE_NO_TYPES
contexts_str = config.get("polyapi", "last_generate_contexts_used", fallback=None)
LAST_GENERATE_CONTEXTS = contexts_str.split(",") if contexts_str else None
names_str = config.get("polyapi", "last_generate_names_used", fallback=None)
LAST_GENERATE_NAMES = names_str.split(",") if names_str else None
function_ids_str = config.get("polyapi", "last_generate_function_ids_used", fallback=None)
LAST_GENERATE_FUNCTION_IDS = function_ids_str.split(",") if function_ids_str else None
LAST_GENERATE_NO_TYPES = config.get("polyapi", "last_generate_no_types_used", fallback="false").lower() == "true"

return key, url

Expand Down Expand Up @@ -133,4 +147,58 @@ def get_direct_execute_config() -> bool:
if API_FUNCTION_DIRECT_EXECUTE is None:
# Force a config read if value isn't cached
get_api_key_and_url()
return bool(API_FUNCTION_DIRECT_EXECUTE)
return bool(API_FUNCTION_DIRECT_EXECUTE)


def get_cached_generate_args() -> Tuple[list | None, list | None, list | None, bool]:
"""Return cached generate command arguments"""
global LAST_GENERATE_CONTEXTS, LAST_GENERATE_NAMES, LAST_GENERATE_FUNCTION_IDS, LAST_GENERATE_NO_TYPES
if LAST_GENERATE_CONTEXTS is None and LAST_GENERATE_NAMES is None and LAST_GENERATE_FUNCTION_IDS is None and LAST_GENERATE_NO_TYPES is None:
# Force a config read if values aren't cached
get_api_key_and_url()
return LAST_GENERATE_CONTEXTS, LAST_GENERATE_NAMES, LAST_GENERATE_FUNCTION_IDS, bool(LAST_GENERATE_NO_TYPES)


def cache_generate_args(contexts: list | None = None, names: list | None = None, function_ids: list | None = None, no_types: bool = False):
"""Cache generate command arguments to config file"""
from typing import List

# Read existing config
path = get_config_file_path()
config = configparser.ConfigParser()

if os.path.exists(path):
with open(path, "r") as f:
config.read_file(f)

# Ensure polyapi section exists
if "polyapi" not in config:
config["polyapi"] = {}

# Update cached values
global LAST_GENERATE_CONTEXTS, LAST_GENERATE_NAMES, LAST_GENERATE_FUNCTION_IDS, LAST_GENERATE_NO_TYPES
LAST_GENERATE_CONTEXTS = contexts
LAST_GENERATE_NAMES = names
LAST_GENERATE_FUNCTION_IDS = function_ids
LAST_GENERATE_NO_TYPES = no_types

# Write values to config
if contexts is not None:
config.set("polyapi", "last_generate_contexts_used", ",".join(contexts))
elif config.has_option("polyapi", "last_generate_contexts_used"):
config.remove_option("polyapi", "last_generate_contexts_used")

if names is not None:
config.set("polyapi", "last_generate_names_used", ",".join(names))
elif config.has_option("polyapi", "last_generate_names_used"):
config.remove_option("polyapi", "last_generate_names_used")

if function_ids is not None:
config.set("polyapi", "last_generate_function_ids_used", ",".join(function_ids))
elif config.has_option("polyapi", "last_generate_function_ids_used"):
config.remove_option("polyapi", "last_generate_function_ids_used")

config.set("polyapi", "last_generate_no_types_used", str(no_types).lower())

with open(path, "w") as f:
config.write(f)
6 changes: 4 additions & 2 deletions polyapi/function_cli.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sys
from typing import Any, List, Optional
import requests
from polyapi.generate import generate as generate_library

from polyapi.config import get_api_key_and_url
from polyapi.utils import get_auth_headers, print_green, print_red, print_yellow
from polyapi.parser import parse_function_code, get_jsonschema_type
Expand Down Expand Up @@ -91,7 +91,9 @@ def function_add_or_update(
function_id = resp.json()["id"]
print(f"Function ID: {function_id}")
if generate:
generate_library()
# Use cached generate arguments when regenerating after function deployment
from polyapi.generate import generate_from_cache
generate_from_cache()
else:
print("Error adding function.")
print(resp.status_code)
Expand Down
28 changes: 24 additions & 4 deletions polyapi/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .server import render_server_function
from .utils import add_import_to_init, get_auth_headers, init_the_init, print_green, to_func_namespace
from .variables import generate_variables
from .config import get_api_key_and_url, get_direct_execute_config
from .config import get_api_key_and_url, get_direct_execute_config, get_cached_generate_args

SUPPORTED_FUNCTION_TYPES = {
"apiFunction",
Expand All @@ -36,7 +36,7 @@
path:'''


def get_specs(contexts=Optional[List[str]], no_types: bool = False) -> List:
def get_specs(contexts: Optional[List[str]] = None, names: Optional[List[str]] = None, function_ids: Optional[List[str]] = None, no_types: bool = False) -> List:
api_key, api_url = get_api_key_and_url()
assert api_key
headers = get_auth_headers(api_key)
Expand All @@ -45,6 +45,12 @@ def get_specs(contexts=Optional[List[str]], no_types: bool = False) -> List:

if contexts:
params["contexts"] = contexts

if names:
params["names"] = names

if function_ids:
params["functionIds"] = function_ids
Comment on lines +48 to +53
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


# Add apiFunctionDirectExecute parameter if direct execute is enabled
if get_direct_execute_config():
Expand Down Expand Up @@ -264,12 +270,26 @@ def __class_getitem__(cls, item):
''')


def generate(contexts: Optional[List[str]] = None, no_types: bool = False) -> None:
def generate_from_cache() -> None:
"""
Generate using cached values after non-explicit call.
"""
cached_contexts, cached_names, cached_function_ids, cached_no_types = get_cached_generate_args()

generate(
contexts=cached_contexts,
names=cached_names,
function_ids=cached_function_ids,
no_types=cached_no_types
)


def generate(contexts: Optional[List[str]] = None, names: Optional[List[str]] = None, function_ids: Optional[List[str]] = None, 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, contexts=contexts)
specs = get_specs(contexts=contexts, names=names, function_ids=function_ids, no_types=no_types)
cache_specs(specs)

limit_ids: List[str] = [] # useful for narrowing down generation to a single function to debug
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ requires = ["setuptools>=61.2", "wheel"]

[project]
name = "polyapi-python"
version = "0.3.8.dev1"
version = "0.3.8.dev2"
description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers"
authors = [{ name = "Dan Fellin", email = "dan@polyapi.io" }]
dependencies = [
"requests>=2.32.3",
"typing_extensions>=4.12.2",
"jsonschema-gentypes==2.6.0",
"pydantic==2.6.4",
"pydantic>=2.6.4",
"stdlib_list==0.10.0",
"colorama==0.4.4",
"python-socketio[asyncio_client]==5.11.1",
Expand Down