From 0c5b96650c6b62ddd50965b866acf1a8a1488176 Mon Sep 17 00:00:00 2001 From: beroussel Date: Tue, 13 Aug 2024 16:07:58 +0200 Subject: [PATCH] chore(discovery): make the SDK use static discovery files GAE runtime will soon enough be decommissionned. To allow API discovery to continue working without breaking change, make the SDK rely on static discovery files hosted on LumApps CDN. --- lumapps/api/base_client.py | 32 +++++++++++++++++-- tests/legacy/test_base_client.py | 53 ++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/lumapps/api/base_client.py b/lumapps/api/base_client.py index 08c57a61..f96578bf 100644 --- a/lumapps/api/base_client.py +++ b/lumapps/api/base_client.py @@ -15,6 +15,7 @@ Tuple, Union, ) +from urllib.parse import urlparse from httpx import Client, HTTPStatusError @@ -59,15 +60,38 @@ def fetch_access_token( raise GetTokenError(str(err)) from err -def _get_urls(base_url: str, api_info: Dict[str, str]) -> Tuple[str, str]: +def _get_discovery_urls(base_url: str, api_info: Dict[str, str]) -> Tuple[str, str]: api_name = api_info.get("name", LUMAPPS_NAME) version = api_info.get("version", "v1") prefix = "" if api_name in GOOGLE_APIS else "/_ah/api" api_url = f"{prefix}/{api_name}/{version}" if api_name == LUMAPPS_NAME: + api_host = urlparse(base_url).netloc.split(".") + if len(api_host) < 4: + raise BaseClientError(f"Invalid base URL: {base_url}") + is_beta_cell = api_host[1] == "beta" + cell = api_host[0] + if is_beta_cell and cell not in ( + "go-cell-001", + "go-cell-003", + "ms-cell-001", + ): + raise BaseClientError(f"Invalid LumApps cell in base URL: {cell}") + + if cell not in ( + "go-cell-001", + "go-cell-002", + "go-cell-003", + "go-cell-005", + "go-cell-600", + "ms-cell-001", + "ms-cell-002", + ): + raise BaseClientError(f"Invalid LumApps cell in base URL: {cell}") return ( - "https://sites.lumapps.com/_ah/api/discovery/v1/apis/lumsites/v1/rest", + "https://storage.googleapis.com/prod-frontend-static-assets/api-discovery/" + f"lumapps-discovery-{'beta-' if is_beta_cell else ''}{cell}.json", api_url, ) return ( @@ -117,7 +141,9 @@ def __init__( } self._extra_http_headers = extra_http_headers or {} self.api_info = api_info - self._discovery_url, self._api_url = _get_urls(self.base_url, self.api_info) + self._discovery_url, self._api_url = _get_discovery_urls( + self.base_url, self.api_info + ) self.token_getter = token_getter self.token = token self.cursor = None diff --git a/tests/legacy/test_base_client.py b/tests/legacy/test_base_client.py index 1b7209cb..29026838 100644 --- a/tests/legacy/test_base_client.py +++ b/tests/legacy/test_base_client.py @@ -1,11 +1,13 @@ +from typing import Dict, Optional from json import load, loads from typing import Sequence from unittest.mock import PropertyMock - +from lumapps.api import __version__ from httpx import HTTPStatusError -from pytest import fixture, raises +from pytest import fixture, raises, mark -from lumapps.api.base_client import BaseClient +from lumapps.api.base_client import BaseClient, fetch_access_token +from lumapps.api.client import LumAppsClient from lumapps.api.errors import BadCallError, BaseClientError from lumapps.api.utils import ( FILTERS, @@ -378,3 +380,48 @@ def get(*args, **kwargs): def test_get_new_client_as_using_dwd(cli: BaseClient): with raises(NotImplementedError): cli.get_new_client_as_using_dwd("foo@bar.com") + +@mark.parametrize("cell, api_info, expected_exception", [ + ("go-cell-002", {"base_url": "https://go-cell-002.api.lumapps.com/"}, None), + ("ms-cell-001", {"base_url": "https://ms-cell-001.api.lumapps.com/"}, None), + ("go-cell-003", {"base_url": "https://go-cell-003.beta.api.lumapps.com/"}, None), + ("go-cell-004", {"base_url": "https://go-cell-004.api.lumapps.com/"}, BaseClientError), + ("go-cell-001", {"base_url": "http://localhost/sdk"}, BaseClientError), + ("go-cell-001", {}, BaseClientError), +]) +def test_create_client(cell: str, api_info: Dict[str, str], expected_exception: Optional[Exception]) -> None: + # Given / When + if expected_exception: + with raises(expected_exception): + LumAppsClient( + "123", + None, + api_info=api_info, + auth_info={"client_id": "abc", "client_secret": "789"}, + ) + return + else: + client = LumAppsClient( + "123", + None, + api_info=api_info, + auth_info={"client_id": "abc", "client_secret": "789"}, + ) + + # Then + assert client._headers == { + "x-lumapps-analytics": "off", + "User-Agent": f"lumapps-sdk {__version__}", + "authorization": "Bearer None" + } + assert client.base_url == api_info["base_url"].rstrip("/") + if ".beta." in client.base_url: + assert client._discovery_url == ( + "https://storage.googleapis.com/prod-frontend-static-assets/api-discovery/" + f"lumapps-discovery-beta-{cell}.json" + ) + else: + assert client._discovery_url == ( + "https://storage.googleapis.com/prod-frontend-static-assets/api-discovery/" + f"lumapps-discovery-{cell}.json" + )