Skip to content

RFC: Switch to rust backend for performance#27

Merged
chonknick merged 7 commits into
mainfrom
refactor-rust
Jan 7, 2026
Merged

RFC: Switch to rust backend for performance#27
chonknick merged 7 commits into
mainfrom
refactor-rust

Conversation

@chonknick

Copy link
Copy Markdown
Contributor
  • Add ci.yml for Rust tests and Python build verification
  • Add release.yml for publishing to crates.io and PyPI
  • Update sync-check.yml for new src/data path
  • Remove old lint.yml, publish.yml, test.yml (consolidated into ci.yml)

- Rewrite core library in Rust for high performance
- Add Python bindings using PyO3 and maturin
- Support all 11 embedding providers:
  - OpenAI, VoyageAI, Cohere, Jina, Mistral
  - Gemini, Together, Mixedbread, Nomic, DeepInfra, Cloudflare
- Features:
  - Sync embed() and async aembed() methods
  - Model catalog with 64+ models (compile-time embedded)
  - Configurable max_retries and timeout
  - Automatic retry with exponential backoff
  - Cost tracking per request
  - Context manager support (sync and async)
  - to_numpy() for easy numpy conversion
- Move legacy Python implementation to src_legacy/
- Update publish.yml for multi-platform wheel builds (Linux, macOS, Windows)
- Add crates.io publishing with CARGO_REGISTRY_TOKEN
- Update test.yml for Rust tests and Python bindings
- Add manual workflow_dispatch trigger for selective publishing
- Add ci.yml for Rust tests and Python build verification
- Add release.yml for publishing to crates.io and PyPI
- Update sync-check.yml for new src/data path
- Remove old lint.yml, publish.yml, test.yml (consolidated into ci.yml)
Copilot AI review requested due to automatic review settings January 7, 2026 08:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR transitions the catsu embeddings client from a pure Python implementation to a Rust-based backend with Python bindings, aimed at improving performance. The changes consolidate multiple GitHub Actions workflows, update the data path for model catalog, and introduce Rust implementations for 11 embedding providers.

Key changes:

  • Replaces Python provider implementations with Rust equivalents
  • Adds Python bindings via PyO3 for the Rust core
  • Consolidates GitHub Actions workflows (test.yml, lint.yml, publish.yml → ci.yml, release.yml)
  • Updates model catalog path from src/catsu/data/models.json to src/data/models.json

Reviewed changes

Copilot reviewed 81 out of 84 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
website/public/models.json Updates symlink path to new data location
src/providers/*.rs Implements embedding providers in Rust (VoyageAI, Together, OpenAI, Nomic, Mixedbread, Mistral, Jina, Gemini, DeepInfra, Cohere, Cloudflare)
src/catalog.rs Adds Rust model catalog with embedded JSON data
packages/python/* Introduces Python bindings and packaging for Rust library
examples/*.{rs,py} Adds example usage files for each provider
.github/workflows/* Consolidates and updates CI/CD workflows
Cargo.toml Adds Rust workspace and dependencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3 to +7
from catsu import CatsuClient


def main():
client = CatsuClient()

Copilot AI Jan 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import uses CatsuClient but other example files import Client. The exposed Python API should use Client for consistency.

Suggested change
from catsu import CatsuClient
def main():
client = CatsuClient()
from catsu import Client
def main():
client = Client()

Copilot uses AI. Check for mistakes.
Comment thread examples/latency_test.py
Comment on lines +3 to +7
from catsu import CatsuClient


def main():
client = CatsuClient()

Copilot AI Jan 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import uses CatsuClient but other example files import Client. The exposed Python API should use Client for consistency.

Suggested change
from catsu import CatsuClient
def main():
client = CatsuClient()
from catsu import Client
def main():
client = Client()

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/ci.yml
Comment on lines +11 to +28
name: Test Rust
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Run tests
run: cargo test

- name: Check formatting
run: cargo fmt --check

- name: Run clippy
run: cargo clippy -- -D warnings

test-python:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 7 months ago

To fix the problem, explicitly restrict the GITHUB_TOKEN permissions in this workflow. Since these jobs only check out code and run Rust/Python builds and tests, they only need read access to repository contents. The minimal and appropriate fix is to add a permissions: block at the top level of the workflow (so it applies to all jobs) with contents: read.

Concretely, edit .github/workflows/ci.yml and insert a new permissions: section between the name: CI and the on: block. No other changes are required, because none of the jobs needs write permissions to GitHub resources. The resulting header of the file will be:

name: CI

permissions:
  contents: read

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

This keeps existing functionality intact while enforcing least‑privilege access for the workflow’s GITHUB_TOKEN.

Suggested changeset 1
.github/workflows/ci.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,5 +1,8 @@
 name: CI
 
+permissions:
+  contents: read
+
 on:
   push:
     branches: [main]
EOF
@@ -1,5 +1,8 @@
name: CI

permissions:
contents: read

on:
push:
branches: [main]
Copilot is powered by AI and may make mistakes. Always verify output.
Comment thread .github/workflows/ci.yml
Comment on lines +29 to +60
name: Test Python
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Set up Python
run: uv python install 3.12

- name: Create virtualenv and install dependencies
run: |
uv venv
uv pip install pytest pytest-asyncio

- name: Build wheel
uses: PyO3/maturin-action@v1
with:
command: build
args: --release -m packages/python/Cargo.toml -o dist

- name: Install wheel
run: uv pip install dist/*.whl

- name: Run tests
run: |
source .venv/bin/activate
python -c "from catsu import Client, EmbedResponse, ModelInfo, Usage; print('Import OK')"
python -c "from catsu import Client; c = Client(); print(f'Models: {len(c.list_models())}')"

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 7 months ago

In general, the fix is to explicitly set a permissions block so that GITHUB_TOKEN has only the minimal scopes required. Since this workflow only checks out code and runs local build/test commands, it only needs read access to repository contents. The simplest and safest change is to add a top-level permissions section with contents: read, which will apply to all jobs (test-rust and test-python) because they do not have their own permissions blocks.

Concretely, in .github/workflows/ci.yml, add a new top-level permissions: mapping near the top of the file (e.g., after name: CI and before on:). Set contents: read as the only permission. No steps need to be modified and no additional imports or actions are required. This preserves existing functionality while constraining the GITHUB_TOKEN to read-only repository contents.

Suggested changeset 1
.github/workflows/ci.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,5 +1,8 @@
 name: CI
 
+permissions:
+  contents: read
+
 on:
   push:
     branches: [main]
EOF
@@ -1,5 +1,8 @@
name: CI

permissions:
contents: read

on:
push:
branches: [main]
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +9 to +20
name: Publish to crates.io
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Publish to crates.io
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}

publish-python:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 7 months ago

In general, the fix is to explicitly restrict GITHUB_TOKEN permissions in this workflow to the minimum required. Since the jobs only need to check out code, build, upload artifacts, and publish to external registries using separate secrets, they only require read access to repository contents. We can define a single root‐level permissions block that applies to all jobs in the workflow.

Concretely, in .github/workflows/release.yml, add a permissions: section near the top of the file (after name: or after on:) specifying contents: read. This will ensure that all jobs use a GITHUB_TOKEN limited to read‑only access to repository contents. No other code or steps need to change, and no additional imports or definitions are required.

Suggested changeset 1
.github/workflows/release.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -4,6 +4,9 @@
   release:
     types: [published]
 
+permissions:
+  contents: read
+
 jobs:
   publish-crate:
     name: Publish to crates.io
EOF
@@ -4,6 +4,9 @@
release:
types: [published]

permissions:
contents: read

jobs:
publish-crate:
name: Publish to crates.io
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +21 to +57
name: Build wheels (${{ matrix.os }}-${{ matrix.target }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64
- os: ubuntu-latest
target: aarch64
- os: macos-latest
target: x86_64
- os: macos-latest
target: aarch64
- os: windows-latest
target: x86_64
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist -m packages/python/Cargo.toml --find-interpreter
manylinux: auto

- name: Upload wheels
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}-${{ matrix.target }}
path: dist

publish-python-sdist:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 7 months ago

The general fix is to explicitly declare a permissions block that limits the GITHUB_TOKEN to the least privileges needed. Here, the jobs only need to read repository contents to check out code; they do not push commits, modify releases, or interact with issues/PRs. Therefore, adding permissions: contents: read at the workflow root is sufficient and will apply to all jobs in this workflow unless overridden.

Concretely, in .github/workflows/release.yml, add a top-level permissions: section after the name: (or before on:) with contents: read. This single change constrains the default token permissions for all jobs (publish-crate, publish-python, publish-python-sdist, and upload-pypi) without changing any of the existing steps or their behavior. No additional imports, methods, or definitions are required, as this is purely a configuration change in the workflow YAML.

Suggested changeset 1
.github/workflows/release.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,5 +1,8 @@
 name: Release
 
+permissions:
+  contents: read
+
 on:
   release:
     types: [published]
EOF
@@ -1,5 +1,8 @@
name: Release

permissions:
contents: read

on:
release:
types: [published]
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +58 to +75
name: Build Python sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist -m packages/python/Cargo.toml

- name: Upload sdist
uses: actions/upload-artifact@v4
with:
name: wheels-sdist
path: dist

upload-pypi:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 7 months ago

In general, the problem is fixed by adding an explicit permissions: block that restricts the GITHUB_TOKEN to the minimal scopes required. For this workflow, none of the jobs need to write to the repository, or access issues, pull requests, etc. They only need to read the repository contents to build and then use separate registry tokens to publish. So we can safely set contents: read at the workflow level, which applies to all jobs and satisfies CodeQL’s recommendation.

The best fix without changing functionality is to add a single top-level permissions: block right after the on: section in .github/workflows/release.yml:

  • Set permissions: contents: read at the root level.
  • This will automatically apply to all jobs (publish-crate, publish-python, publish-python-sdist, upload-pypi) since they do not define their own permissions.
  • No job requires additional scopes (such as packages or id-token) given the current snippet, because publishing is done with explicit secrets, not GITHUB_TOKEN, and there’s no OIDC usage shown.

No imports or additional methods are needed because this is a YAML workflow configuration change only.

Suggested changeset 1
.github/workflows/release.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -4,6 +4,9 @@
   release:
     types: [published]
 
+permissions:
+  contents: read
+
 jobs:
   publish-crate:
     name: Publish to crates.io
EOF
@@ -4,6 +4,9 @@
release:
types: [published]

permissions:
contents: read

jobs:
publish-crate:
name: Publish to crates.io
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +76 to +90
name: Upload to PyPI
needs: [publish-python, publish-python-sdist]
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: dist
merge-multiple: true

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_TOKEN }}

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copilot Autofix

AI 7 months ago

In general, the fix is to add an explicit permissions block that grants the least privileges required by the jobs. Since the shown jobs only need to read repository contents (for checkout) and do not modify issues, PRs, or contents, they can safely run with contents: read. Define this at the top (root) of the workflow so it applies to all jobs, including upload-pypi, which CodeQL highlighted.

Concretely, edit .github/workflows/release.yml and insert a root-level permissions block after the name: Release line (before on:). Use:

permissions:
  contents: read

This keeps GITHUB_TOKEN limited to read-only repository contents for all jobs, without changing the current functionality, because none of the steps need write access. No additional imports, methods, or definitions are required.

Suggested changeset 1
.github/workflows/release.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,5 +1,8 @@
 name: Release
 
+permissions:
+  contents: read
+
 on:
   release:
     types: [published]
EOF
@@ -1,5 +1,8 @@
name: Release

permissions:
contents: read

on:
release:
types: [published]
Copilot is powered by AI and may make mistakes. Always verify output.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jan 7, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
catsu-docs fd98d47 Commit Preview URL

Branch Preview URL
Jan 07 2026, 08:52 AM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jan 7, 2026

Copy link
Copy Markdown

Deploying catsu with  Cloudflare Pages  Cloudflare Pages

Latest commit: fd98d47
Status: ✅  Deploy successful!
Preview URL: https://a624cc3e.catsu-3ib.pages.dev
Branch Preview URL: https://refactor-rust.catsu-3ib.pages.dev

View logs

@chonknick
chonknick merged commit 3bcef66 into main Jan 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants