Skip to content

RFC: Optional Python Interoperability Layer + PyPI Distribution (PyO3 + maturin + uv publish)  #45

@muk2

Description

@muk2

This issue proposes adding an optional Python interoperability layer for pgrsql, enabling:

  • Native Python bindings via PyO3
  • Building wheels using maturin
  • Publishing to PyPI
  • Installing via pip install pgrsql
  • Modern packaging + publishing workflow using uv publish

This would allow pgrsql to be used:

  • Inside Jupyter notebooks
  • In data science workflows
  • In ETL pipelines
  • In ML pipelines
  • In backend services
  • As a high-performance embedded SQL engine

The Python layer will remain optional and modular so it does not affect the Rust core engine.


Motivation

Python dominates:

  • Data science
  • Analytics
  • Machine learning
  • Quant research
  • Data engineering
  • Rapid prototyping

If pgrsql can be installed via:

pip install pgrsql


And used like:

import pgrsql

db = pgrsql.connect(":memory:")
result = db.query("SELECT 1;")


	•	Provide first-class Python API bindings
	•	Maintain Rust as the core execution engine
	•	Distribute wheels for:
	•	macOS
	•	Linux
	•	Windows
	•	Support Python 3.9+
	•	Use modern packaging standards
	•	Keep interop optional (feature-gated)


Phase 1: Add PyO3 Bindings

Use:
	•	pyo3
	•	maturin

Example Rust Binding


use pyo3::prelude::*;

#[pyclass]
struct PyConnection {
    inner: pgrsql::Connection,
}

#[pymethods]
impl PyConnection {
    #[new]
    fn new(path: &str) -> PyResult<Self> {
        let conn = pgrsql::Connection::connect(path)?;
        Ok(Self { inner: conn })
    }

    fn query(&self, sql: &str) -> PyResult<String> {
        let result = self.inner.query(sql)?;
        Ok(result.to_string())
    }
}

#[pymodule]
fn pgrsql(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_class::<PyConnection>()?;
    Ok(())
}

Phase 2: Add pyproject.toml

Use maturin backend:

[build-system]
requires = ["maturin>=1.0"]
build-backend = "maturin"

[project]
name = "pgrsql"
version = "0.1.0"
description = "High-performance SQL engine powered by Rust"
requires-python = ">=3.9"

Phase 3: Local Development

Build wheel locally

maturin develop

maturin build --release

Phase 4: Publishing to PyPI

Use modern uv workflow:

Authenticate

uv auth login pypi

uv publish

maturin publish

Phase 5: API Design

Design clean, Pythonic interface.

Minimal API

import pgrsql

conn = pgrsql.connect(":memory:")
rows = conn.query("SELECT * FROM users;")

conn.execute("""
WITH ranked AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rnk
    FROM employees
)
SELECT * FROM ranked WHERE rnk <= 3;
""")




DataFrame integration (Pandas/Polars)
	•	Async API
	•	Prepared statements
	•	Transaction context manager:

with conn.transaction():
    conn.execute("INSERT ...")

Optional Feature Flag

Add feature flag in Cargo:

[features]
python = ["pyo3"]

So Python bindings are only compiled when explicitly enabled.

⸻

CI Requirements
	•	Build wheels for:
	•	macOS (x86_64 + ARM64)
	•	Linux (manylinux)
	•	Windows
	•	Test Python import
	•	Test simple query execution
	•	Ensure no symbol conflicts

⸻




Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions