stdb-cli 0.1.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.
- stdb_cli/__init__.py +0 -0
- stdb_cli/client.py +16 -0
- stdb_cli/commands/__init__.py +0 -0
- stdb_cli/commands/create_key.py +12 -0
- stdb_cli/commands/retrieve.py +39 -0
- stdb_cli/commands/search_dataset.py +30 -0
- stdb_cli/commands/search_location.py +30 -0
- stdb_cli/main.py +14 -0
- stdb_cli-0.1.0.dist-info/METADATA +7 -0
- stdb_cli-0.1.0.dist-info/RECORD +12 -0
- stdb_cli-0.1.0.dist-info/WHEEL +4 -0
- stdb_cli-0.1.0.dist-info/entry_points.txt +2 -0
stdb_cli/__init__.py
ADDED
|
File without changes
|
stdb_cli/client.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import os
|
|
3
|
+
import httpx
|
|
4
|
+
|
|
5
|
+
STDB_ENDPOINT = os.getenv("STDB_ENDPOINT", "https://stdb-mcp.azurecontainerapps.io")
|
|
6
|
+
STDB_API_KEY = os.getenv("STDB_API_KEY", "")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_client() -> httpx.Client:
|
|
10
|
+
if not STDB_API_KEY:
|
|
11
|
+
raise SystemExit("STDB_API_KEY environment variable is not set.")
|
|
12
|
+
return httpx.Client(
|
|
13
|
+
base_url=f"{STDB_ENDPOINT}/v1",
|
|
14
|
+
headers={"Authorization": f"Bearer {STDB_API_KEY}"},
|
|
15
|
+
timeout=60.0,
|
|
16
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
|
|
3
|
+
app = typer.Typer()
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@app.command()
|
|
7
|
+
def create_key(
|
|
8
|
+
name: str = typer.Option(..., help="Key name"),
|
|
9
|
+
email: str = typer.Option(..., help="Email address"),
|
|
10
|
+
):
|
|
11
|
+
"""Create a new API key (admin operation — requires direct DB access via server)."""
|
|
12
|
+
typer.echo("create-key is an admin operation. Use the STDB portal or run scripts/create_key.py on the server.")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import json
|
|
3
|
+
import typer
|
|
4
|
+
from stdb_cli.client import get_client
|
|
5
|
+
|
|
6
|
+
app = typer.Typer()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@app.command()
|
|
10
|
+
def retrieve(
|
|
11
|
+
cf: str = typer.Option(..., help="Dataset cf name"),
|
|
12
|
+
cq: str = typer.Option(..., help="Dataset cq name"),
|
|
13
|
+
h3_resolution: int = typer.Option(..., "--res", help="H3 resolution (7-10)"),
|
|
14
|
+
timestamps: list[str] = typer.Option(..., "--ts", help="Timestamps, e.g. 2023-12-31"),
|
|
15
|
+
location_ids: list[int] = typer.Option([], "--location-id", help="Location IDs from search-location"),
|
|
16
|
+
bbox: list[float] = typer.Option([], "--bbox", help="Bounding box: west south east north"),
|
|
17
|
+
format: str = typer.Option("parquet", help="Output format: parquet or csv"),
|
|
18
|
+
ttl_seconds: int = typer.Option(3600, help="Artifact TTL in seconds"),
|
|
19
|
+
json_output: bool = typer.Option(False, "--json", help="Output raw JSON"),
|
|
20
|
+
):
|
|
21
|
+
"""Retrieve H3 spatial data as a downloadable artifact URL."""
|
|
22
|
+
payload = {
|
|
23
|
+
"cf": cf, "cq": cq, "h3_resolution": h3_resolution,
|
|
24
|
+
"timestamps": timestamps, "location_ids": location_ids,
|
|
25
|
+
"bbox": bbox if bbox else None,
|
|
26
|
+
"format": format, "ttl_seconds": ttl_seconds,
|
|
27
|
+
}
|
|
28
|
+
with get_client() as client:
|
|
29
|
+
resp = client.post("/retrieve", json=payload)
|
|
30
|
+
resp.raise_for_status()
|
|
31
|
+
data = resp.json()
|
|
32
|
+
|
|
33
|
+
if json_output:
|
|
34
|
+
typer.echo(json.dumps(data, ensure_ascii=False, indent=2))
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
typer.echo(f"Artifact URL: {data['artifact_url']}")
|
|
38
|
+
typer.echo(f"Expires in: {data.get('expires_in_seconds', '?')}s")
|
|
39
|
+
typer.echo(f"Summary: {data.get('summary', '')}")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import json
|
|
3
|
+
import typer
|
|
4
|
+
from stdb_cli.client import get_client
|
|
5
|
+
|
|
6
|
+
app = typer.Typer()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@app.command()
|
|
10
|
+
def search_dataset(
|
|
11
|
+
query: str = typer.Argument(..., help="Natural language query, e.g. '台北租屋坪數'"),
|
|
12
|
+
top_k: int = typer.Option(10, help="Number of candidates before rerank"),
|
|
13
|
+
json_output: bool = typer.Option(False, "--json", help="Output raw JSON"),
|
|
14
|
+
):
|
|
15
|
+
"""Search for available datasets matching a query."""
|
|
16
|
+
with get_client() as client:
|
|
17
|
+
resp = client.post("/search-dataset", json={"query": query, "top_k": top_k})
|
|
18
|
+
resp.raise_for_status()
|
|
19
|
+
data = resp.json()
|
|
20
|
+
|
|
21
|
+
if json_output:
|
|
22
|
+
typer.echo(json.dumps(data, ensure_ascii=False, indent=2))
|
|
23
|
+
return
|
|
24
|
+
|
|
25
|
+
results = data.get("results", [])
|
|
26
|
+
if not results:
|
|
27
|
+
typer.echo("No results found.")
|
|
28
|
+
return
|
|
29
|
+
for r in results:
|
|
30
|
+
typer.echo(f" {r['cf']}/{r['cq']} {r.get('readable_name_zh', '')} [{', '.join(r.get('available_timestamps', []))}]")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import json
|
|
3
|
+
import typer
|
|
4
|
+
from stdb_cli.client import get_client
|
|
5
|
+
|
|
6
|
+
app = typer.Typer()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@app.command()
|
|
10
|
+
def search_location(
|
|
11
|
+
location_name: str = typer.Argument(..., help="One specific place name, e.g. '大安區'"),
|
|
12
|
+
top_k: int = typer.Option(3, help="Number of candidates to return"),
|
|
13
|
+
json_output: bool = typer.Option(False, "--json", help="Output raw JSON"),
|
|
14
|
+
):
|
|
15
|
+
"""Find location_id candidates for a place name."""
|
|
16
|
+
with get_client() as client:
|
|
17
|
+
resp = client.post("/search-location", json={"location_name": location_name, "top_k": top_k})
|
|
18
|
+
resp.raise_for_status()
|
|
19
|
+
data = resp.json()
|
|
20
|
+
|
|
21
|
+
if json_output:
|
|
22
|
+
typer.echo(json.dumps(data, ensure_ascii=False, indent=2))
|
|
23
|
+
return
|
|
24
|
+
|
|
25
|
+
candidates = data.get("candidates", [])
|
|
26
|
+
if not candidates:
|
|
27
|
+
typer.echo("No candidates found.")
|
|
28
|
+
return
|
|
29
|
+
for c in candidates:
|
|
30
|
+
typer.echo(f" [{c['location_id']}] {c['name']} confidence={c['confidence']} source={c['source']}")
|
stdb_cli/main.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from stdb_cli.commands.search_dataset import app as search_dataset_app
|
|
3
|
+
from stdb_cli.commands.search_location import app as search_location_app
|
|
4
|
+
from stdb_cli.commands.retrieve import app as retrieve_app
|
|
5
|
+
from stdb_cli.commands.create_key import app as create_key_app
|
|
6
|
+
|
|
7
|
+
app = typer.Typer(name="stdb", help="STDB CLI — spatio-temporal database client")
|
|
8
|
+
app.add_typer(search_dataset_app, name="search-dataset")
|
|
9
|
+
app.add_typer(search_location_app, name="search-location")
|
|
10
|
+
app.add_typer(retrieve_app, name="retrieve")
|
|
11
|
+
app.add_typer(create_key_app, name="create-key")
|
|
12
|
+
|
|
13
|
+
if __name__ == "__main__":
|
|
14
|
+
app()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
stdb_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
stdb_cli/client.py,sha256=LWHJis-JhfjnY6mmxB8XIRhYRR2hVOg0MXlrwpn4Fk8,478
|
|
3
|
+
stdb_cli/main.py,sha256=7qyJK-dTl-6BvXCmKbbJ_5rp8FCICfJ640vLnZ4Xe5A,612
|
|
4
|
+
stdb_cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
stdb_cli/commands/create_key.py,sha256=ObqWZwKR6c4qWPI57F9FMtnMpVEJeUhk6pwAv49t9Q0,387
|
|
6
|
+
stdb_cli/commands/retrieve.py,sha256=UwVZYL-y3WUQfcPORuBSp687LQ9ox5Flp2PoieVYQHM,1621
|
|
7
|
+
stdb_cli/commands/search_dataset.py,sha256=5_PM_29okvfFeCSXENWNgCs7sBbu-7OLW-P8eK3FoVA,1015
|
|
8
|
+
stdb_cli/commands/search_location.py,sha256=N2Eg1FqAFdeFhC8YLT4G76egGZoWQGBJLud1XLG2xIE,1023
|
|
9
|
+
stdb_cli-0.1.0.dist-info/METADATA,sha256=0uPh6xNyjBuNGeQeEEwnQkXbVvBp3-S7Hdv7HR0V6n4,170
|
|
10
|
+
stdb_cli-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
11
|
+
stdb_cli-0.1.0.dist-info/entry_points.txt,sha256=wQDjD1a0pXOdOhXvawVIBHMfUJt6cdQQj0wXOeSxRLE,43
|
|
12
|
+
stdb_cli-0.1.0.dist-info/RECORD,,
|