Skip to content
Merged

R24 #69

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
2a4b538
# Feature (2970): Update python client to support setup command (#22)
sudiptatj Oct 31, 2024
8723978
improve polyapi-python setup (#24)
eupharis Nov 4, 2024
7ece4d0
# Feature (3007): Update python -m polyapi function add --logs option…
sudiptatj Nov 4, 2024
e292e4e
Project Glide + Refactor main command line args parsing (#26)
aarongoin Nov 14, 2024
cd89d8a
fix for poly cache directory path construction
aarongoin Nov 18, 2024
a8c2f52
one more adjustment to the deployables cache directory so there can't…
aarongoin Nov 18, 2024
4a0277a
this better?
aarongoin Nov 18, 2024
571e85a
verbose logging on upload code to see what's failing in CI/CD
aarongoin Nov 18, 2024
dbbbe61
bumpity
aarongoin Nov 18, 2024
c03268e
whoops
aarongoin Nov 18, 2024
64c2e37
so close
aarongoin Nov 18, 2024
2f71748
better?
aarongoin Nov 18, 2024
57a2d40
okay this should be the fix
aarongoin Nov 18, 2024
0e78bd3
is it this?
aarongoin Nov 18, 2024
30b2a28
maybe
aarongoin Nov 18, 2024
156d3df
oh for the love of pete
aarongoin Nov 18, 2024
20d8982
whatever. might be a pypi issue
aarongoin Nov 19, 2024
37b421b
removing verbose logging
aarongoin Nov 19, 2024
4cc8a16
fixing bugs in sync command to use correct api urls
aarongoin Nov 19, 2024
aa0be64
update logging
aarongoin Nov 19, 2024
db8aec6
lint
aarongoin Nov 19, 2024
32a65d1
improved auth
aarongoin Nov 19, 2024
14cf1ce
last fix for function sync
aarongoin Nov 19, 2024
9d4824a
fix bug when comment arguments don't align with the function
aarongoin Nov 19, 2024
ffe19f0
try forcing the poly directory to exist
aarongoin Nov 20, 2024
0d32c4a
test logging
aarongoin Nov 20, 2024
8bbb2c7
remove debug logging
aarongoin Nov 20, 2024
2808c97
fixing project glide deployable types and bumping the version
aarongoin Nov 22, 2024
123f0b7
fixing missing arguments in python client function upload
aarongoin Nov 22, 2024
7dc7afe
fixing return type for trained functions
aarongoin Nov 22, 2024
e117f1e
fix bug preventing use of poly sync command locally
aarongoin Nov 22, 2024
d4a656f
next version of client!
eupharis Nov 26, 2024
7441019
EN #3183 allow null logs flag for python client (#28)
eneumann Dec 5, 2024
57e7369
let the typing_extensions versions increase to support latest openai …
eupharis Dec 6, 2024
03fd34c
update dependency in one more place
eupharis Dec 6, 2024
28a1c39
Some bug fixes for python client (#29)
aarongoin Dec 14, 2024
027ceb5
Merge branch 'main' into develop
eupharis Dec 23, 2024
4ff9ba9
0.3.2
eupharis Dec 23, 2024
e895ae9
add poly schemas support (#31)
eupharis Mar 24, 2025
d189377
update to v4
eupharis Mar 24, 2025
a140802
v4 everywhere
eupharis Mar 24, 2025
96f63c3
bump version
eupharis Mar 24, 2025
15eab87
add new version
eupharis Mar 24, 2025
3ad2607
remove warning, just go with any type for now
eupharis Mar 26, 2025
1479d39
better generate printed messages, fix generate bug after function add
eupharis Mar 26, 2025
7db1cbe
Update python version (#32)
dchiniquy Mar 27, 2025
a3f09cd
Update python image (#33)
dchiniquy Mar 27, 2025
19fafde
Rollback version
nahuel-polyapi Mar 27, 2025
fccbf1e
onward (#34)
eupharis Apr 8, 2025
1e947d6
next (#35)
eupharis Apr 8, 2025
11108e0
improve intellisense detection of schemas
eupharis Apr 11, 2025
ef7e5e9
release 0.3.3.dev8, fix misleading generate after setup
eupharis Apr 14, 2025
71e2332
0.3.3.dev9 - add support for optional arguments (#36)
eupharis Apr 14, 2025
2b4a2d0
next
eupharis Apr 15, 2025
2169e15
release 0.3.3.dev10
eupharis Apr 15, 2025
c2db3e9
EN #3943 update to support SFX serverSideAsync True by setting correc…
eneumann May 2, 2025
2fc69ea
deploying version 0.3.3 for R22
nahuel-polyapi May 6, 2025
1e683f2
Merge branch 'main' into develop
eupharis May 6, 2025
a4a4872
upgrade version
FedeMarchiniHotovo May 6, 2025
e0e74b7
Merge branch 'main' into develop
FedeMarchiniHotovo May 6, 2025
a6ba2f3
4084 - revert strippping none values from function arguments during e…
akinboboye May 7, 2025
9c1a2a1
P2) Update clients and specs endpoint so when generating with no-type…
RichardDzurus May 7, 2025
d20794b
4010 generate contexts (#43)
akinboboye May 8, 2025
d02bae3
make contexts truly optional
eupharis May 12, 2025
bf238b2
P3) (Optoro) Allow variable to be secret in the UI, but gettable in f…
RichardDzurus May 13, 2025
78d4b15
add generate contexts (#45)
akinboboye May 15, 2025
ebf6e6b
adds mtls and direct execute options (#44)
RichardDzurus May 22, 2025
938dfdd
polyCustom - prevent rewrites of executionId (#46)
RichardDzurus May 26, 2025
db5381b
4292 (#47)
akinboboye May 27, 2025
93cff00
create mock schemas to fit everything when using no types flag (#48)
RichardDzurus May 28, 2025
050853e
EN #4348 flatten new-lines in arg descriptions (#50)
eneumann May 28, 2025
ee50a54
EN #4360 fix return types for TS funcs (#49)
eneumann May 28, 2025
bd33593
adding ability for python client server and client functions to add c…
aarongoin May 28, 2025
bc8e096
fix type error!
aarongoin May 28, 2025
569ec60
try simple upgrade
eupharis May 30, 2025
8c9d3d1
changed version
FedeMarchiniHotovo Jun 3, 2025
bd5729d
0.3.8.dev0 make it clearer that jsonschema parsing issue is warning n…
eupharis Jun 4, 2025
19c5613
4418 p2 bug on glide pre commit hook poly prepare make sure we git ad…
Daniel-Estoll Jun 18, 2025
391871a
4523 fix python client to save generate command arguments and reuse t…
Ash1R Jun 18, 2025
0026216
Update pydantic version to work with Python 3.13 (#54)
Ash1R Jun 24, 2025
a719bc0
fix vari under no types (#56)
eupharis Jun 25, 2025
0052b8e
better import error (#59)
eupharis Jun 26, 2025
cde7993
4645 Add github action for polyapi-python unittests, fix polyapi-pyth…
Ash1R Jun 26, 2025
4672a5a
Windows glide bug (#61)
Daniel-Estoll Jun 26, 2025
aa693fe
version command in python (#58)
RichardDzurus Jun 27, 2025
c6d9b8e
P2) Webhook Payload Type Blows Up our Python Client (#62)
RichardDzurus Jun 27, 2025
d47ab1d
Fixing bug where users couldn't put a description in their polyConfig…
aarongoin Jun 27, 2025
d32781a
next
eupharis Jun 30, 2025
f8416ee
fix schema generation (#64)
RichardDzurus Jun 30, 2025
88c55a3
remove bad ci file
eupharis Jun 30, 2025
58ac792
Upgrading version to 0.3.8 (#67)
nahuel-polyapi Jul 1, 2025
7dc8423
Merge branch 'main' into develop
eupharis Jul 1, 2025
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,5 @@ Please ignore \[name-defined\] errors for now. This is a known bug we are workin

## Support

If you run into any issues or want help getting started with this project, please contact support@polyapi.io
If you run into any issues or want help getting started with this project, please contact support@polyapi.io
.
3 changes: 3 additions & 0 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-r requirements.txt
mock==5.2.0
pytest
43 changes: 42 additions & 1 deletion polyapi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
CLI_COMMANDS = ["setup", "generate", "function", "clear", "help", "update_rendered_spec"]


def _get_version_string():
"""Get the version string for the package."""
try:
import importlib.metadata
version = importlib.metadata.version('polyapi-python')
return version
except Exception:
return "Unknown"


def execute_from_cli():
# First we setup all our argument parsing logic
# Then we parse the arguments (waaay at the bottom)
Expand All @@ -22,6 +32,11 @@ def execute_from_cli():
description="Manage your Poly API configurations and functions",
formatter_class=argparse.RawTextHelpFormatter
)

# Add global --version/-v flag
parser.add_argument('-v', '--version', action='version',
version=_get_version_string(),
help="Show version information")

subparsers = parser.add_subparsers(help="Available commands")

Expand All @@ -36,6 +51,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 +64,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)")

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
8 changes: 4 additions & 4 deletions polyapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
"""


def _wrap_code_in_try_except(code: str) -> str:
def _wrap_code_in_try_except(function_name: str, code: str) -> str:
""" this is necessary because client functions with imports will blow up ALL server functions,
even if they don't use them.
because the server function will try to load all client functions when loading the library
"""
prefix = """logger = logging.getLogger("poly")
try:
"""
suffix = """except ImportError as e:
logger.debug(e)"""
suffix = f"""except ImportError as e:
logger.warning("Failed to import client function '{function_name}', function unavailable: " + str(e))"""

lines = code.split("\n")
code = "\n ".join(lines)
Expand All @@ -39,6 +39,6 @@ def render_client_function(
return_type_def=return_type_def,
)

code = _wrap_code_in_try_except(code)
code = _wrap_code_in_try_except(function_name, code)

return code + "\n\n", func_type_defs
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)
17 changes: 10 additions & 7 deletions polyapi/deployables.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class ParsedDeployableConfig(TypedDict):
context: str
name: str
type: DeployableTypes
description: Optional[str]
disableAi: Optional[bool]
config: Dict[str, Any]

Expand Down Expand Up @@ -112,20 +113,22 @@ class PolyDeployConfig(TypedDict):

def get_all_deployable_files_windows(config: PolyDeployConfig) -> List[str]:
# Constructing the Windows command using dir and findstr
include_pattern = " ".join(f"*.{f}" if "." in f else f"*.{f}" for f in config["include_files_or_extensions"]) or "*"
exclude_pattern = '|'.join(config["exclude_dirs"])
pattern = '|'.join(f"polyConfig: {name}" for name in config["type_names"]) or 'polyConfig'
include_pattern = " ".join(f"*.{f}" for f in config["include_files_or_extensions"]) or "*"
exclude_pattern = ' '.join(f"\\{f}" for f in config["exclude_dirs"])
pattern = ' '.join(f"/C:\"polyConfig: {name}\"" for name in config["type_names"]) or '/C:"polyConfig"'

exclude_command = f" | findstr /V /I \"{exclude_pattern}\"" if exclude_pattern else ''
search_command = f" | findstr /M /I /F:/ /C:\"{pattern}\""
search_command = f" | findstr /S /M /I /F:/ {pattern} *.*"

result = []
for dir_path in config["include_dirs"]:
dir_command = f"dir /S /P /B {include_pattern} {dir_path}"
if dir_path != '.':
include_pattern = " ".join(f"{dir_path}*.{f}" for f in config["include_files_or_extensions"]) or "*"
dir_command = f"dir {include_pattern} /S /P /B > NUL"
full_command = f"{dir_command}{exclude_command}{search_command}"
try:
output = subprocess.check_output(full_command, shell=True, text=True)
result.extend(output.strip().split('\r\n'))
result.extend(output.strip().split('\n'))
except subprocess.CalledProcessError:
pass
return result
Expand Down Expand Up @@ -154,7 +157,7 @@ def get_all_deployable_files(config: PolyDeployConfig) -> List[str]:
if not config.get("include_files_or_extensions"):
config["include_files_or_extensions"] = ["py"]
if not config.get("exclude_dirs"):
config["exclude_dirs"] = ["poly", "node_modules", "dist", "build", "output", ".vscode", ".poly", ".github", ".husky", ".yarn"]
config["exclude_dirs"] = ["Lib", "node_modules", "dist", "build", "output", ".vscode", ".poly", ".github", ".husky", ".yarn", ".venv"]

is_windows = os.name == "nt"
if is_windows:
Expand Down
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
Loading