strata-client 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- strata_client/__init__.py +52 -0
- strata_client/_clientconfig.py +69 -0
- strata_client/client.py +1876 -0
- strata_client/filters.py +172 -0
- strata_client/integration/__init__.py +54 -0
- strata_client/integration/arrow.py +389 -0
- strata_client/integration/datafusion.py +290 -0
- strata_client/integration/duckdb.py +322 -0
- strata_client/integration/pandas.py +201 -0
- strata_client/integration/polars.py +285 -0
- strata_client-0.3.0.dist-info/METADATA +63 -0
- strata_client-0.3.0.dist-info/RECORD +13 -0
- strata_client-0.3.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""strata_client — a lightweight Python client for a Strata server.
|
|
2
|
+
|
|
3
|
+
Depends only on ``httpx`` + ``pyarrow`` — none of the Strata server's stack
|
|
4
|
+
(no pyiceberg / fastapi / duckdb / pydantic, no Rust extension). Install it
|
|
5
|
+
anywhere you want to *use* Strata as a library::
|
|
6
|
+
|
|
7
|
+
pip install strata-client
|
|
8
|
+
|
|
9
|
+
from strata_client import StrataClient
|
|
10
|
+
|
|
11
|
+
with StrataClient() as client:
|
|
12
|
+
art = client.materialize(
|
|
13
|
+
inputs=["file:///warehouse#db.events"],
|
|
14
|
+
transform={"executor": "scan@v1", "params": {}},
|
|
15
|
+
)
|
|
16
|
+
table = client.fetch(art.uri)
|
|
17
|
+
|
|
18
|
+
The server distribution (``strata-notebook``) depends on this package and
|
|
19
|
+
re-exports it as ``strata.client`` / ``strata.filters`` for backward
|
|
20
|
+
compatibility. See docs/internal/design-strata-client.md.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from strata_client.client import (
|
|
24
|
+
Artifact,
|
|
25
|
+
AsyncStrataClient,
|
|
26
|
+
RetryConfig,
|
|
27
|
+
StrataClient,
|
|
28
|
+
eq,
|
|
29
|
+
ge,
|
|
30
|
+
gt,
|
|
31
|
+
le,
|
|
32
|
+
lt,
|
|
33
|
+
ne,
|
|
34
|
+
)
|
|
35
|
+
from strata_client.filters import Filter, FilterOp, FilterValue, compute_filter_fingerprint
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
"Artifact",
|
|
39
|
+
"AsyncStrataClient",
|
|
40
|
+
"Filter",
|
|
41
|
+
"FilterOp",
|
|
42
|
+
"FilterValue",
|
|
43
|
+
"RetryConfig",
|
|
44
|
+
"StrataClient",
|
|
45
|
+
"compute_filter_fingerprint",
|
|
46
|
+
"eq",
|
|
47
|
+
"ge",
|
|
48
|
+
"gt",
|
|
49
|
+
"le",
|
|
50
|
+
"lt",
|
|
51
|
+
"ne",
|
|
52
|
+
]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Slim server-URL resolution for the client.
|
|
2
|
+
|
|
3
|
+
The full :class:`strata.config.StrataConfig` pulls in pydantic, pydantic-settings,
|
|
4
|
+
and notebook submodules — far more than a client needs just to find the server.
|
|
5
|
+
This module replicates *only* the server-URL resolution, standard library only,
|
|
6
|
+
so ``StrataClient()`` can locate the server without importing the server's config
|
|
7
|
+
stack. ``StrataClient(config=...)`` still accepts a full ``StrataConfig`` (it has
|
|
8
|
+
a ``server_url``); this is just the default path.
|
|
9
|
+
|
|
10
|
+
Resolution precedence (highest wins):
|
|
11
|
+
|
|
12
|
+
1. ``STRATA_SERVER_URL`` env var (a full URL — the simplest knob for pointing a
|
|
13
|
+
client at a remote server; not read by the server config itself).
|
|
14
|
+
2. ``STRATA_HOST`` / ``STRATA_PORT`` env vars.
|
|
15
|
+
3. ``[tool.strata]`` ``host`` / ``port`` in the nearest ``pyproject.toml``.
|
|
16
|
+
4. Defaults ``127.0.0.1:8765`` — matching ``StrataConfig`` defaults.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import os
|
|
22
|
+
import tomllib
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from typing import Protocol
|
|
25
|
+
|
|
26
|
+
_DEFAULT_HOST = "127.0.0.1"
|
|
27
|
+
_DEFAULT_PORT = 8765
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class HasServerUrl(Protocol):
|
|
31
|
+
"""Anything carrying a ``server_url`` — e.g. a full ``StrataConfig``."""
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def server_url(self) -> str: ...
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _find_pyproject() -> Path | None:
|
|
38
|
+
"""Find pyproject.toml in the current or a parent directory."""
|
|
39
|
+
current = Path.cwd()
|
|
40
|
+
for parent in [current, *current.parents]:
|
|
41
|
+
candidate = parent / "pyproject.toml"
|
|
42
|
+
if candidate.exists():
|
|
43
|
+
return candidate
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _pyproject_strata() -> dict:
|
|
48
|
+
"""Return the ``[tool.strata]`` table, or ``{}`` if none is found."""
|
|
49
|
+
path = _find_pyproject()
|
|
50
|
+
if path is None:
|
|
51
|
+
return {}
|
|
52
|
+
try:
|
|
53
|
+
with open(path, "rb") as f:
|
|
54
|
+
data = tomllib.load(f)
|
|
55
|
+
except (OSError, tomllib.TOMLDecodeError):
|
|
56
|
+
return {}
|
|
57
|
+
return data.get("tool", {}).get("strata", {})
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def resolve_server_url() -> str:
|
|
61
|
+
"""Resolve the Strata server URL for a client (see module docstring)."""
|
|
62
|
+
direct = os.environ.get("STRATA_SERVER_URL")
|
|
63
|
+
if direct:
|
|
64
|
+
return direct
|
|
65
|
+
|
|
66
|
+
strata_table = _pyproject_strata()
|
|
67
|
+
host = os.environ.get("STRATA_HOST") or strata_table.get("host") or _DEFAULT_HOST
|
|
68
|
+
port = os.environ.get("STRATA_PORT") or strata_table.get("port") or _DEFAULT_PORT
|
|
69
|
+
return f"http://{host}:{port}"
|