diff --git a/bin/generate_rest.sh b/bin/generate_rest.sh index 2905f058..ca197a3a 100755 --- a/bin/generate_rest.sh +++ b/bin/generate_rest.sh @@ -57,17 +57,16 @@ rm -rf sdk/nodejs/sdk/src/api openapi-generator-cli generate -i specs/zrok.yml -o sdk/nodejs/sdk/src/api -g typescript-fetch echo "...generating python sdk client" -# Clean up existing files listed in .openapi-generator/FILES before regeneration -if [ -f sdk/python/sdk/zrok/.openapi-generator/FILES ]; then - while IFS= read -r file; do - if [ -f "sdk/python/sdk/zrok/$file" ]; then - echo "Removing existing file: sdk/python/sdk/zrok/$file" - rm "sdk/python/sdk/zrok/$file" - fi - done < sdk/python/sdk/zrok/.openapi-generator/FILES -fi -# Then remove the tracking file itself +# Delete tracked Python files +while IFS= read -r file; do + if [ -f "sdk/python/sdk/zrok/$file" ]; then + echo "Removing existing file: sdk/python/sdk/zrok/$file" + rm -f "sdk/python/sdk/zrok/$file" + fi +done < sdk/python/sdk/zrok/.openapi-generator/FILES +# Delete the tracking file rm -f sdk/python/sdk/zrok/.openapi-generator/FILES +# Generate and track new files openapi-generator-cli generate -i specs/zrok.yml -o sdk/python/sdk/zrok --package-name zrok_api -g python git checkout rest_server_zrok/configure_zrok.go diff --git a/sdk/python/sdk/zrok/zrok/environment/root.py b/sdk/python/sdk/zrok/zrok/environment/root.py index df76324b..8fb97af6 100644 --- a/sdk/python/sdk/zrok/zrok/environment/root.py +++ b/sdk/python/sdk/zrok/zrok/environment/root.py @@ -5,11 +5,11 @@ import os import json import zrok_api as zrok from zrok_api.configuration import Configuration -from ..api_client_wrapper import ZrokApiClient -import re +from zrok_api.models.client_version_check_request import ClientVersionCheckRequest V = "v1.0" + @dataclass class Metadata: V: str = "" @@ -43,27 +43,25 @@ class Root: def HasConfig(self) -> bool: return self.cfg != Config() - def Client(self) -> ZrokApiClient: + def Client(self) -> zrok.ApiClient: apiEndpoint = self.ApiEndpoint() cfg = Configuration() cfg.host = apiEndpoint[0] + "/api/v1" - cfg.api_key["x-token"] = self.env.Token - cfg.api_key_prefix['Authorization'] = 'Bearer' - - version_check_client = ZrokApiClient(configuration=cfg) - # Perform version check without authentication - self.client_version_check(version_check_client) - # Create a new client with the same configuration for authenticated requests - auth_client = ZrokApiClient(configuration=cfg) - # Explicitly set the x-token header in default_headers to ensure it's used - auth_client.set_default_header('x-token', self.env.Token) + # Update: Configure authentication token + # The token needs to be set with 'key' instead of 'x-token' + # This matches the securityDefinitions in the OpenAPI spec + cfg.api_key["key"] = self.env.Token + + # Create the API client with the configured authentication + auth_client = zrok.ApiClient(configuration=cfg) + self.client_version_check(auth_client) return auth_client def ApiEndpoint(self) -> ApiEndpoint: - apiEndpoint = "https://api.zrok.io" + apiEndpoint = "https://api-v1.zrok.io" frm = "binary" if self.cfg.ApiEndpoint != "": @@ -97,17 +95,10 @@ class Root: """Check if the client version is compatible with the API.""" metadata_api = zrok.MetadataApi(zrock_client) try: - # Create a request with NO authentication for version check - # We'll remove any authentication headers for this initial check - # The client's default_headers might already have x-token, so let's ensure this call doesn't use it - custom_headers = {} - for key, value in zrock_client.default_headers.items(): - if key.lower() != 'x-token': # Skip the auth token header - custom_headers[key] = value - + # Perform version check using the client_version_check method + request = ClientVersionCheckRequest(client_version=V) response = metadata_api.client_version_check_with_http_info( - body={"clientVersion": V}, - _headers=custom_headers # Pass custom headers without auth token + body=request, ) # Check if the response status code is 200 OK @@ -120,6 +111,7 @@ class Root: except Exception as e: raise Exception(f"Client version check failed: {str(e)}") + def Default() -> Root: r = Root() root = rootDir() diff --git a/sdk/python/sdk/zrok/zrok/share.py b/sdk/python/sdk/zrok/zrok/share.py index 4b861bf4..cff52858 100644 --- a/sdk/python/sdk/zrok/zrok/share.py +++ b/sdk/python/sdk/zrok/zrok/share.py @@ -4,6 +4,9 @@ from zrok.environment.root import Root from zrok_api.models.auth_user import AuthUser from zrok_api.models.share_request import ShareRequest from zrok_api.models.unshare_request import UnshareRequest +import json +from zrok_api.exceptions import ApiException +import zrok.model as model class Share(): @@ -55,8 +58,46 @@ def CreateShare(root: Root, request: model.ShareRequest) -> model.Share: zrok = root.Client() except Exception as e: raise Exception("error getting zrok client", e) + try: - res = ShareApi(zrok).share(body=out) + # Use share_with_http_info to get access to the HTTP info and handle custom response format + share_api = ShareApi(zrok) + # Add Accept header to handle the custom content type + custom_headers = { + 'Accept': 'application/json, application/zrok.v1+json' + } + + response_data = share_api.share_with_http_info( + body=out, + _headers=custom_headers + ) + + # Parse response + if hasattr(response_data, 'data') and response_data.data is not None: + res = response_data.data + else: + raise Exception("invalid response from server") + + except ApiException as e: + # If it's a content type error, try to parse the raw JSON + if "Unsupported content type: application/zrok.v1+json" in str(e) and hasattr(e, 'body'): + try: + # Parse the response body directly + res_dict = json.loads(e.body) + # Create a response object with the expected fields + class ShareResponse: + def __init__(self, share_token, frontend_proxy_endpoints): + self.share_token = share_token + self.frontend_proxy_endpoints = frontend_proxy_endpoints + + res = ShareResponse( + share_token=res_dict.get('shareToken', ''), + frontend_proxy_endpoints=res_dict.get('frontendProxyEndpoints', []) + ) + except (json.JSONDecodeError, ValueError, AttributeError) as json_err: + raise Exception(f"unable to parse API response: {str(json_err)}") from e + else: + raise Exception("unable to create share", e) except Exception as e: raise Exception("unable to create share", e) @@ -103,7 +144,24 @@ def DeleteShare(root: Root, shr: model.Share): raise Exception("error getting zrok client", e) try: - ShareApi(zrok).unshare(body=req) + # Add Accept header to handle the custom content type + share_api = ShareApi(zrok) + custom_headers = { + 'Accept': 'application/json, application/zrok.v1+json' + } + + # Use unshare_with_http_info to get access to the HTTP info + share_api.unshare_with_http_info( + body=req, + _headers=custom_headers + ) + except ApiException as e: + # If it's a content type error but the operation was likely successful, don't propagate the error + if "Unsupported content type: application/zrok.v1+json" in str(e) and (200 <= e.status <= 299): + # The operation was likely successful despite the content type error + pass + else: + raise Exception("error deleting share", e) except Exception as e: raise Exception("error deleting share", e) @@ -119,6 +177,23 @@ def ReleaseReservedShare(root: Root, shr: model.Share): raise Exception("error getting zrok client", e) try: - ShareApi(zrok).unshare(body=req) + # Add Accept header to handle the custom content type + share_api = ShareApi(zrok) + custom_headers = { + 'Accept': 'application/json, application/zrok.v1+json' + } + + # Use unshare_with_http_info to get access to the HTTP info + share_api.unshare_with_http_info( + body=req, + _headers=custom_headers + ) + except ApiException as e: + # If it's a content type error but the operation was likely successful, don't propagate the error + if "Unsupported content type: application/zrok.v1+json" in str(e) and (200 <= e.status <= 299): + # The operation was likely successful despite the content type error + pass + else: + raise Exception("error releasing share", e) except Exception as e: raise Exception("error releasing share", e)