Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion dbtsl/api/graphql/client/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(
auth_token: str,
url_format: Optional[str] = None,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if we moved this to a property and out of the constructor to reduce the cognitive overload of regular users, since 99% of people won't need to set this param.

):
"""Initialize the metadata client.

Expand All @@ -60,12 +61,13 @@ def __init__(
into a full URL. If `None`, the default `https://{server_host}/api/graphql`
will be assumed.
timeout: TimeoutOptions or total timeout (in seconds) for all GraphQL requests.
client_partner_source: Pass a dbt partner source header for traffic source tracking

NOTE: If `timeout` is a `TimeoutOptions`, the `connect_timeout` will not be used, due to
limitations of `gql`'s `aiohttp` transport.
See: https://github.com/graphql-python/gql/blob/b066e8944b0da0a4bbac6c31f43e5c3c7772cd51/gql/transport/aiohttp.py#L110
"""
super().__init__(server_host, environment_id, auth_token, url_format, timeout)
super().__init__(server_host, environment_id, auth_token, url_format, timeout, client_partner_source)

@override
def _create_transport(self, url: str, headers: Dict[str, str]) -> AIOHTTPTransport:
Expand Down
1 change: 1 addition & 0 deletions dbtsl/api/graphql/client/asyncio.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class AsyncGraphQLClient:
auth_token: str,
url_format: Optional[str] = None,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
) -> None: ...
def session(self) -> AbstractAsyncContextManager[AsyncIterator[Self]]: ...
@property
Expand Down
11 changes: 6 additions & 5 deletions dbtsl/api/graphql/client/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ def _default_backoff(cls) -> ExponentialBackoff:
)

@classmethod
def _extra_headers(cls) -> Dict[str, str]:
return {
"user-agent": env.PLATFORM.user_agent,
}
def _extra_headers(cls, client_partner_source: Optional[str] = None) -> Dict[str, str]:
return {"user-agent": env.PLATFORM.user_agent, "x-dbt-partner-source": client_partner_source or "sl-python-sdk"}

