Skip to content

Commit 8076d85

Browse files
aarongoinsudiptatjeuphariseneumanndchiniquy
authored
R25 deploy (#80)
* # Feature (2970): Update python client to support setup command (#22) * # Feature (2970): Update python client to support setup command - Function add command now support --execution-api-key - Extra Old Function call removed * improve polyapi-python setup (#24) * improve polyapi-python setup * # Feature (3019): improve polyapi-python setup (#25) * # Feature (3019): improve polyapi-python setup * # Feature (3019): improve polyapi-python setup - UUID Validation check added --------- Co-authored-by: Sudipta at TechJays <sudipta.kumar@techjays.com> * # Feature (3007): Update python -m polyapi function add --logs options (#23) * # Feature (3007): Update python -m polyapi function add --logs options - if --logs added, then value must enabled or disabled - If Nothing passed the value is default disabled - pyproject.toml version updated * Project Glide + Refactor main command line args parsing (#26) * Refactor main command line args parsing, adding prepare and sync commands to enable project glide workflows for python * improved tests * updating version * fix for poly cache directory path construction * one more adjustment to the deployables cache directory so there can't be any conflict with any custom namespace * this better? * verbose logging on upload code to see what's failing in CI/CD * bumpity * whoops * so close * better? * okay this should be the fix * is it this? * maybe * oh for the love of pete * whatever. might be a pypi issue * removing verbose logging * fixing bugs in sync command to use correct api urls * update logging * lint * improved auth * last fix for function sync * fix bug when comment arguments don't align with the function * try forcing the poly directory to exist * test logging * remove debug logging * fixing project glide deployable types and bumping the version * fixing missing arguments in python client function upload * fixing return type for trained functions * fix bug preventing use of poly sync command locally * next version of client! * EN #3183 allow null logs flag for python client (#28) * let the typing_extensions versions increase to support latest openai pypi package version * update dependency in one more place * Some bug fixes for python client (#29) * fixed bug with parsing python functions without any types, and bug where functions with multiple deployment receipts were getting mangled * whoops. uncommenting tests * last test fix * 0.3.2 * add poly schemas support (#31) * onward * adding schemas for Pythonland! * onward * next * next * next * next * test * next * next * next * little tweak for A-Aron * fix * next * update to v4 * v4 everywhere * bump version * add new version * remove warning, just go with any type for now * better generate printed messages, fix generate bug after function add * Update python version (#32) * Update python image (#33) * Update python version * Updated version * Rollback version * onward (#34) * woot! we have some better return types * toward working tests - except parser/deployables * more * getting there * next * onawrd * next * next * next * next * next (#35) * improve intellisense detection of schemas * release 0.3.3.dev8, fix misleading generate after setup * 0.3.3.dev9 - add support for optional arguments (#36) * next * release 0.3.3.dev10 * EN #3943 update to support SFX serverSideAsync True by setting correct return type (#39) * deploying version 0.3.3 for R22 * upgrade version * 4084 - revert strippping none values from function arguments during execution * P2) Update clients and specs endpoint so when generating with no-types argument all schemas get excluded (#38) * added no type option * version updated * 4010 generate contexts (#43) * make contexts truly optional * P3) (Optoro) Allow variable to be secret in the UI, but gettable in functions, and prevent secret variables from being made non-secret (#42) * secret -> secrecy - updated python client * comment fixed * add generate contexts (#45) * adds mtls and direct execute options (#44) * adds mtls and direct execute support * support for direct execute from client * fixed mtls * removed unused dep * polyCustom - prevent rewrites of executionId (#46) * 4292 (#47) * create mock schemas to fit everything when using no types flag (#48) * EN #4348 flatten new-lines in arg descriptions (#50) * EN #4348 flatten new-lines in arg descriptions * EN #4348 bump version to 0.3.7.dev4 * EN #4360 fix return types for TS funcs (#49) * adding ability for python client server and client functions to add custom headers (#51) * fix type error! * try simple upgrade * changed version * 0.3.8.dev0 make it clearer that jsonschema parsing issue is warning not error * 4418 p2 bug on glide pre commit hook poly prepare make sure we git add any docstrings added from poly prepare (#55) * Fixed windows no deployables found bug * removed superfluous print * Fixed deployables not being staged properly * Added .venv to excluded directories * Bumped version up to 0.3.8.dev1 * 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 <ar2558@cornell.edu> * Update pydantic version to work with Python 3.13 (#54) * fix vari under no types (#56) * better import error (#59) * 4645 Add github action for polyapi-python unittests, fix polyapi-python unittests (#57) * make tests pass and github actions * comment + push * add dev_requirements * use dev requirements * using mkdir to avoid poly not existing * Revert deployables anf change whitespace for passing tests * undo diff * undo deployables.py change * Windows glide bug (#61) * Fixed windows find deployable command and fixed ai description generation urls * Changed version number * version command in python (#58) * version command in python * P2) Webhook Payload Type Blows Up our Python Client (#62) * adds a fail safe when generating resources * version increase * version increment * Fixing bug where users couldn't put a description in their polyConfig… (#60) * Fixing bug where users couldn't put a description in their polyConfig field for glide functions * removing test_bash which should not have been commited, and bumping the version * next * fix schema generation (#64) * remove bad ci file * Upgrading version to 0.3.8 (#67) * 4655 p3 polyapi python schema errors lets fix (#63) * Changed encoding to utf-8 and added unit test * changed version * Updated version * Fixed find deployables command to ensure there are no duplicates (#65) * Fixed find deployables command to ensure there are no duplicates * Updated version * Updated version * Added check for LOGS_ENABLED env var and updated exceptions (#70) * Added check for LOGS_ENABLED env var and updated exceptions * Bumped version * allow higher stdlib_list * update in one more spot * increase version of truststore installed * added logger (#72) * added logger * bumped version * Change print to use logging (#73) * Monkey patched print to use logging module * Bumped version * EN #4845 fix function args schema bug for TypedDicts * Revert c612f6e (EN #4845 fix function args schema bug for TypedDicts) – accidental push * EN bump v to 0.3.9.dev8 * EN #4845 fix func arg schema bug with typed dicts (#75) * EN #4845 fix func arg schema bug with typed dicts * EN #4845 v0.3.9.dev9 * Tabi sdk (#74) * fixing client_id to be singe shared value per generation--matching typescript behavior * fixing some little type errors * tabi in the house! * tweaked to make table_id available on class, and adding description as a docstring comment for the class * bump version * oh lordy (#76) * One more missed f-string in tabi * Revert monkey patch (#77) * Revert "Monkey patched print to use logging module" This reverts commit a761c64. * bumped version * remove need for special logging process * fix GitHub action for polyapi python unittests, fix polyapi python unittests (#66) * make tests pass and github actions * comment + push * add dev_requirements * use dev requirements * using mkdir to avoid poly not existing * Revert deployables anf change whitespace for passing tests * undo diff * undo deployables.py change * new python-ci with pytest, correct actions syntax * add flask to the requirements, needed for a test * running into weird ord bug in python3.11, lets do simpler 7 char hash (#79) * running into weird ord bug in python3.11, lets do simpler 7 char hash * bump * fix tests * add workflow dispatch * try under 3.13 * 0.3.9.dev15: define some sort of scrub_keys * back up * actually fix tests * Revert "actually fix tests" This reverts commit 87caa04. * in sync with actions now? * update version for deploy --------- Co-authored-by: Sudipta at TechJays <sudipta.kumar@techjays.com> Co-authored-by: Dan Fellin <dan@polyapi.io> Co-authored-by: Dan Fellin <dan@highwaterlabs.com> Co-authored-by: Eric Neumann <eneumann@users.noreply.github.com> Co-authored-by: Don Chiniquy <drchiniquy@gmail.com> Co-authored-by: nahuel-polyapi <nahuel@polyapi.io> Co-authored-by: Bboydozzy96 <federico.marchini@hotovo.com> Co-authored-by: FedeMarchiniHotovo <130762770+FedeMarchiniHotovo@users.noreply.github.com> Co-authored-by: Shina Akinboboye <shina@polyapi.io> Co-authored-by: Richard <github.agonize754@passmail.net> Co-authored-by: Shina Akinboboye <60622084+akinboboye@users.noreply.github.com> Co-authored-by: Daniel-Estoll <115661842+Daniel-Estoll@users.noreply.github.com> Co-authored-by: Ashir Rao <69091220+Ash1R@users.noreply.github.com> Co-authored-by: Ashir Rao <ar2558@cornell.edu> Co-authored-by: eric.neumann <neumann.bend@gmail.com>
1 parent 6510e07 commit 8076d85

22 files changed

+1379
-92
lines changed

.flake8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[flake8]
2-
ignore = E203,E303,E402,E501,E722,W391,F401,W292,F811
2+
ignore = E203,E303,E402,E501,E722,W391,F401,W292,F811,E302
33
max-line-length = 150
44
max-complexity = 22

.github/workflows/python-ci.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Python CI
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches: [develop]
7+
pull_request:
8+
branches: [develop]
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
17+
- name: Set up Python 3.12
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: '3.12'
21+
cache: 'pip'
22+
23+
- name: Install dependencies
24+
run: |
25+
python -m pip install --upgrade pip
26+
pip install -r dev_requirements.txt --no-cache-dir
27+
28+
- name: Create dummy poly directory for tests
29+
run: mkdir -p polyapi/poly
30+
31+
- name: Run unit tests
32+
run: python -m unittest discover -s tests -t . -v

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ function_add_test.py
3434
lib_test*.py
3535
polyapi/poly
3636
polyapi/vari
37+
polyapi/tabi
3738
polyapi/schemas

README.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,6 @@ def bar():
7070
return "Hello World"
7171
```
7272

73-
## See Server Function Logs
74-
75-
In order to see function logs, please first set `logsEnabled` to `true` in Canopy for the function.
76-
77-
https://na1.polyapi.io/canopy/polyui/collections/server-functions
78-
79-
Then in your code, get the poly logger and log with it like so:
80-
81-
```python
82-
logger = logging.getLogger("poly")
83-
def bar():
84-
logger.warning("I AM THE LOG")
85-
return "Hello World"
86-
```
87-
88-
Finally, click the "Show Logs" button to see your server function logs in Canopy!
89-
90-
9173
## Complex Types In Server Functions
9274

9375
You can define arbitrarily complex argument and return types using TypedDicts.

dev_requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
-r requirements.txt
22
mock==5.2.0
3-
pytest
3+
pytest
4+
flask==3.0.3
5+

polyapi/auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from typing import List, Dict, Any, Tuple
2-
import uuid
32

43
from polyapi.typedefs import PropertySpecification
54
from polyapi.utils import parse_arguments, get_type_and_def
@@ -26,7 +25,8 @@ async def getToken(clientId: str, clientSecret: str, scopes: List[str], callback
2625
2726
Function ID: {function_id}
2827
\"""
29-
eventsClientId = "{client_id}"
28+
from polyapi.poly.client_id import client_id
29+
eventsClientId = client_id
3030
function_id = "{function_id}"
3131
3232
options = options or {{}}
@@ -165,7 +165,7 @@ def render_auth_function(
165165
func_str = ""
166166

167167
if function_name == "getToken":
168-
func_str = GET_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description, client_id=uuid.uuid4().hex)
168+
func_str = GET_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description)
169169
elif function_name == "introspectToken":
170170
func_str = INTROSPECT_TOKEN_TEMPLATE.format(function_id=function_id, description=function_description)
171171
elif function_name == "refreshToken":

polyapi/deployables.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import os
2+
import string
3+
import random
24
import subprocess
35
import json
46
import hashlib
@@ -65,20 +67,21 @@ class SyncDeployment(TypedDict, total=False):
6567
context: str
6668
name: str
6769
description: str
68-
type: str
70+
type: DeployableTypes
6971
fileRevision: str
7072
file: str
7173
types: DeployableFunctionTypes
72-
typeSchemas: Dict[str, any]
74+
typeSchemas: Dict[str, Any]
7375
dependencies: List[str]
74-
config: Dict[str, any]
76+
config: Dict[str, Any]
7577
instance: str
76-
id: Optional[str] = None
77-
deployed: Optional[str] = None
78+
id: Optional[str]
79+
deployed: Optional[str]
80+
7881

7982
DeployableTypeEntries: List[Tuple[DeployableTypeNames, DeployableTypes]] = [
80-
("PolyServerFunction", "server-function"),
81-
("PolyClientFunction", "client-function"),
83+
("PolyServerFunction", "server-function"), # type: ignore
84+
("PolyClientFunction", "client-function"), # type: ignore
8285
]
8386

8487
DeployableTypeToName: Dict[DeployableTypeNames, DeployableTypes] = {name: type for name, type in DeployableTypeEntries}
@@ -118,13 +121,13 @@ def get_all_deployable_files_windows(config: PolyDeployConfig) -> List[str]:
118121
pattern = ' '.join(f"/C:\"polyConfig: {name}\"" for name in config["type_names"]) or '/C:"polyConfig"'
119122

120123
exclude_command = f" | findstr /V /I \"{exclude_pattern}\"" if exclude_pattern else ''
121-
search_command = f" | findstr /S /M /I /F:/ {pattern} *.*"
124+
search_command = f" | findstr /M /I /F:/ {pattern}"
122125

123126
result = []
124127
for dir_path in config["include_dirs"]:
125128
if dir_path != '.':
126129
include_pattern = " ".join(f"{dir_path}*.{f}" for f in config["include_files_or_extensions"]) or "*"
127-
dir_command = f"dir {include_pattern} /S /P /B > NUL"
130+
dir_command = f"dir {include_pattern} /S /P /B"
128131
full_command = f"{dir_command}{exclude_command}{search_command}"
129132
try:
130133
output = subprocess.check_output(full_command, shell=True, text=True)
@@ -175,7 +178,7 @@ def get_git_revision(branch_or_tag: str = "HEAD") -> str:
175178
return check_output(["git", "rev-parse", "--short", branch_or_tag], text=True).strip()
176179
except CalledProcessError:
177180
# Return a random 7-character hash as a fallback
178-
return "".join(format(ord(c), 'x') for c in os.urandom(4))[:7]
181+
return "".join([random.choice(string.ascii_letters + string.digits) for _ in range(7)])
179182

180183
def get_cache_deployments_revision() -> str:
181184
"""Retrieve the cache deployments revision from a file."""

polyapi/execute.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
from typing import Dict, Optional
22
import requests
3+
import os
4+
import logging
35
from requests import Response
46
from polyapi.config import get_api_key_and_url, get_mtls_config
57
from polyapi.exceptions import PolyApiException
68

9+
logger = logging.getLogger("poly")
10+
711
def direct_execute(function_type, function_id, data) -> Response:
812
""" execute a specific function id/type
913
"""
@@ -13,7 +17,11 @@ def direct_execute(function_type, function_id, data) -> Response:
1317

1418
endpoint_info = requests.post(url, json=data, headers=headers)
1519
if endpoint_info.status_code < 200 or endpoint_info.status_code >= 300:
16-
raise PolyApiException(f"{endpoint_info.status_code}: {endpoint_info.content.decode('utf-8', errors='ignore')}")
20+
error_content = endpoint_info.content.decode("utf-8", errors="ignore")
21+
if function_type == 'api' and os.getenv("LOGS_ENABLED"):
22+
raise PolyApiException(f"Error executing api function with id: {function_id}. Status code: {endpoint_info.status_code}. Request data: {data}, Response: {error_content}")
23+
elif function_type != 'api':
24+
raise PolyApiException(f"{endpoint_info.status_code}: {error_content}")
1725

1826
endpoint_info_data = endpoint_info.json()
1927
request_params = endpoint_info_data.copy()
@@ -38,9 +46,12 @@ def direct_execute(function_type, function_id, data) -> Response:
3846
**request_params
3947
)
4048

41-
if resp.status_code < 200 or resp.status_code >= 300:
49+
if (resp.status_code < 200 or resp.status_code >= 300):
4250
error_content = resp.content.decode("utf-8", errors="ignore")
43-
raise PolyApiException(f"{resp.status_code}: {error_content}")
51+
if function_type == 'api' and os.getenv("LOGS_ENABLED"):
52+
logger.error(f"Error executing api function with id: {function_id}. Status code: {resp.status_code}. Request data: {data}, Response: {error_content}")
53+
elif function_type != 'api':
54+
raise PolyApiException(f"{resp.status_code}: {error_content}")
4455

4556
return resp
4657

@@ -59,9 +70,12 @@ def execute(function_type, function_id, data) -> Response:
5970
headers=headers,
6071
)
6172

62-
if resp.status_code < 200 or resp.status_code >= 300:
73+
if (resp.status_code < 200 or resp.status_code >= 300) and os.getenv("LOGS_ENABLED"):
6374
error_content = resp.content.decode("utf-8", errors="ignore")
64-
raise PolyApiException(f"{resp.status_code}: {error_content}")
75+
if function_type == 'api' and os.getenv("LOGS_ENABLED"):
76+
logger.error(f"Error executing api function with id: {function_id}. Status code: {resp.status_code}. Request data: {data}, Response: {error_content}")
77+
elif function_type != 'api':
78+
raise PolyApiException(f"{resp.status_code}: {error_content}")
6579

6680
return resp
6781

0 commit comments

Comments
 (0)