Skip to content

Commit 5853740

Browse files
committed
simple smoke test to remove the need for the notebook
1 parent cf14ca1 commit 5853740

2 files changed

Lines changed: 86 additions & 1 deletion

File tree

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
.PHONY: sync test lint format check clean
1+
.PHONY: sync test smoke lint format check clean
22

33
sync:
44
uv sync --all-extras
55

66
test:
77
uv run pytest tests/unit -q
88

9+
smoke:
10+
uv run python tests/smoke.py
11+
912
lint:
1013
uv run ruff check src tests
1114
uv run ruff format --check src tests

tests/smoke.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""Smoke test for the Lago Agent SDK against AWS Bedrock.
2+
3+
Reads credentials from .env (or the surrounding shell), wraps a Bedrock
4+
client, makes one converse() call, and flushes the usage event to Lago.
5+
6+
This is NOT a pytest test — it costs real money (one Bedrock call + one
7+
Lago event). The filename intentionally avoids pytest's `test_*.py` /
8+
`*_test.py` discovery patterns so it's never auto-collected.
9+
10+
Run:
11+
uv run python tests/smoke.py
12+
13+
Required env vars:
14+
LAGO_API_KEY
15+
LAGO_EXTERNAL_SUBSCRIPTION_ID
16+
AWS_BEARER_TOKEN_BEDROCK
17+
"""
18+
19+
from __future__ import annotations
20+
21+
import os
22+
import pathlib
23+
import sys
24+
25+
import boto3
26+
27+
from lago_agent_sdk import LagoSDK
28+
29+
_REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent
30+
31+
32+
def _load_dotenv(path: pathlib.Path | None = None) -> None:
33+
"""Tiny no-deps .env loader. Skips comments, blanks, and already-set vars."""
34+
p = path or (_REPO_ROOT / ".env")
35+
if not p.exists():
36+
return
37+
for raw in p.read_text().splitlines():
38+
line = raw.strip()
39+
if not line or line.startswith("#") or "=" not in line:
40+
continue
41+
key, _, value = line.partition("=")
42+
key = key.strip().lstrip("export ").strip()
43+
value = value.strip().strip("'").strip('"')
44+
os.environ.setdefault(key, value)
45+
46+
47+
def main() -> int:
48+
_load_dotenv()
49+
50+
try:
51+
api_key = os.environ["LAGO_API_KEY"]
52+
subscription = os.environ["LAGO_EXTERNAL_SUBSCRIPTION_ID"]
53+
except KeyError as missing:
54+
print(f"error: {missing} is required (set in .env or shell)", file=sys.stderr)
55+
return 1
56+
57+
api_url = os.environ.get("LAGO_API_URL", "https://api.getlago.com/api/v1/")
58+
region = os.environ.get("BEDROCK_REGION", "eu-west-1")
59+
model_id = os.environ.get("BEDROCK_MODEL_ID", "eu.amazon.nova-lite-v1:0")
60+
61+
sdk = LagoSDK(api_key=api_key, api_url=api_url)
62+
bedrock = sdk.wrap(boto3.client("bedrock-runtime", region_name=region))
63+
64+
resp = bedrock.converse(
65+
modelId=model_id,
66+
messages=[{"role": "user", "content": [{"text": "what is the capital of France?"}]}],
67+
extra_lago={"subscription": subscription},
68+
)
69+
70+
print(resp["output"]["message"]["content"][0]["text"])
71+
print("\ntokens:", resp["usage"])
72+
73+
# Ship the usage event before exit — atexit would handle it too, but
74+
# explicit makes failures (network errors, etc.) visible synchronously.
75+
if not sdk.flush(timeout=10.0):
76+
print("warning: lago queue did not drain within 10s", file=sys.stderr)
77+
return 2
78+
return 0
79+
80+
81+
if __name__ == "__main__":
82+
sys.exit(main())

0 commit comments

Comments
 (0)