From d62a361e5f5eeebed86ba1158570737a8561cec2 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Mercereau <24897252+plmercereau@users.noreply.github.com> Date: Thu, 19 Jun 2025 11:39:33 +0200 Subject: [PATCH 1/7] feat: add a "country" property to the current_workspace --- openhexa/sdk/workspaces/current_workspace.py | 54 ++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/openhexa/sdk/workspaces/current_workspace.py b/openhexa/sdk/workspaces/current_workspace.py index 0dc6e590..cb4d6484 100644 --- a/openhexa/sdk/workspaces/current_workspace.py +++ b/openhexa/sdk/workspaces/current_workspace.py @@ -21,7 +21,17 @@ S3Connection, ) +class Country: + """Represents a country with its code, name, alpha3 code and flag.""" + def __init__(self, code: str, name: str, alpha3: str, flag: str): + self.code = code + self.name = name + self.alpha3 = alpha3 + self.flag = flag + + def __repr__(self): + return f"Country(code={self.code}, name={self.name}, alpha3={self.alpha3}, flag={self.flag})" class WorkspaceConfigError(Exception): """Raised whenever the system cannot find an environment variable required to configure the current workspace.""" @@ -59,6 +69,50 @@ def slug(self) -> str: except KeyError: raise WorkspaceConfigError("The workspace slug is not available in this environment.") + @property + def country(self) -> Country: + """The country of the workspace. + + """ + try: + if self._connected: + response = graphql( + """ + query getWorkspaceCountry($slug: String!) { + workspace(slug: $slug) { + countries { + code + name + alpha3 + flag + } + } + } + """, + {"slug": self.slug}, + ) + countries = response["workspace"]["countries"] + if not countries: + raise WorkspaceConfigError("The workspace does not have a country configured.") + if len(response["workspace"]["countries"]) > 1: + warn( + "The workspace has multiple countries configured. The first one will be used.", + UserWarning, + stacklevel=2, + ) + # return the first country + first_country = response["workspace"]["countries"][0] + return Country( + code=first_country["code"], + name=first_country["name"], + alpha3=first_country["alpha3"], + flag=first_country["flag"], + ) + else: + return os.environ["WORKSPACE_COUNTRY"] + except KeyError: + raise WorkspaceConfigError("The workspace country is not available in this environment.") + @property def database_host(self) -> str: """The workspace database host.""" From 74b07eaf3a4a7d98de0fa04f28bca0d0b3fef3e5 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Mercereau <24897252+plmercereau@users.noreply.github.com> Date: Thu, 19 Jun 2025 11:43:36 +0200 Subject: [PATCH 2/7] style: correct property description --- openhexa/sdk/workspaces/current_workspace.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openhexa/sdk/workspaces/current_workspace.py b/openhexa/sdk/workspaces/current_workspace.py index cb4d6484..303cd567 100644 --- a/openhexa/sdk/workspaces/current_workspace.py +++ b/openhexa/sdk/workspaces/current_workspace.py @@ -71,9 +71,7 @@ def slug(self) -> str: @property def country(self) -> Country: - """The country of the workspace. - - """ + """The country of the workspace.""" try: if self._connected: response = graphql( @@ -112,7 +110,7 @@ def country(self) -> Country: return os.environ["WORKSPACE_COUNTRY"] except KeyError: raise WorkspaceConfigError("The workspace country is not available in this environment.") - + @property def database_host(self) -> str: """The workspace database host.""" From 6fe4f203346ac81d899a19eaf557d4243ab3fbc2 Mon Sep 17 00:00:00 2001 From: nazarfil Date: Thu, 19 Jun 2025 14:39:57 +0200 Subject: [PATCH 3/7] fix: use codegen --- .../cli/graphql/graphql_client/__init__.py | 8 ++++ openhexa/cli/graphql/graphql_client/client.py | 23 +++++++++ .../graphql/graphql_client/get_countries.py | 27 +++++++++++ openhexa/cli/graphql/queries.graphql | 11 +++++ openhexa/sdk/workspaces/current_workspace.py | 47 ++++--------------- pyproject.toml | 1 + 6 files changed, 79 insertions(+), 38 deletions(-) create mode 100644 openhexa/cli/graphql/graphql_client/get_countries.py diff --git a/openhexa/cli/graphql/graphql_client/__init__.py b/openhexa/cli/graphql/graphql_client/__init__.py index a82fb51c..f4320cb0 100644 --- a/openhexa/cli/graphql/graphql_client/__init__.py +++ b/openhexa/cli/graphql/graphql_client/__init__.py @@ -134,6 +134,11 @@ GraphQLClientHttpError, GraphQLClientInvalidResponseError, ) +from .get_countries import ( + GetCountries, + GetCountriesWorkspace, + GetCountriesWorkspaceCountries, +) from .get_workspace_pipelines import ( GetWorkspacePipelines, GetWorkspacePipelinesPipelines, @@ -377,6 +382,9 @@ "GeneratePipelineWebhookUrlInput", "GenerateWorkspaceTokenError", "GenerateWorkspaceTokenInput", + "GetCountries", + "GetCountriesWorkspace", + "GetCountriesWorkspaceCountries", "GetWorkspacePipelines", "GetWorkspacePipelinesPipelines", "GetWorkspacePipelinesPipelinesItems", diff --git a/openhexa/cli/graphql/graphql_client/client.py b/openhexa/cli/graphql/graphql_client/client.py index c5f97d2d..1bb62ae1 100644 --- a/openhexa/cli/graphql/graphql_client/client.py +++ b/openhexa/cli/graphql/graphql_client/client.py @@ -5,6 +5,7 @@ from .base_client import BaseClient from .base_model import UNSET, UnsetType +from .get_countries import GetCountries from .get_workspace_pipelines import GetWorkspacePipelines @@ -60,3 +61,25 @@ def get_workspace_pipelines( ) data = self.get_data(response) return GetWorkspacePipelines.model_validate(data) + + def get_countries(self, workspace_slug: str, **kwargs: Any) -> GetCountries: + query = gql( + """ + query getCountries($workspaceSlug: String!) { + workspace(slug: $workspaceSlug) { + countries { + code + name + flag + alpha3 + } + } + } + """ + ) + variables: Dict[str, object] = {"workspaceSlug": workspace_slug} + response = self.execute( + query=query, operation_name="getCountries", variables=variables, **kwargs + ) + data = self.get_data(response) + return GetCountries.model_validate(data) diff --git a/openhexa/cli/graphql/graphql_client/get_countries.py b/openhexa/cli/graphql/graphql_client/get_countries.py new file mode 100644 index 00000000..2292c773 --- /dev/null +++ b/openhexa/cli/graphql/graphql_client/get_countries.py @@ -0,0 +1,27 @@ +# Generated by ariadne-codegen +# Source: openhexa/cli/graphql/queries.graphql + +from typing import List, Optional + +from pydantic import Field + +from .base_model import BaseModel + + +class GetCountries(BaseModel): + workspace: Optional["GetCountriesWorkspace"] + + +class GetCountriesWorkspace(BaseModel): + countries: List["GetCountriesWorkspaceCountries"] + + +class GetCountriesWorkspaceCountries(BaseModel): + code: str + name: str + flag: str + alpha_3: str = Field(alias="alpha3") + + +GetCountries.model_rebuild() +GetCountriesWorkspace.model_rebuild() diff --git a/openhexa/cli/graphql/queries.graphql b/openhexa/cli/graphql/queries.graphql index e49b0cea..03be1b88 100644 --- a/openhexa/cli/graphql/queries.graphql +++ b/openhexa/cli/graphql/queries.graphql @@ -13,4 +13,15 @@ query getWorkspacePipelines($workspaceSlug: String!, $name: String, $page: Int = } } } +} + +query getCountries($workspaceSlug:String!){ + workspace(slug: $workspaceSlug) { + countries { + code + name + flag + alpha3 + } + } } \ No newline at end of file diff --git a/openhexa/sdk/workspaces/current_workspace.py b/openhexa/sdk/workspaces/current_workspace.py index 303cd567..9299bde2 100644 --- a/openhexa/sdk/workspaces/current_workspace.py +++ b/openhexa/sdk/workspaces/current_workspace.py @@ -20,6 +20,8 @@ PostgreSQLConnection, S3Connection, ) +from ...cli.api import OpenHexaClient + class Country: """Represents a country with its code, name, alpha3 code and flag.""" @@ -32,6 +34,8 @@ def __init__(self, code: str, name: str, alpha3: str, flag: str): def __repr__(self): return f"Country(code={self.code}, name={self.name}, alpha3={self.alpha3}, flag={self.flag})" + + class WorkspaceConfigError(Exception): """Raised whenever the system cannot find an environment variable required to configure the current workspace.""" @@ -70,46 +74,13 @@ def slug(self) -> str: raise WorkspaceConfigError("The workspace slug is not available in this environment.") @property - def country(self) -> Country: - """The country of the workspace.""" + def countries(self) -> list[Country]: + """The countries of the workspace.""" try: - if self._connected: - response = graphql( - """ - query getWorkspaceCountry($slug: String!) { - workspace(slug: $slug) { - countries { - code - name - alpha3 - flag - } - } - } - """, - {"slug": self.slug}, - ) - countries = response["workspace"]["countries"] - if not countries: - raise WorkspaceConfigError("The workspace does not have a country configured.") - if len(response["workspace"]["countries"]) > 1: - warn( - "The workspace has multiple countries configured. The first one will be used.", - UserWarning, - stacklevel=2, - ) - # return the first country - first_country = response["workspace"]["countries"][0] - return Country( - code=first_country["code"], - name=first_country["name"], - alpha3=first_country["alpha3"], - flag=first_country["flag"], - ) - else: - return os.environ["WORKSPACE_COUNTRY"] + response = OpenHexaClient().get_countries(workspace_slug=self.slug) + return response["workspace"]["countries"] except KeyError: - raise WorkspaceConfigError("The workspace country is not available in this environment.") + raise WorkspaceConfigError("The workspace countries are not available in this environment.") @property def database_host(self) -> str: diff --git a/pyproject.toml b/pyproject.toml index baffc7da..ec67644e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,6 +98,7 @@ ignore = [ "ANN204", "ANN205", "ANN401", + "D105" ] [tool.ruff.pycodestyle] From a924cf1df24a29cca7b1af48f9666c46e91367b8 Mon Sep 17 00:00:00 2001 From: nazarfil Date: Thu, 19 Jun 2025 14:48:46 +0200 Subject: [PATCH 4/7] fix: codegen --- openhexa/sdk/workspaces/current_workspace.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openhexa/sdk/workspaces/current_workspace.py b/openhexa/sdk/workspaces/current_workspace.py index 9299bde2..67a17256 100644 --- a/openhexa/sdk/workspaces/current_workspace.py +++ b/openhexa/sdk/workspaces/current_workspace.py @@ -20,19 +20,21 @@ PostgreSQLConnection, S3Connection, ) -from ...cli.api import OpenHexaClient +from openhexa.cli.api import OpenHexaClient class Country: """Represents a country with its code, name, alpha3 code and flag.""" def __init__(self, code: str, name: str, alpha3: str, flag: str): + """Initialize a Country object.""" self.code = code self.name = name self.alpha3 = alpha3 self.flag = flag def __repr__(self): + """Return a string representation of the Country object.""" return f"Country(code={self.code}, name={self.name}, alpha3={self.alpha3}, flag={self.flag})" @@ -77,8 +79,7 @@ def slug(self) -> str: def countries(self) -> list[Country]: """The countries of the workspace.""" try: - response = OpenHexaClient().get_countries(workspace_slug=self.slug) - return response["workspace"]["countries"] + return OpenHexaClient().get_countries(workspace_slug=self.slug).workspace.countries except KeyError: raise WorkspaceConfigError("The workspace countries are not available in this environment.") From 5b64d2289158947d3335db1d8227a37e1e586689 Mon Sep 17 00:00:00 2001 From: nazarfil Date: Thu, 19 Jun 2025 14:51:19 +0200 Subject: [PATCH 5/7] reuse type --- openhexa/sdk/workspaces/current_workspace.py | 20 +++----------------- pyproject.toml | 3 +-- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/openhexa/sdk/workspaces/current_workspace.py b/openhexa/sdk/workspaces/current_workspace.py index 67a17256..39c53ee7 100644 --- a/openhexa/sdk/workspaces/current_workspace.py +++ b/openhexa/sdk/workspaces/current_workspace.py @@ -7,8 +7,10 @@ from dataclasses import fields, make_dataclass from warnings import warn +from openhexa.cli.api import OpenHexaClient from openhexa.utils import stringcase +from ...cli.graphql.graphql_client import GetCountriesWorkspaceCountries from ..datasets import Dataset from ..utils import graphql from .connection import ( @@ -20,22 +22,6 @@ PostgreSQLConnection, S3Connection, ) -from openhexa.cli.api import OpenHexaClient - - -class Country: - """Represents a country with its code, name, alpha3 code and flag.""" - - def __init__(self, code: str, name: str, alpha3: str, flag: str): - """Initialize a Country object.""" - self.code = code - self.name = name - self.alpha3 = alpha3 - self.flag = flag - - def __repr__(self): - """Return a string representation of the Country object.""" - return f"Country(code={self.code}, name={self.name}, alpha3={self.alpha3}, flag={self.flag})" class WorkspaceConfigError(Exception): @@ -76,7 +62,7 @@ def slug(self) -> str: raise WorkspaceConfigError("The workspace slug is not available in this environment.") @property - def countries(self) -> list[Country]: + def countries(self) -> list[GetCountriesWorkspaceCountries]: """The countries of the workspace.""" try: return OpenHexaClient().get_countries(workspace_slug=self.slug).workspace.countries diff --git a/pyproject.toml b/pyproject.toml index ec67644e..4763a6ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -97,8 +97,7 @@ ignore = [ "ANN202", "ANN204", "ANN205", - "ANN401", - "D105" + "ANN401" ] [tool.ruff.pycodestyle] From 09df67bb15e13fcb221b0c4849833eb9774f0935 Mon Sep 17 00:00:00 2001 From: nazarfil Date: Thu, 19 Jun 2025 15:00:11 +0200 Subject: [PATCH 6/7] add client --- openhexa/sdk/workspaces/current_workspace.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openhexa/sdk/workspaces/current_workspace.py b/openhexa/sdk/workspaces/current_workspace.py index 39c53ee7..ee627688 100644 --- a/openhexa/sdk/workspaces/current_workspace.py +++ b/openhexa/sdk/workspaces/current_workspace.py @@ -7,7 +7,6 @@ from dataclasses import fields, make_dataclass from warnings import warn -from openhexa.cli.api import OpenHexaClient from openhexa.utils import stringcase from ...cli.graphql.graphql_client import GetCountriesWorkspaceCountries @@ -64,6 +63,9 @@ def slug(self) -> str: @property def countries(self) -> list[GetCountriesWorkspaceCountries]: """The countries of the workspace.""" + + from openhexa.cli.api import OpenHexaClient + try: return OpenHexaClient().get_countries(workspace_slug=self.slug).workspace.countries except KeyError: From 2980a006595d566e99b51e653b5a691c8235fefb Mon Sep 17 00:00:00 2001 From: nazarfil Date: Thu, 19 Jun 2025 15:03:36 +0200 Subject: [PATCH 7/7] fix import --- openhexa/sdk/workspaces/current_workspace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openhexa/sdk/workspaces/current_workspace.py b/openhexa/sdk/workspaces/current_workspace.py index ee627688..189edbab 100644 --- a/openhexa/sdk/workspaces/current_workspace.py +++ b/openhexa/sdk/workspaces/current_workspace.py @@ -63,7 +63,6 @@ def slug(self) -> str: @property def countries(self) -> list[GetCountriesWorkspaceCountries]: """The countries of the workspace.""" - from openhexa.cli.api import OpenHexaClient try: