Skip to content

Commit 44b9fcc

Browse files
authored
Merge branch 'main' into fix/control-flow-exception-check-in-error-handlers
2 parents 9e7aa4c + 3a65ce8 commit 44b9fcc

162 files changed

Lines changed: 10913 additions & 7490 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55

66
version: 2
77
updates:
8-
- package-ecosystem: "pip" # See documentation for possible values
8+
- package-ecosystem: "uv" # See documentation for possible values
99
directory: "/" # Location of package manifests
1010
schedule:
1111
interval: "daily"
12+
cooldown:
13+
default-days: 7
1214
rebase-strategy: "disabled" # use dependabot-rebase-stale
1315
commit-message:
1416
prefix: chore
@@ -21,3 +23,19 @@ updates:
2123
llama-index:
2224
patterns:
2325
- "llama-index*"
26+
27+
- package-ecosystem: "github-actions"
28+
directory: "/"
29+
schedule:
30+
interval: "daily"
31+
cooldown:
32+
default-days: 7
33+
rebase-strategy: "disabled"
34+
commit-message:
35+
prefix: chore
36+
prefix-development: chore
37+
include: scope
38+
groups:
39+
github-actions:
40+
patterns:
41+
- "*"

.github/workflows/ci.yml

Lines changed: 165 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -10,59 +10,62 @@ on:
1010
branches:
1111
- "*"
1212

13+
permissions: {}
14+
1315
concurrency:
1416
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
15-
cancel-in-progress: false
17+
cancel-in-progress: true
1618

1719
jobs:
1820
linting:
19-
runs-on: ubuntu-latest
21+
runs-on: blacksmith-2vcpu-ubuntu-2404
2022
steps:
21-
- uses: actions/checkout@v3
22-
- uses: astral-sh/ruff-action@v3
23+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
24+
with:
25+
persist-credentials: false
26+
- name: Install uv and set Python version
27+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
28+
with:
29+
version: "0.11.2"
30+
python-version: "3.13"
31+
enable-cache: true # zizmor: ignore[cache-poisoning] CI-only, no artifacts published
32+
- name: Install dependencies
33+
run: uv sync --locked
34+
- name: Run Ruff
35+
run: uv run --frozen ruff check .
2336

2437
type-checking:
25-
runs-on: ubuntu-latest
38+
runs-on: blacksmith-2vcpu-ubuntu-2404
2639
steps:
27-
- uses: actions/checkout@v3
28-
- name: Set up Python
29-
uses: actions/setup-python@v4
40+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
3041
with:
31-
python-version: "3.13"
32-
- name: Install poetry
33-
uses: abatilo/actions-poetry@v2
34-
- name: Setup a local virtual environment
35-
run: |
36-
poetry config virtualenvs.create true --local
37-
poetry config virtualenvs.in-project true --local
38-
- uses: actions/cache@v3
39-
name: Define a cache for the virtual environment based on the dependencies lock file
42+
persist-credentials: false
43+
- name: Install uv and set Python version
44+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
4045
with:
41-
path: ./.venv
42-
key: venv-type-check-${{ hashFiles('poetry.lock') }}
43-
- uses: actions/cache@v3
46+
version: "0.11.2"
47+
python-version: "3.13"
48+
enable-cache: true # zizmor: ignore[cache-poisoning] CI-only, no artifacts published
49+
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 # zizmor: ignore[cache-poisoning]
4450
name: Cache mypy cache
4551
with:
4652
path: ./.mypy_cache
4753
key: mypy-${{ hashFiles('**/*.py', 'pyproject.toml') }}
4854
restore-keys: |
4955
mypy-
5056
- name: Install dependencies
51-
run: poetry install --only=main,dev
57+
run: uv sync --locked
5258
- name: Run mypy type checking
53-
run: poetry run mypy langfuse --no-error-summary
59+
run: uv run --frozen mypy langfuse --no-error-summary
5460

