Skip to content

Commit 391871a

Browse files
Ash1RAshir Rao
andauthored
4523 fix python client to save generate command arguments and reuse them (#53)
* Add caching for all arguments, add names and function-ids arguments * Fix restrictiveness logic to work on all arguments * Only use cache when indirectly generated * initialize cache with generate * initialize cache to generate * Update toml and config * Restore Generating... print message --------- Co-authored-by: Ashir Rao <[email protected]>
1 parent 19c5613 commit 391871a

File tree

5 files changed

+126
-10
lines changed

5 files changed

+126
-10
lines changed

polyapi/cli.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ def setup(args):
3636
set_api_key_and_url(args.url, args.api_key)
3737
else:
3838
initialize_config(force=True)
39+
# setup command should have default cache values
40+
from .config import cache_generate_args
41+
cache_generate_args(contexts=None, names=None, function_ids=None, no_types=False)
3942
generate()
4043

4144
setup_parser.set_defaults(command=setup)
@@ -46,11 +49,34 @@ def setup(args):
4649
generate_parser = subparsers.add_parser("generate", help="Generates Poly library")
4750
generate_parser.add_argument("--no-types", action="store_true", help="Generate SDK without type definitions")
4851
generate_parser.add_argument("--contexts", type=str, required=False, help="Contexts to generate")
52+
generate_parser.add_argument("--names", type=str, required=False, help="Resource names to generate (comma-separated)")
53+
generate_parser.add_argument("--function-ids", type=str, required=False, help="Function IDs to generate (comma-separated)")
4954

5055
def generate_command(args):
56+
from .config import cache_generate_args
57+
5158
initialize_config()
59+
5260
contexts = args.contexts.split(",") if args.contexts else None
53-
generate(contexts=contexts, no_types=args.no_types)
61+
names = args.names.split(",") if args.names else None
62+
function_ids = args.function_ids.split(",") if args.function_ids else None
63+
no_types = args.no_types
64+
65+
# overwrite all cached values with the values passed in from the command line
66+
final_contexts = contexts
67+
final_names = names
68+
final_function_ids = function_ids
69+
final_no_types = no_types
70+
71+
# cache the values used for this explicit generate command
72+
cache_generate_args(
73+
contexts=final_contexts,
74+
names=final_names,
75+
function_ids=final_function_ids,
76+
no_types=final_no_types
77+
)
78+
79+
generate(contexts=final_contexts, names=final_names, function_ids=final_function_ids, no_types=final_no_types)
5480

5581
generate_parser.set_defaults(command=generate_command)
5682

polyapi/config.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
MTLS_CERT_PATH = None
1313
MTLS_KEY_PATH = None
1414
MTLS_CA_PATH = None
15+
LAST_GENERATE_CONTEXTS = None
16+
LAST_GENERATE_NAMES = None
17+
LAST_GENERATE_FUNCTION_IDS = None
18+
LAST_GENERATE_NO_TYPES = None
1519

1620

1721
def get_config_file_path() -> str:
@@ -55,6 +59,16 @@ def get_api_key_and_url() -> Tuple[str | None, str | None]:
5559
MTLS_CERT_PATH = config.get("polyapi", "mtls_cert_path", fallback=None)
5660
MTLS_KEY_PATH = config.get("polyapi", "mtls_key_path", fallback=None)
5761
MTLS_CA_PATH = config.get("polyapi", "mtls_ca_path", fallback=None)
62+
63+
# Read and cache generate command arguments
64+
global LAST_GENERATE_CONTEXTS, LAST_GENERATE_NAMES, LAST_GENERATE_FUNCTION_IDS, LAST_GENERATE_NO_TYPES
65+
contexts_str = config.get("polyapi", "last_generate_contexts_used", fallback=None)
66+
LAST_GENERATE_CONTEXTS = contexts_str.split(",") if contexts_str else None
67+
names_str = config.get("polyapi", "last_generate_names_used", fallback=None)
68+
LAST_GENERATE_NAMES = names_str.split(",") if names_str else None
69+
function_ids_str = config.get("polyapi", "last_generate_function_ids_used", fallback=None)
70+
LAST_GENERATE_FUNCTION_IDS = function_ids_str.split(",") if function_ids_str else None
71+
LAST_GENERATE_NO_TYPES = config.get("polyapi", "last_generate_no_types_used", fallback="false").lower() == "true"
5872

5973
return key, url
6074

@@ -133,4 +147,58 @@ def get_direct_execute_config() -> bool:
133147
if API_FUNCTION_DIRECT_EXECUTE is None:
134148
# Force a config read if value isn't cached
135149
get_api_key_and_url()
136-
return bool(API_FUNCTION_DIRECT_EXECUTE)
150+
return bool(API_FUNCTION_DIRECT_EXECUTE)
151+
152+
153+
def get_cached_generate_args() -> Tuple[list | None, list | None, list | None, bool]:
154+
"""Return cached generate command arguments"""
155+
global LAST_GENERATE_CONTEXTS, LAST_GENERATE_NAMES, LAST_GENERATE_FUNCTION_IDS, LAST_GENERATE_NO_TYPES
156+
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:
157+
# Force a config read if values aren't cached
158+
get_api_key_and_url()
159+
return LAST_GENERATE_CONTEXTS, LAST_GENERATE_NAMES, LAST_GENERATE_FUNCTION_IDS, bool(LAST_GENERATE_NO_TYPES)
160+
161+
162+
def cache_generate_args(contexts: list | None = None, names: list | None = None, function_ids: list | None = None, no_types: bool = False):
163+
"""Cache generate command arguments to config file"""
164+
from typing import List
165+
166+
# Read existing config
167+
path = get_config_file_path()
168+
config = configparser.ConfigParser()
169+
170+
if os.path.exists(path):
171+
with open(path, "r") as f:
172+
config.read_file(f)
173+
174+
# Ensure polyapi section exists
175+
if "polyapi" not in config:
176+
config["polyapi"] = {}
177+
178+
# Update cached values
179+
global LAST_GENERATE_CONTEXTS, LAST_GENERATE_NAMES, LAST_GENERATE_FUNCTION_IDS, LAST_GENERATE_NO_TYPES
180+
LAST_GENERATE_CONTEXTS = contexts
181+
LAST_GENERATE_NAMES = names
182+
LAST_GENERATE_FUNCTION_IDS = function_ids
183+
LAST_GENERATE_NO_TYPES = no_types
184+
185+
# Write values to config
186+
if contexts is not None:
187+
config.set("polyapi", "last_generate_contexts_used", ",".join(contexts))
188+
elif config.has_option("polyapi", "last_generate_contexts_used"):
189+
config.remove_option("polyapi", "last_generate_contexts_used")
190+
191+
if names is not None:
192+
config.set("polyapi", "last_generate_names_used", ",".join(names))
193+
elif config.has_option("polyapi", "last_generate_names_used"):
194+
config.remove_option("polyapi", "last_generate_names_used")
195+
196+
if function_ids is not None:
197+
config.set("polyapi", "last_generate_function_ids_used", ",".join(function_ids))
198+
elif config.has_option("polyapi", "last_generate_function_ids_used"):
199+
config.remove_option("polyapi", "last_generate_function_ids_used")
200+
201+
config.set("polyapi", "last_generate_no_types_used", str(no_types).lower())
202+
203+
with open(path, "w") as f:
204+
config.write(f)

polyapi/function_cli.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import sys
22
from typing import Any, List, Optional
33
import requests
4-
from polyapi.generate import generate as generate_library
4+
55
from polyapi.config import get_api_key_and_url
66
from polyapi.utils import get_auth_headers, print_green, print_red, print_yellow
77
from polyapi.parser import parse_function_code, get_jsonschema_type
@@ -91,7 +91,9 @@ def function_add_or_update(
9191
function_id = resp.json()["id"]
9292
print(f"Function ID: {function_id}")
9393
if generate:
94-
generate_library()
94+
# Use cached generate arguments when regenerating after function deployment
95+
from polyapi.generate import generate_from_cache
96+
generate_from_cache()
9597
else:
9698
print("Error adding function.")
9799
print(resp.status_code)

polyapi/generate.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from .server import render_server_function
1515
from .utils import add_import_to_init, get_auth_headers, init_the_init, print_green, to_func_namespace
1616
from .variables import generate_variables
17-
from .config import get_api_key_and_url, get_direct_execute_config
17+
from .config import get_api_key_and_url, get_direct_execute_config, get_cached_generate_args
1818

1919
SUPPORTED_FUNCTION_TYPES = {
2020
"apiFunction",
@@ -36,7 +36,7 @@
3636
path:'''
3737

3838

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

4646
if contexts:
4747
params["contexts"] = contexts
48+
49+
if names:
50+
params["names"] = names
51+
52+
if function_ids:
53+
params["functionIds"] = function_ids
4854

4955
# Add apiFunctionDirectExecute parameter if direct execute is enabled
5056
if get_direct_execute_config():
@@ -264,12 +270,26 @@ def __class_getitem__(cls, item):
264270
''')
265271

266272

267-
def generate(contexts: Optional[List[str]] = None, no_types: bool = False) -> None:
273+
def generate_from_cache() -> None:
274+
"""
275+
Generate using cached values after non-explicit call.
276+
"""
277+
cached_contexts, cached_names, cached_function_ids, cached_no_types = get_cached_generate_args()
278+
279+
generate(
280+
contexts=cached_contexts,
281+
names=cached_names,
282+
function_ids=cached_function_ids,
283+
no_types=cached_no_types
284+
)
285+
286+
287+
def generate(contexts: Optional[List[str]] = None, names: Optional[List[str]] = None, function_ids: Optional[List[str]] = None, no_types: bool = False) -> None:
268288
generate_msg = f"Generating Poly Python SDK for contexts ${contexts}..." if contexts else "Generating Poly Python SDK..."
269289
print(generate_msg, end="", flush=True)
270290
remove_old_library()
271291

272-
specs = get_specs(no_types=no_types, contexts=contexts)
292+
specs = get_specs(contexts=contexts, names=names, function_ids=function_ids, no_types=no_types)
273293
cache_specs(specs)
274294

275295
limit_ids: List[str] = [] # useful for narrowing down generation to a single function to debug

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ requires = ["setuptools>=61.2", "wheel"]
33

44
[project]
55
name = "polyapi-python"
6-
version = "0.3.8.dev1"
6+
version = "0.3.8.dev2"
77
description = "The Python Client for PolyAPI, the IPaaS by Developers for Developers"
88
authors = [{ name = "Dan Fellin", email = "[email protected]" }]
99
dependencies = [
1010
"requests>=2.32.3",
1111
"typing_extensions>=4.12.2",
1212
"jsonschema-gentypes==2.6.0",
13-
"pydantic==2.6.4",
13+
"pydantic>=2.6.4",
1414
"stdlib_list==0.10.0",
1515
"colorama==0.4.4",
1616
"python-socketio[asyncio_client]==5.11.1",

0 commit comments

Comments
 (0)