Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

version: 2
updates:
- package-ecosystem: "pip" # See documentation for possible values
- package-ecosystem: "uv" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
Expand Down
66 changes: 23 additions & 43 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,27 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: astral-sh/ruff-action@v3
- name: Install uv and set Python version
uses: astral-sh/setup-uv@v7
with:
version: "0.11.2"
python-version: "3.13"
enable-cache: true
- name: Install dependencies
run: uv sync --locked
- name: Run Ruff
run: uv run --frozen ruff check .

type-checking:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
- name: Install uv and set Python version
uses: astral-sh/setup-uv@v7
with:
version: "0.11.2"
python-version: "3.13"
- name: Install poetry
uses: abatilo/actions-poetry@v2
- name: Setup a local virtual environment
run: |
poetry config virtualenvs.create true --local
poetry config virtualenvs.in-project true --local
- uses: actions/cache@v3
name: Define a cache for the virtual environment based on the dependencies lock file
with:
path: ./.venv
key: venv-type-check-${{ hashFiles('poetry.lock') }}
enable-cache: true
- uses: actions/cache@v3
name: Cache mypy cache
with:
Expand All @@ -48,9 +48,9 @@ jobs:
restore-keys: |
mypy-
- name: Install dependencies
run: poetry install --only=main,dev
run: uv sync --locked
- name: Run mypy type checking
run: poetry run mypy langfuse --no-error-summary
run: uv run --frozen mypy langfuse --no-error-summary

ci:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -154,43 +154,23 @@ jobs:
done
echo "Langfuse server is up and running!"

- name: Install Python
uses: actions/setup-python@v4
# see details (matrix, python-version, python-version-file, etc.)
# https://github.com/actions/setup-python
- name: Install uv and set Python version
uses: astral-sh/setup-uv@v7
with:
version: "0.11.2"
python-version: ${{ matrix.python-version }}
enable-cache: true

- name: Check python version
- name: Check Python version
run: python --version

- name: Install poetry
uses: abatilo/actions-poetry@v2

- name: Set poetry python version
run: |
poetry env use ${{ matrix.python-version }}
poetry env info

- name: Setup a local virtual environment (if no poetry.toml file)
run: |
poetry config virtualenvs.create true --local
poetry config virtualenvs.in-project true --local

- uses: actions/cache@v3
name: Define a cache for the virtual environment based on the dependencies lock file
with:
path: ./.venv
key: |
venv-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}-${{ github.sha }}

- name: Install the project dependencies
run: poetry install --all-extras
run: uv sync --locked

- name: Run the automated tests
run: |
python --version
poetry run pytest -n auto --dist loadfile -s -v --log-cli-level=INFO
uv run --frozen pytest -n auto --dist loadfile -s -v --log-cli-level=INFO

all-tests-passed:
# This allows us to have a branch protection rule for tests and deploys with matrix
Expand Down
49 changes: 18 additions & 31 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,12 @@ jobs:
fetch-depth: 0
token: ${{ secrets.GH_ACCESS_TOKEN }}

- name: Setup Python
uses: actions/setup-python@v5
- name: Install uv and set Python version
uses: astral-sh/setup-uv@v7
with:
version: "0.11.2"
python-version: "3.12"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: "1.8.4"
virtualenvs-create: true
virtualenvs-in-project: true
enable-cache: true

- name: Configure Git
env:
Expand All @@ -92,7 +87,7 @@ jobs:
- name: Get current version
id: current-version
run: |
current_version=$(poetry version -s)
current_version=$(uv version --short)
echo "version=$current_version" >> $GITHUB_OUTPUT
echo "Current version: $current_version"

Expand Down Expand Up @@ -211,27 +206,13 @@ jobs:

- name: Update version in pyproject.toml
run: |
poetry version ${{ steps.new-version.outputs.version }}

- name: Update version in langfuse/version.py
run: |
new_version="${{ steps.new-version.outputs.version }}"
sed -i "s/__version__ = \".*\"/__version__ = \"$new_version\"/" langfuse/version.py
echo "Updated langfuse/version.py:"
cat langfuse/version.py
uv version ${{ steps.new-version.outputs.version }} --frozen
Comment thread
hassiebp marked this conversation as resolved.
Outdated

- name: Verify version consistency
run: |
pyproject_version=$(poetry version -s)
file_version=$(grep -oP '__version__ = "\K[^"]+' langfuse/version.py)
pyproject_version=$(uv version --short)
Comment thread
hassiebp marked this conversation as resolved.
Outdated

echo "pyproject.toml version: $pyproject_version"
echo "langfuse/version.py version: $file_version"

if [ "$pyproject_version" != "$file_version" ]; then
echo "❌ Error: Version mismatch between pyproject.toml and langfuse/version.py"
exit 1
fi

if [ "$pyproject_version" != "${{ steps.new-version.outputs.version }}" ]; then
echo "❌ Error: Version in files doesn't match expected version"
Expand All @@ -241,7 +222,7 @@ jobs:
echo "✅ Versions are consistent: $pyproject_version"

- name: Build package
run: poetry build
run: uv build --no-sources

- name: Verify build artifacts
run: |
Expand Down Expand Up @@ -278,9 +259,17 @@ jobs:
fi
echo "✅ Artifact version verified"