55-
ci:
56-
runs-on: ubuntu-latest
61+
unit-tests:
62+
runs-on: blacksmith-4vcpu-ubuntu-2404
5763
timeout-minutes: 30
5864
env:
5965
LANGFUSE_BASE_URL: "http://localhost:3000"
60-
LANGFUSE_PUBLIC_KEY: "pk-lf-1234567890"
61-
LANGFUSE_SECRET_KEY: "sk-lf-1234567890"
62-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
63-
# SERPAPI_API_KEY: ${{ secrets.SERPAPI_API_KEY }}
64-
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
65-
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
66+
LANGFUSE_PUBLIC_KEY: "pk-lf-test"
67+
LANGFUSE_SECRET_KEY: "sk-lf-test"
68+
OPENAI_API_KEY: "test-openai-key"
6669
strategy:
6770
fail-fast: false
6871
matrix:
@@ -73,125 +76,182 @@ jobs:
7376
- "3.13"
7477
- "3.14"
7578

76-
name: Test on Python version ${{ matrix.python-version }}
79+
name: Unit tests on Python ${{ matrix.python-version }}
7780
steps:
78-
- uses: actions/checkout@v3
79-
- uses: pnpm/action-setup@v3
81+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
8082
with:
81-
version: 9.5.0
83+
persist-credentials: false
84+
- name: Install uv and set Python version
85+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
86+
with:
87+
version: "0.11.2"
88+
python-version: ${{ matrix.python-version }}
89+
enable-cache: true # zizmor: ignore[cache-poisoning] CI-only, no artifacts published
8290

83-
- name: Clone langfuse server
91+
- name: Check Python version
92+
run: python --version
93+
94+
- name: Install the project dependencies
95+
run: uv sync --locked
96+
97+
- name: Run the automated tests
8498
run: |
85-
git clone https://github.com/langfuse/langfuse.git ./langfuse-server && echo $(cd ./langfuse-server && git rev-parse HEAD)
99+
python --version
100+
uv run --frozen pytest -n auto --dist worksteal -s -v --log-cli-level=INFO tests/unit
86101
87-
- name: Setup node (for langfuse server)
88-
uses: actions/setup-node@v3
89-
with:
90-
node-version: 24
102+
e2e-tests:
103+
runs-on: ubuntu-latest
104+
timeout-minutes: 30
105+
strategy:
106+
fail-fast: false
107+
matrix:
108+
include:
109+
- suite: e2e
110+
job_name: E2E shard 1 tests on Python 3.13
111+
shard_name: shard-1
112+
shard_index: 0
113+
shard_count: 2
114+
- suite: e2e
115+
job_name: E2E shard 2 tests on Python 3.13
116+
shard_name: shard-2
117+
shard_index: 1
118+
shard_count: 2
119+
- suite: live_provider
120+
job_name: E2E live-provider tests on Python 3.13
121+
shard_name: live-provider
122+
env:
123+
LANGFUSE_BASE_URL: "http://localhost:3000"
124+
LANGFUSE_PUBLIC_KEY: "pk-lf-1234567890"
125+
LANGFUSE_SECRET_KEY: "sk-lf-1234567890"
126+
LANGFUSE_INIT_ORG_ID: "0c6c96f4-0ca0-4f16-92a8-6dd7d7c6a501"
127+
LANGFUSE_INIT_ORG_NAME: "SDK Test Org"
128+
LANGFUSE_INIT_PROJECT_ID: "7a88fb47-b4e2-43b8-a06c-a5ce950dc53a"
129+
LANGFUSE_INIT_PROJECT_NAME: "SDK Test Project"
130+
LANGFUSE_INIT_PROJECT_PUBLIC_KEY: "pk-lf-1234567890"
131+
LANGFUSE_INIT_PROJECT_SECRET_KEY: "sk-lf-1234567890"
132+
LANGFUSE_INIT_USER_EMAIL: "sdk-tests@langfuse.local"
133+
LANGFUSE_INIT_USER_NAME: "SDK Tests"
134+
LANGFUSE_INIT_USER_PASSWORD: "langfuse-ci-password"
135+
LANGFUSE_E2E_READ_TIMEOUT_SECONDS: "60"
136+
LANGFUSE_E2E_READ_INTERVAL_SECONDS: "0.5"
137+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
138+
# SERPAPI_API_KEY: ${{ secrets.SERPAPI_API_KEY }}
139+
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
140+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
91141