def __init__( # noqa: D107
self,
Expand All @@ -60,6 +58,7 @@ def __init__( # noqa: D107
auth_token: str,
url_format: Optional[str] = None,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
):
self.environment_id = environment_id

Expand All @@ -79,7 +78,7 @@ def __init__( # noqa: D107

headers = {
"authorization": f"bearer {auth_token}",
**self._extra_headers(),
**self._extra_headers(client_partner_source),
}
transport = self._create_transport(url=server_url, headers=headers)
self._gql = Client(transport=transport, execute_timeout=self.timeout.execute_timeout)
Expand Down Expand Up @@ -144,6 +143,7 @@ def __call__(
auth_token: str,
url_format: Optional[str] = None,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
) -> TClient:
"""Initialize the Semantic Layer client.

Expand All @@ -153,5 +153,6 @@ def __call__(
auth_token: the API auth token
url_format: the URL format string to construct the final URL with
timeout: `TimeoutOptions` or total timeout
client_partner_source: Pass a dbt partner source header for traffic source tracking
"""
pass
4 changes: 3 additions & 1 deletion dbtsl/api/graphql/client/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def __init__(
auth_token: str,
url_format: Optional[str] = None,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
):
"""Initialize the metadata client.

Expand All @@ -49,11 +50,12 @@ def __init__(
into a full URL. If `None`, the default `https://{server_host}/api/graphql`
will be assumed.
timeout: TimeoutOptions or total timeout (in seconds) for all GraphQL requests.
client_partner_source: Pass a dbt partner source header for traffic source tracking

NOTE: If `timeout` is a `TimeoutOptions`, the `tls_close_timeout` will not be used, since
`requests` does not support TLS termination timeouts.
"""
super().__init__(server_host, environment_id, auth_token, url_format, timeout)
super().__init__(server_host, environment_id, auth_token, url_format, timeout, client_partner_source)

@override
def _create_transport(self, url: str, headers: Dict[str, str]) -> RequestsHTTPTransport:
Expand Down
1 change: 1 addition & 0 deletions dbtsl/api/graphql/client/sync.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class SyncGraphQLClient:
auth_token: str,
url_format: Optional[str] = None,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
) -> None: ...
def session(self) -> AbstractContextManager[Iterator[Self]]: ...
@property
Expand Down
2 changes: 2 additions & 0 deletions dbtsl/client/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(
auth_token: str,
host: str,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
) -> None:
"""Initialize the Semantic Layer client.

Expand All @@ -42,6 +43,7 @@ def __init__(
gql_factory=AsyncGraphQLClient,
adbc_factory=AsyncADBCClient,
timeout=timeout,
client_partner_source=client_partner_source,
)

@asynccontextmanager
Expand Down
1 change: 1 addition & 0 deletions dbtsl/client/asyncio.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class AsyncSemanticLayerClient:
auth_token: str,
host: str,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
) -> None: ...
@overload
async def compile_sql(
Expand Down
3 changes: 3 additions & 0 deletions dbtsl/client/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def __init__(
gql_factory: GraphQLClientFactory[TGQLClient],
adbc_factory: ADBCClientFactory[TADBCClient],
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
) -> None:
"""Initialize the Semantic Layer client.

Expand All @@ -50,6 +51,7 @@ def __init__(
gql_factory: class of the underlying GQL client
adbc_factory: class of the underlying ADBC client
timeout: `TimeoutOptions` or total timeout for the underlying GraphQL client.
client_partner_source: Pass a dbt partner source header for traffic source tracking
"""
self._has_session = False

Expand All @@ -61,6 +63,7 @@ def __init__(
auth_token=auth_token,
url_format=env.GRAPHQL_URL_FORMAT,
timeout=timeout,
client_partner_source=client_partner_source,
)
self._adbc = adbc_factory(
server_host=host,
Expand Down
2 changes: 2 additions & 0 deletions dbtsl/client/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(
auth_token: str,
host: str,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
) -> None:
"""Initialize the Semantic Layer client.

Expand All @@ -42,6 +43,7 @@ def __init__(
gql_factory=SyncGraphQLClient,
adbc_factory=SyncADBCClient,
timeout=timeout,
client_partner_source=client_partner_source,
)

@contextmanager
Expand Down
1 change: 1 addition & 0 deletions dbtsl/client/sync.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class SyncSemanticLayerClient:
auth_token: str,
host: str,
timeout: Optional[Union[TimeoutOptions, float, int]] = None,
client_partner_source: Optional[str] = None,
) -> None: ...
@overload
def compile_sql(
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ test = [
"pytest-asyncio>=0.23.7,<0.24.0",
"pytest-subtests>=0.12.1,<0.13.0",
"pytest-mock>=3.14.0,<4.0.0",
"python-dotenv>=1.0.0,<2.0.0",
]

[tool.hatch.build]
Expand Down
2 changes: 2 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Any, Callable, Dict, Union, cast

import pytest
from dotenv import load_dotenv
from gql import Client, gql
from gql.utilities.serialize_variable_values import serialize_variable_values

Expand Down Expand Up @@ -69,6 +70,7 @@ def from_env(cls) -> "Credentials":
- SL_TOKEN
- SL_ENV_ID
"""
load_dotenv()
return cls(
host=os.environ["SL_HOST"],
token=os.environ["SL_TOKEN"],
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/test_sl_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ async def async_client(credentials: Credentials) -> AsyncIterator[AsyncSemanticL
environment_id=credentials.environment_id,
auth_token=credentials.token,
host=credentials.host,
client_partner_source="dbt-e2e-tests",
)
async with client.session():
yield client
Expand All @@ -31,6 +32,7 @@ def sync_client(credentials: Credentials) -> Iterator[SyncSemanticLayerClient]:
environment_id=credentials.environment_id,
auth_token=credentials.token,
host=credentials.host,
client_partner_source="dbt-e2e-tests",
)
with client.session():
yield client
Expand Down
1 change: 1 addition & 0 deletions tests/integration/test_timeouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def factory(timeout: TimeoutOptions) -> SyncSemanticLayerClient:
auth_token=credentials.token,
host=credentials.host,
timeout=timeout,
client_partner_source="dbt-e2e-tests",
)

return factory
Expand Down
Loading