diff --git a/flareio/api_client.py b/flareio/api_client.py index 947b6b0..597860c 100644 --- a/flareio/api_client.py +++ b/flareio/api_client.py @@ -15,6 +15,13 @@ from flareio.version import __version__ as _flareio_version +_API_DOMAIN_DEFAULT: str = "api.flare.io" +_ALLOWED_API_DOMAINS: t.Tuple[str, ...] = ( + _API_DOMAIN_DEFAULT, + "api.eu.flare.io", +) + + class FlareApiClient: def __init__( self, @@ -22,9 +29,21 @@ def __init__( api_key: str, tenant_id: t.Optional[int] = None, session: t.Optional[requests.Session] = None, + api_domain: t.Optional[str] = None, + _enable_beta_features: bool = False, ) -> None: if not api_key: raise Exception("API Key cannot be empty.") + + api_domain = api_domain or _API_DOMAIN_DEFAULT + if api_domain not in _ALLOWED_API_DOMAINS: + raise Exception( + f"Invalid API domain: {api_domain}. Only {_ALLOWED_API_DOMAINS} are supported." + ) + if api_domain != _API_DOMAIN_DEFAULT and not _enable_beta_features: + raise Exception("Custom API domains considered a beta feature.") + self._api_domain: str = api_domain + self._api_key: str = api_key self._tenant_id: t.Optional[int] = tenant_id @@ -93,7 +112,7 @@ def generate_token(self) -> str: } resp = self._session.post( - "https://api.flare.io/tokens/generate", + f"https://{self._api_domain}/tokens/generate", json=payload, headers={ "Authorization": self._api_key, @@ -128,12 +147,12 @@ def _request( json: t.Optional[t.Dict[str, t.Any]] = None, headers: t.Optional[t.Dict[str, t.Any]] = None, ) -> requests.Response: - url = urljoin("https://api.flare.io", url) + url = urljoin(f"https://{self._api_domain}", url) netloc: str = urlparse(url).netloc - if not netloc == "api.flare.io": + if not netloc == self._api_domain: raise Exception( - f"Client was used to access {netloc=} at {url=}. Only the domain api.flare.io is supported." + f"Client was used to access {netloc=} at {url=}. Only the domain {self._api_domain} is supported." ) headers = { diff --git a/tests/test_api_client_creation.py b/tests/test_api_client_creation.py index 39f69b1..7e0a323 100644 --- a/tests/test_api_client_creation.py +++ b/tests/test_api_client_creation.py @@ -14,6 +14,19 @@ def test_create_client() -> None: FlareApiClient(api_key="test") +def test_create_client_eu() -> None: + FlareApiClient( + api_key="test", + api_domain="api.eu.flare.io", + _enable_beta_features=True, + ) + + +def test_create_client_bad_api_domain() -> None: + with pytest.raises(Exception, match="Invalid API domain"): + FlareApiClient(api_key="test", api_domain="bad.com") + + def test_create_client_empty_api_key() -> None: with pytest.raises(Exception, match="API Key cannot be empty."): FlareApiClient( diff --git a/tests/test_api_client_endpoints.py b/tests/test_api_client_endpoints.py index 9e90013..e23c616 100644 --- a/tests/test_api_client_endpoints.py +++ b/tests/test_api_client_endpoints.py @@ -82,6 +82,21 @@ def test_get_path_only() -> None: assert mocker.last_request.url == "https://api.flare.io/hello/test" +def test_get_eu_domain() -> None: + client = get_test_client( + api_domain="api.eu.flare.io", + _enable_beta_features=True, + ) + with requests_mock.Mocker() as mocker: + mocker.register_uri( + "GET", + "https://api.eu.flare.io/hello/test", + status_code=200, + ) + client.get("/hello/test") + assert mocker.last_request.url == "https://api.eu.flare.io/hello/test" + + def test_get_user_agent() -> None: client = get_test_client() with requests_mock.Mocker() as mocker: diff --git a/tests/utils.py b/tests/utils.py index 6d8112d..910ee14 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -9,17 +9,21 @@ def get_test_client( *, tenant_id: t.Optional[int] = None, authenticated: bool = True, + api_domain: t.Optional[str] = None, + _enable_beta_features: bool = False, ) -> FlareApiClient: client = FlareApiClient( api_key="test-api-key", tenant_id=tenant_id, + api_domain=api_domain, + _enable_beta_features=_enable_beta_features, ) if authenticated: with requests_mock.Mocker() as mocker: mocker.register_uri( "POST", - "https://api.flare.io/tokens/generate", + f"https://{client._api_domain}/tokens/generate", json={ "token": "test-token-hello", },