92-
- name: Cache langfuse server dependencies
93-
uses: actions/cache@v3
142+
name: ${{ matrix.job_name }}
143+
steps:
144+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
145+
with:
146+
persist-credentials: false
147+
- name: Install uv and set Python version
148+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
94149
with:
95-
path: ./langfuse-server/node_modules
96-
key: |
97-
langfuse-server-${{ hashFiles('./langfuse-server/package-lock.json') }}
98-
langfuse-server-
150+
version: "0.11.2"
151+
python-version: "3.13"
152+
enable-cache: true # zizmor: ignore[cache-poisoning] CI-only, no artifacts published
153+
- name: Install the project dependencies
154+
run: uv sync --locked
155+
- name: Check uv Python version
156+
run: uv run --frozen python --version
157+
- name: Prepare langfuse server compose
158+
run: |
159+
mkdir -p ./langfuse-server
160+
LANGFUSE_SERVER_SHA="$(git ls-remote https://github.com/langfuse/langfuse.git HEAD | cut -f1)"
161+
curl -fsSL "https://raw.githubusercontent.com/langfuse/langfuse/${LANGFUSE_SERVER_SHA}/docker-compose.yml" \
162+
-o ./langfuse-server/docker-compose.yml
163+
echo "${LANGFUSE_SERVER_SHA}"
99164
100165
- name: Run langfuse server
101166
run: |
102167
cd ./langfuse-server
103168
104-
echo "::group::Run langfuse server"
105-
TELEMETRY_ENABLED=false docker compose up -d postgres
106-
echo "::endgroup::"
107-
108-
echo "::group::Logs from langfuse server"
109-
TELEMETRY_ENABLED=false docker compose logs
110-
echo "::endgroup::"
111-
112-
echo "::group::Install dependencies (necessary to run seeder)"
113-
pnpm i
114-
echo "::endgroup::"
115-
116-
echo "::group::Seed db"
117-
cp .env.dev.example .env
118-
pnpm run db:migrate
119-
pnpm run db:seed
120-
echo "::endgroup::"
121-
rm -rf .env
122-
123-
echo "::group::Run server"
124-
169+
echo "::group::Start langfuse server"
125170
TELEMETRY_ENABLED=false \
171+
NEXT_PUBLIC_LANGFUSE_RUN_NEXT_INIT=true \
126172
LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT=http://localhost:9090 \
127173
LANGFUSE_INGESTION_QUEUE_DELAY_MS=10 \
128174
LANGFUSE_INGESTION_CLICKHOUSE_WRITE_INTERVAL_MS=10 \
175+
LANGFUSE_EXPERIMENT_INSERT_INTO_EVENTS_TABLE=true \
176+
QUEUE_CONSUMER_EVENT_PROPAGATION_QUEUE_IS_ENABLED=true \
177+
LANGFUSE_ENABLE_EVENTS_TABLE_V2_APIS=true \
178+
LANGFUSE_ENABLE_EVENTS_TABLE_OBSERVATIONS=true \
129179
docker compose up -d
130-
131180
echo "::endgroup::"
132181
133-
# Add this step to check the health of the container
134182
- name: Health check for langfuse server
135183
run: |
136184
echo "Checking if the langfuse server is up..."
137185
retry_count=0
138-
max_retries=10
139-
until curl --output /dev/null --silent --head --fail http://localhost:3000/api/public/health
186+
max_retries=20
187+
until curl --output /dev/null --silent --head --fail http://localhost:3000/api/public/health && \
188+
uv run --frozen python -c "from langfuse import Langfuse; client = Langfuse(); project_id = client._get_project_id(); assert project_id == '7a88fb47-b4e2-43b8-a06c-a5ce950dc53a', project_id; print(project_id)"
140189
do
141190
retry_count=`expr $retry_count + 1`
142191
echo "Attempt $retry_count of $max_retries..."
143192
if [ $retry_count -ge $max_retries ]; then
144193
echo "Langfuse server did not respond in time. Printing logs..."
145-
docker logs langfuse-server-langfuse-web-1
194+
(cd ./langfuse-server && docker compose ps)
195+
(cd ./langfuse-server && docker compose logs langfuse-web langfuse-worker)
146196
echo "Failing the step..."
147197
exit 1
148198
fi
149199
sleep 5
150200
done
151201
echo "Langfuse server is up and running!"
152202
153-
- name: Install Python
154-
uses: actions/setup-python@v4
155-
# see details (matrix, python-version, python-version-file, etc.)
156-
# https://github.com/actions/setup-python
157-
with:
158-
python-version: ${{ matrix.python-version }}
159-
160-
- name: Check python version
161-
run: python --version
162-
163-
- name: Install poetry
164-
uses: abatilo/actions-poetry@v2
165-
166-
- name: Set poetry python version
203+
- name: Select e2e shard files
204+
if: ${{ matrix.suite == 'e2e' }}
167205
run: |
168-
poetry env use ${{ matrix.python-version }}
169-
poetry env info
206+
uv run --frozen python scripts/select_e2e_shard.py \
207+
--shard-index ${{ matrix.shard_index }} \
208+
--shard-count ${{ matrix.shard_count }} \
209+
--json
210+
uv run --frozen python scripts/select_e2e_shard.py \
211+
--shard-index ${{ matrix.shard_index }} \
212+
--shard-count ${{ matrix.shard_count }} \
213+
> "$RUNNER_TEMP/e2e-shard-files.txt"
214+
cat "$RUNNER_TEMP/e2e-shard-files.txt"
170215
171-
- name: Setup a local virtual environment (if no poetry.toml file)
216+
- name: Run the parallel end-to-end tests
217+
if: ${{ matrix.suite == 'e2e' }}
172218
run: |
173-
poetry config virtualenvs.create true --local
174-
poetry config virtualenvs.in-project true --local
175-
176-
- uses: actions/cache@v3
177-
name: Define a cache for the virtual environment based on the dependencies lock file
178-
with:
179-
path: ./.venv
180-
key: |
181-
venv-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}-${{ github.sha }}
219+
uv run --frozen python --version
220+
mapfile -t e2e_files < "$RUNNER_TEMP/e2e-shard-files.txt"
221+
set +e
222+
uv run --frozen pytest -n 4 --dist worksteal -s -v --log-cli-level=INFO "${e2e_files[@]}" -m "not serial_e2e"
223+
status=$?
224+
set -e
225+
if [ "$status" -eq 5 ]; then
226+
echo "No parallel e2e tests selected for this shard."
227+
elif [ "$status" -ne 0 ]; then
228+
exit "$status"
229+
fi
182230
183-
- name: Install the project dependencies
184-
run: poetry install --all-extras
231+
- name: Run serial end-to-end tests
232+
if: ${{ matrix.suite == 'e2e' }}
233+
run: |
234+
mapfile -t e2e_files < "$RUNNER_TEMP/e2e-shard-files.txt"
235+
set +e
236+
uv run --frozen pytest -s -v --log-cli-level=INFO "${e2e_files[@]}" -m "serial_e2e"
237+
status=$?
238+
set -e
239+
if [ "$status" -eq 5 ]; then
240+
echo "No serial e2e tests selected for this shard."
241+
elif [ "$status" -ne 0 ]; then
242+
exit "$status"
243+
fi
185244
186-
- name: Run the automated tests
245+
- name: Run live-provider tests
246+
if: ${{ matrix.suite == 'live_provider' }}
187247
run: |
188-
python --version
189-
poetry run pytest -n auto --dist loadfile -s -v --log-cli-level=INFO
248+
uv run --frozen python --version
249+
uv run --frozen pytest -n 4 --dist worksteal -s -v --log-cli-level=INFO tests/live_provider -m "live_provider"
190250
191251
all-tests-passed:
192252
# This allows us to have a branch protection rule for tests and deploys with matrix
193-
runs-on: ubuntu-latest
194-
needs: [ci, linting, type-checking]
253+
runs-on: blacksmith-2vcpu-ubuntu-2404
254+
needs: [unit-tests, e2e-tests, linting, type-checking]
195255
if: always()
196256
steps:
197257
- name: Successful deploy

0 commit comments

Comments
 (0)