- name: Smoke test wheel
run: |
uv run --isolated --no-project --with dist/*.whl python -c "from importlib.metadata import version; import langfuse; assert langfuse.__version__ == version('langfuse')"

- name: Smoke test source distribution
run: |
uv run --isolated --no-project --with dist/*.tar.gz python -c "from importlib.metadata import version; import langfuse; assert langfuse.__version__ == version('langfuse')"

- name: Commit version changes
run: |
git add pyproject.toml langfuse/version.py
git add pyproject.toml
git commit -m "chore: release v${{ steps.new-version.outputs.version }}"

- name: Create and push tag
Expand All @@ -292,9 +281,7 @@ jobs:

- name: Publish to PyPI
id: publish-pypi
uses: pypa/gh-action-pypi-publish@release/v1
with:
print-hash: true
run: uv publish --trusted-publishing always

- name: Create GitHub Release
id: create-release
Expand Down
47 changes: 21 additions & 26 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.2
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.11.2
hooks:
- id: uv-lock

- repo: local
hooks:
# Run the linter and fix
- id: ruff-check
- id: uv-ruff-check
name: ruff-check
entry: uv run --frozen ruff check --fix
language: system
types_or: [python, pyi, jupyter]
args: [--fix]
exclude: ^langfuse/api/

# Run the formatter.
- id: ruff-format
- id: uv-ruff-format
name: ruff-format
entry: uv run --frozen ruff format
language: system
types_or: [python, pyi, jupyter]
exclude: ^langfuse/api/

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.18.2
hooks:
- id: mypy
additional_dependencies:
- types-requests
- types-setuptools
- httpx
- pydantic>=1.10.7
- backoff>=1.10.0
- openai>=0.27.8
- wrapt
- packaging>=23.2
- opentelemetry-api
- opentelemetry-sdk
- opentelemetry-exporter-otlp
- numpy
- langchain>=0.0.309
- langchain-core
- langgraph
args: [--no-error-summary]
- id: uv-mypy
name: mypy
entry: uv run --frozen mypy langfuse --no-error-summary
language: system
files: ^langfuse/
pass_filenames: false
35 changes: 16 additions & 19 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,60 +11,57 @@ This is the Langfuse Python SDK, a client library for accessing the Langfuse obs
### Setup

```bash
# Install Poetry plugins (one-time setup)
poetry self add poetry-dotenv-plugin

# Install all dependencies including optional extras
poetry install --all-extras
# Install the project and development dependencies
uv sync

# Setup pre-commit hooks
poetry run pre-commit install
uv run pre-commit install
```

### Testing

```bash
# Run all tests with verbose output
poetry run pytest -s -v --log-cli-level=INFO
uv run --env-file .env pytest -s -v --log-cli-level=INFO

# Run a specific test
poetry run pytest -s -v --log-cli-level=INFO tests/test_core_sdk.py::test_flush
uv run --env-file .env pytest -s -v --log-cli-level=INFO tests/test_core_sdk.py::test_flush

# Run tests in parallel (faster)
poetry run pytest -s -v --log-cli-level=INFO -n auto
uv run --env-file .env pytest -s -v --log-cli-level=INFO -n auto
```

### Code Quality

```bash
# Format code with Ruff
poetry run ruff format .
uv run ruff format .

# Run linting (development config)
poetry run ruff check .
uv run ruff check .

# Run type checking
poetry run mypy .
uv run mypy .

# Run pre-commit hooks manually
poetry run pre-commit run --all-files
uv run pre-commit run --all-files
```

### Building and Releasing

```bash
# Build the package locally (for testing)
poetry build
uv build --no-sources

# Generate documentation
poetry run pdoc -o docs/ --docformat google --logo "https://langfuse.com/langfuse_logo.svg" langfuse
uv run --group docs pdoc -o docs/ --docformat google --logo "https://langfuse.com/langfuse_logo.svg" langfuse
```

Releases are automated via GitHub Actions. To release:

1. Go to Actions > "Release Python SDK" workflow
2. Click "Run workflow"
3. Select version bump type (patch/minor/major/prerelease)
3. Select version bump type (patch/minor/major/prepatch/preminor/premajor)
4. For prereleases, select the type (alpha/beta/rc)

The workflow handles versioning, building, PyPI publishing (via OIDC), and GitHub release creation.
Expand Down Expand Up @@ -120,16 +117,16 @@ Environment variables (defined in `_client/environment_variables.py`):

## Important Files

- `pyproject.toml`: Poetry configuration, dependencies, and tool settings
- `langfuse/version.py`: Version string (updated by CI release workflow)
- `pyproject.toml`: uv project metadata, dependencies, and tool settings
- `uv.lock`: Locked dependency graph for local development and CI

## API Generation

The `langfuse/api/` directory is auto-generated from the Langfuse OpenAPI specification using Fern. To update:

1. Generate new SDK in main Langfuse repo
2. Copy generated files from `generated/python` to `langfuse/api/`
3. Run `poetry run ruff format .` to format the generated code
3. Run `uv run ruff format .` to format the generated code

## Testing Guidelines

Expand Down
Loading
Loading