Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
76 changes: 76 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Python Publish

on:
release:
types:
- released
pull_request:
paths:
- .github/workflows/python-publish.yml
workflow_dispatch:
inputs:
mode:
description: "dry_run: build & test only, release: build & publish to PyPI"
required: true
default: dry_run
type: choice
options:
- dry_run
- release

jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-C debuginfo=1"
RUST_BACKTRACE: "1"
CARGO_INCREMENTAL: "0"
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
cache: false

- name: Install system dependencies
run: |
sudo apt update
sudo apt install -y protobuf-compiler libssl-dev

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Install maturin
run: |
pip install maturin

- name: Build distributions
working-directory: python
run: |
uv build --sdist --wheel --out-dir dist

- name: Upload distributions
uses: actions/upload-artifact@v4
with:
name: python-dist
path: python/dist

- name: Publish to PyPI
if: >
(github.event_name == 'release' && github.event.action == 'released') ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.mode == 'release')
working-directory: python
run: |
uv publish --trusted-publishing always
2 changes: 1 addition & 1 deletion crates/lance-context-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
authors = ["Lance Devs <dev@lancedb.com>"]
repository = "https://github.com/lancedb/lance-context"
readme = "../../README.md"
readme = "README.md"
description = "Multimodal, versioned context storage for agentic workflows"
keywords = ["context", "multimodal", "lance", "agents", "storage"]
categories = ["database", "data-structures", "science"]
Expand Down
2 changes: 1 addition & 1 deletion crates/lance-context/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = "Apache-2.0"
authors = ["Lance Devs <dev@lancedb.com>"]
repository = "https://github.com/lancedb/lance-context"
description = "Public re-export crate for lance-context bindings"
readme = "../../README.md"
readme = "README.md"

[dependencies]
lance-context-core = { path = "../lance-context-core" }
3 changes: 3 additions & 0 deletions crates/lance-context/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# lance-context

This crate is a light wrapper around `lance-context-core` that re-exports the public API for downstream Rust consumers and the Python bindings build. It carries no additional logic beyond the re-export.
1 change: 1 addition & 0 deletions examples/pypi-basic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.artifacts/
35 changes: 35 additions & 0 deletions examples/pypi-basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Lance Context PyPI Example

This example project demonstrates how to install the `lance-context` package from PyPI and work with a context store using the Python API.

## Setup

Ensure Python 3.11 or newer is available locally.

### Using uv

```bash
cd examples/pypi-basic
uv venv
source .venv/bin/activate
uv pip install -e .
```

### Using pip

```bash
cd examples/pypi-basic
python -m venv .venv
source .venv/bin/activate
pip install -e .
```

## Run the demo

```bash
uv run context-demo
# or
python -m context_example.main
```

The script creates a Lance dataset under `.artifacts/` (ignored by git) and appends a short travel-planning conversation. It prints the current version, demonstrates time-travel by checking out an earlier version, and shows how you can reopen the dataset path to continue appending in future runs.
14 changes: 14 additions & 0 deletions examples/pypi-basic/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[build-system]
requires = ["setuptools>=64"]
build-backend = "setuptools.build_meta"

[project]
name = "lance-context-example"
version = "0.1.0"
description = "Example project demonstrating the lance-context PyPI package."
readme = "README.md"
requires-python = ">=3.11"
dependencies = ["lance-context>=0.1.0"]

[project.scripts]
context-demo = "context_example.main:main"
3 changes: 3 additions & 0 deletions examples/pypi-basic/src/context_example/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .main import main

__all__ = ["main"]
46 changes: 46 additions & 0 deletions examples/pypi-basic/src/context_example/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from __future__ import annotations

from pathlib import Path
from uuid import uuid4

from lance_context import Context


def main() -> None:
project_root = Path(__file__).resolve().parent.parent.parent
artifacts_dir = project_root / ".artifacts"
artifacts_dir.mkdir(exist_ok=True)

dataset_path = artifacts_dir / f"travel_context_{uuid4().hex}.lance"
ctx = Context.create(dataset_path.as_posix())
print(f"Created context store at {dataset_path}")

ctx.add("system", "You are a friendly travel agent who compares destinations.")
ctx.add("user", "Where should I travel in spring if I love street food?")
ctx.add(
"assistant",
"Consider Osaka, Japan for cherry blossoms and the Kuromon market.",
)

first_version = ctx.version()

ctx.add("user", "Any budget-friendly option in Europe?")
ctx.add(
"assistant",
"Porto, Portugal offers great food, coastal views, and reasonable prices.",
)

print(f"Entries stored: {ctx.entries()}")
print(f"Current version: {ctx.version()}")

ctx.checkout(first_version)
print(f"Rolled back to version {first_version}; entries now {ctx.entries()}")

print(
"Re-run this script to create a fresh dataset, or reuse the printed path to "
"append more entries from another process."
)


if __name__ == "__main__": # pragma: no cover - manual invocation
main()
Loading