Skip to content

Commit 51e57a1

Browse files
authored
Support tracing with traceloop (#34)
* add demo for traceloop Signed-off-by: kerthcet <kerthcet@gmail.com> * support traceloop for tracing Signed-off-by: kerthcet <kerthcet@gmail.com> * Install libraries Signed-off-by: kerthcet <kerthcet@gmail.com> * fix test Signed-off-by: kerthcet <kerthcet@gmail.com> * upgrade openai Signed-off-by: kerthcet <kerthcet@gmail.com> * fix test error Signed-off-by: kerthcet <kerthcet@gmail.com> --------- Signed-off-by: kerthcet <kerthcet@gmail.com>
1 parent 64f8817 commit 51e57a1

8 files changed

Lines changed: 2970 additions & 118 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ __pycache__
3434
.ruff_cache
3535
*.tgz
3636
dist
37-
.env
37+
.env
38+
39+
tmp

Makefile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ publish: build
1010

1111
.PHONY: launch
1212
launch:
13-
docker-compose up -d
13+
docker-compose -f ./hack/docker-compose.yaml up -d
1414

1515
.PHONY: lint
1616
lint:
@@ -29,10 +29,11 @@ test: lint
2929
test-integration: lint
3030
@bash -c '\
3131
set -e; \
32-
docker-compose up -d; \
33-
trap "docker-compose down" EXIT; \
32+
docker-compose -f ./hack/docker-compose.yaml up -d; \
33+
trap "docker-compose -f ./hack/docker-compose.yaml down" EXIT; \
3434
until docker exec postgres pg_isready -U at_user; do sleep 1; done; \
35+
until curl -sf http://localhost:11434/api/tags | grep "smollm:135m" > /dev/null; do sleep 1; done; \
3536
$(POETRY) run pytest tests/integration; \
3637
'
3738
.PHONY: test-all
38-
test-all: test test-integration
39+
test-all: test test-integration

alphatrion/tracing/tracing.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
2+
from opentelemetry.semconv_ai import TraceloopSpanKindValues
3+
from traceloop.sdk import Traceloop
4+
from traceloop.sdk.decorators import task as _task
5+
from traceloop.sdk.decorators import workflow as _workflow
6+
7+
Traceloop.init(
8+
# TODO: make this configurable
9+
exporter=ConsoleSpanExporter(),
10+
disable_batch=True,
11+
)
12+
13+
14+
def task(
15+
name: str | None = None,
16+
version: int | None = None,
17+
method_name: str | None = None,
18+
tlp_span_kind: TraceloopSpanKindValues | None = TraceloopSpanKindValues.TASK,
19+
):
20+
return _task(
21+
name=name,
22+
version=version,
23+
method_name=method_name,
24+
tlp_span_kind=tlp_span_kind,
25+
)
26+
27+
28+
def workflow(
29+
name: str | None = None,
30+
version: int | None = None,
31+
method_name: str | None = None,
32+
tlp_span_kind: TraceloopSpanKindValues | None = TraceloopSpanKindValues.WORKFLOW,
33+
):
34+
return _workflow(
35+
name=name,
36+
version=version,
37+
method_name=method_name,
38+
tlp_span_kind=tlp_span_kind,
39+
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
services:
2+
ollama:
3+
container_name: ollama
4+
image: ollama/ollama:latest
5+
ports:
6+
- "11434:11434"
7+
entrypoint: ["/bin/bash", "-c", "\
8+
ollama serve & \
9+
sleep 2 && \
10+
ollama pull smollm:135m && \
11+
wait"]
12+
deploy:
13+
replicas: 1
14+
restart_policy:
15+
condition: any
16+
healthcheck:
17+
test: ["CMD-SHELL", "curl -sf http://localhost:11434/api/tags"]
18+
interval: 5s
19+
timeout: 3s
20+
retries: 20
21+
start_period: 10s
222
postgres:
323
container_name: postgres
424
image: postgres:16

poetry.lock

Lines changed: 2836 additions & 108 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ version = "0.0.1"
44
description = "AlphaTrion is an open-source and all-in-one platform to build AI-powered applications."
55
license = {text = "Apache-2.0"}
66
readme = "README.md"
7-
requires-python = ">=3.12"
7+
requires-python = ">=3.12, <4.0"
88

99
dependencies = [
1010
"sqlalchemy (>=2.0.43,<3.0.0)",
1111
"python-dotenv (>=1.1.1,<2.0.0)",
1212
"oras (>=0.2.38,<0.3.0)",
1313
"psycopg2-binary (>=2.9.10,<3.0.0)",
1414
"pydantic (>=2.11.7,<3.0.0)",
15+
"traceloop-sdk (>=0.47.5,<1.0.0)",
16+
"openai (>=2.6.1,<3.0.0)",
1517
]
1618

1719
[tool.poetry.group.dev.dependencies]
@@ -48,4 +50,4 @@ quote-style = "double"
4850
indent-style = "space"
4951

5052
[tool.ruff.lint.per-file-ignores]
51-
"tests/*" = ["PLR2004"]
53+
"tests/*" = ["PLR2004"]

tests/integration/test_tracing.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# ruff: noqa: E501
2+
3+
from openai import OpenAI
4+
5+
from alphatrion.tracing.tracing import task, workflow
6+
7+
client = OpenAI(
8+
base_url="http://localhost:11434/v1",
9+
api_key="",
10+
)
11+
12+
13+
@task(name="joke_creation")
14+
def create_joke():
15+
completion = client.chat.completions.create(
16+
model="smollm:135m",
17+
messages=[{"role": "user", "content": "Tell me a joke about opentelemetry"}],
18+
)
19+
return completion.choices[0].message.content
20+
21+
22+
@task(name="joke_translation")
23+
def translate_joke_to_pirate(joke: str):
24+
completion = client.chat.completions.create(
25+
model="smollm:135m",
26+
messages=[
27+
{
28+
"role": "user",
29+
"content": f"Translate the below joke to pirate-like english:\n\n{joke}",
30+
}
31+
],
32+
)
33+
return completion.choices[0].message.content
34+
35+
36+
@task(name="signature_generation")
37+
def generate_signature(joke: str):
38+
completion = client.chat.completions.create(
39+
model="smollm:135m",
40+
messages=[
41+
{"role": "user", "content": "add a signature to the joke:\n\n" + joke}
42+
],
43+
)
44+
return completion.choices[0].message.content
45+
46+
47+
@workflow(name="pirate_joke_generator")
48+
def joke_workflow():
49+
eng_joke = create_joke()
50+
pirate_joke = translate_joke_to_pirate(eng_joke)
51+
signature = generate_signature(pirate_joke)
52+
return pirate_joke, signature
53+
54+
55+
def test_workflow():
56+
pirate_joke, signature = joke_workflow()
57+
assert pirate_joke is not None
58+
assert signature is not None
59+
60+
61+
if __name__ == "__main__":
62+
test_workflow()

tests/unit/trial/test_trial.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ def test_timeout(self):
3535
{
3636
"name": "With started_at, positive timeout",
3737
"config": TrialConfig(max_duration_seconds=5),
38-
"started_at": (
39-
datetime.now(UTC) - timedelta(seconds=3)
40-
).isoformat(),
38+
"started_at": (datetime.now(UTC) - timedelta(seconds=3)).isoformat(),
4139
"expected": 2,
4240
},
4341
]

0 commit comments

Comments
 (0)