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
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
pull_request:
push:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- uses: dtolnay/rust-toolchain@stable

- name: Create virtualenv
run: python -m venv .venv

- name: Build extension
uses: PyO3/maturin-action@v1
with:
command: develop
env:
VIRTUAL_ENV: ${{ github.workspace }}/.venv

- name: Install test extras
run: .venv/bin/pip install pytest pytest-asyncio httpx

- name: Test
run: .venv/bin/pytest -q
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Cargo
# will have compiled files and executables
debug
target

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# Generated by cargo mutants
# Contains mutation testing data
**/mutants.out*/

# RustRover
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

.venv/
__pycache__/
.pytest_cache/
132 changes: 132 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "rust-python-lab"
version = "0.1.0"
edition = "2024"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "rust_python_lab"
crate-type = ["cdylib"]

[dependencies]
pyo3 = "0.29.0"
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# rust-python-lab

A Rust async execution controller for Python, exposed through PyO3. Python remains the authoring surface; Rust owns scheduling, limits, and lifecycle. Python's asyncio event loop still executes coroutine bodies.

## Setup

Requires Rust (stable) and Python 3.12 (local development uses 3.12.3). CI installs CPython 3.12.

```bash
python -m venv .venv
source .venv/bin/activate
pip install maturin
maturin develop --extras dev
```

## Test

```bash
pytest
```

CI runs `maturin develop` and `pytest` on pull requests. No API keys are required.
28 changes: 28 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[build-system]
requires = ["maturin>=1.15,<2.0"]
build-backend = "maturin"

[project]
name = "rust-python-lab"
requires-python = ">=3.12"
classifiers = [
"Programming Language :: Rust",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
]
dynamic = ["version"]

[project.optional-dependencies]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.24",
"httpx>=0.27",
]

[tool.maturin]
features = ["pyo3/extension-module"]

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use pyo3::prelude::*;

/// A Python module implemented in Rust.
#[pymodule]
mod rust_python_lab {
use pyo3::prelude::*;

/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
}
5 changes: 5 additions & 0 deletions tests/test_scaffold.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from rust_python_lab import sum_as_string


def test_sum_as_string():
assert sum_as_string(1, 2) == "3"
Loading