mcurl
Python wrapper for libcurl with a high-level API for the easy and multi interfaces. Originally created for the Px proxy server.
Installation
mcurl can be installed using pip:
pip install pymcurl
Binary packages are provided for the following platforms:
- aarch64-linux-gnu
- aarch64-linux-musl
- arm64-mac
- i686-linux-gnu
- x86_64-linux-gnu
- x86_64-linux-musl
- x86_64-windows
mcurl leverages cffi to interface with libcurl and all binary dependencies are sourced from binarybuilder.org. auditwheel on Linux, delocate on macOS and delvewheel on Windows are used to bundle the shared libraries into the wheels.
Thanks to cffi and Py_LIMITED_API, the CPython wheel works on any CPython ≥ 3.9. Separate wheels are provided for PyPy.
Usage
Easy interface
import mcurl
mcurl.dprint = print
c = mcurl.Curl('http://httpbin.org/get')
c.set_debug()
c.buffer()
ret = c.perform()
if ret == 0:
ret, resp = c.get_response()
headers = c.get_headers()
data = c.get_data()
print(f"Response: {resp}\n\n{headers}{data}")
Multi interface
import mcurl
mcurl.dprint = print
m = mcurl.MCurl()
c1 = mcurl.Curl('http://httpbin.org/get')
c1.set_debug()
c1.buffer()
m.add(c1)
data = "test8192".encode("utf-8")
c2 = mcurl.Curl('https://httpbin.org/post', 'POST')
c2.set_debug()
c2.buffer(data=data)
c2.set_headers({"Content-Length": len(data)})
m.add(c2)
ret1 = m.do(c1)
ret2 = m.do(c2)
if ret1:
print(f"Response: {c1.get_response()}\n\n" +
f"{c1.get_headers()}{c1.get_data()}")
else:
print(f"Failed with error: {c1.errstr}")
if ret2:
print(f"Response: {c2.get_response()}\n\n" +
f"{c2.get_headers()}{c2.get_data()}")
else:
print(f"Failed with error: {c2.errstr}")
m.close()
Raw libcurl API
The libcurl C API can also be accessed directly:
from mcurl import ffi, libcurl
url = "http://httpbin.org/get"
curl = ffi.new("char []", url.encode("utf-8"))
easy = libcurl.curl_easy_init()
libcurl.curl_easy_setopt(easy, libcurl.CURLOPT_URL, curl)
cerr = libcurl.curl_easy_perform(easy)
Threading
Each MCurl instance manages its own curl multi handle with internal locking for thread-safe concurrent operations. Multiple threads can safely call add(), do(), remove(), and stop() on the same MCurl instance.
Recommended patterns:
-
MCurl per thread — create a separate
MCurlin each thread for maximum parallelism:import threading, mcurl def worker(url): m = mcurl.MCurl() c = mcurl.Curl(url) c.buffer() m.do(c) print(c.get_data()) m.close() threads = [threading.Thread(target=worker, args=(f"http://httpbin.org/get?id={i}",)) for i in range(4)] for t in threads: t.start() for t in threads: t.join()
-
Shared MCurl — multiple threads can share one
MCurlinstance (internally locked):m = mcurl.MCurl() def worker(url): c = mcurl.Curl(url) c.buffer() m.do(c) print(c.get_data()) m.remove(c) threads = [threading.Thread(target=worker, args=(f"http://httpbin.org/get?id={i}",)) for i in range(4)] for t in threads: t.start() for t in threads: t.join() m.close()
Versioning
Version format is X.Y.Z.P where X.Y.Z matches the upstream libcurl version and P is the wrapper patch (starts at 1 per upstream release). Wheels are built automatically when a new LibCURL_jll.jl release is detected.
Documentation
See the docs/ folder for detailed documentation:
- Build system —
pyproject.toml,setup.py, cffi, cibuildwheel, wheel matrix - CI & GitHub Actions — workflows, deployment flow
- API reference —
Curl,MCurl, utility functions - Changelog — release history
- Testing — test layout, running tests, fixtures
Development
Requires a C compiler and uv.
git clone https://github.com/genotrance/mcurl.git
cd mcurl
make install
make test
| Target | Description |
|---|---|
make install |
Create venv, build C extension, install pre-commit |
make test |
Run tests with coverage |
make check |
Run linters and type checking |
make build |
Build sdist and wheel |
make clean |
Remove build artifacts |
make env |
Print LD_LIBRARY_PATH for local development |
Contributing
Bug reports and pull requests are welcome at https://github.com/genotrance/mcurl/issues.
- Fork and clone the repository.
- Run
make installto set up the venv, build the C extension, and install pre-commit hooks. - Create a feature branch, make changes, add tests in
tests/. - Run
make check && make test— all checks must pass. - Open a pull request. CI runs on Ubuntu, Windows, and macOS across Python 3.9–3.14 and PyPy 3.11.
Building
mcurl is built using gcc on Linux, clang on macOS and mingw-x64 on Windows. The
shared libraries are downloaded from binarybuilder.org
using jbb for Linux and Windows. Custom libcurl
binaries that include kerberos support on Linux and remove the libssh2 dependency
are available. macOS uses the
libcurl binaries and dependencies installed via Homebrew.
cibuildwheel is used to build wheels for all platforms and architectures via GitHub Actions. See docs/build.md for details.
Acknowledgments
The modernization of this project — including expanded test suite, CI/CD infrastructure, and comprehensive documentation — was developed with the assistance of LLMs.
License
MIT
Metadata
Release files for pymcurl 8.21.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pymcurl-8.21.0.1.tar.gz | 148.7 kB | Details |
Built distributions (wheels)
Total release size: 52.4 MB
Release files / pymcurl-8.21.0.1.tar.gz
| Download URL | pymcurl-8.21.0.1.tar.gz |
|---|---|
| Size | 148.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fd9f884f734bdcadf68f02007254dcd237d2c523453dd13bd462dc62b9496162
|
|
BLAKE2b-256 checksum How to use checksums |
32b515841a4362829bc2d6f4a80c8f296030f370db903897c43f38c2ab86b08f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pymcurl-8.21.0.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 6.0 MB |
| Tags | Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 PyPy 3.11 PyPy 3.11 7.3 |
|
SHA-256 checksum How to use checksums |
9ae704b53e9e056503b3183d03b6aa05caf8103a1b8cb73cdaa5dbbe8ed51289
|
|
BLAKE2b-256 checksum How to use checksums |
6e159f88247586ce6c764fa26fc7c861f3bb0355e20b00f07832090c9001fcbb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl
| Download URL | pymcurl-8.21.0.1-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl |
|---|---|
| Size | 5.8 MB |
| Tags | Linux glibc 2.17+ x86-32 Linux glibc 2.28+ x86-32 PyPy 3.11 PyPy 3.11 7.3 |
|
SHA-256 checksum How to use checksums |
28ad899037312641e6be65360757d18dc2136be5fd612a9f19d3f7dac0ee9b1f
|
|
BLAKE2b-256 checksum How to use checksums |
6502a4613b4a2cc735c4b40ed550fe7a69fdf47869e7ef83031c10f87174e8cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pymcurl-8.21.0.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 5.6 MB |
| Tags | Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 PyPy 3.11 PyPy 3.11 7.3 |
|
SHA-256 checksum How to use checksums |
601fa8e7b83215ead1cb105ca88b9be0c498737b0b7cceabfeab1c1f29f0bf24
|
|
BLAKE2b-256 checksum How to use checksums |
a1b2246884c0209cae951cb536e79d0bedd6833eeaca1de9f6077ab6b47b9f83
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-cp39-abi3-win_amd64.whl
| Download URL | pymcurl-8.21.0.1-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
5e789d2f73249cef3f205f14e0a7224f3f59244392e45a2d48ab189d382dfb9d
|
|
BLAKE2b-256 checksum How to use checksums |
ead99f4ff835dba2868b77ca14cda143db16d0eb7b5c2ca2824a3cc912623b6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-cp39-abi3-musllinux_1_2_x86_64.whl
| Download URL | pymcurl-8.21.0.1-cp39-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 6.0 MB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4244b0d8d7cd76ef8e695926329598ee2b870bbf6b99ea41c2aa9b61a94aaa57
|
|
BLAKE2b-256 checksum How to use checksums |
11c468fb652935ce9d1523faeae5f143b38ff09cf70c0bfcb2c25dc6e93ef699
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-cp39-abi3-musllinux_1_2_aarch64.whl
| Download URL | pymcurl-8.21.0.1-cp39-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 5.6 MB |
| Tags | CPython 3.9 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
ee62eb931735ef61c50138aada524bd0ea74687a9047ef1fdb4174bf95163305
|
|
BLAKE2b-256 checksum How to use checksums |
423a38808dde7f1b88de91894d1263da34ddbb33624db8a2edcc92b594b42ce4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | pymcurl-8.21.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 6.1 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
fe2d1a71bbfe073cc6f835f6b143b8a17044e908d03f78c8921921850a50706d
|
|
BLAKE2b-256 checksum How to use checksums |
ed24193c7f5112d3afcf796452da2f31bc5d5b4287f0369f2fd466dae7e2576b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-cp39-abi3-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl
| Download URL | pymcurl-8.21.0.1-cp39-abi3-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl |
|---|---|
| Size | 5.9 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-32 Linux glibc 2.28+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
7d62b00c1746ed09971a889377a2fa39b1eca7fb32f51e37eb37f29ef39310ff
|
|
BLAKE2b-256 checksum How to use checksums |
7f97f4e5c5578a550aa70214e9948a0d423916d9f0d642cc483eb0f436180a53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | pymcurl-8.21.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 5.7 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
9ca195944576a7ba33a4fdded3057900fd65ff273fdeb0c543ee9e983ef24fca
|
|
BLAKE2b-256 checksum How to use checksums |
ea6a55d5b392182c7d084f30c6175b9eaafa53e50a3d9f786df1a48a5b5af5cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency logRelease files / pymcurl-8.21.0.1-cp39-abi3-macosx_14_0_arm64.whl
| Download URL | pymcurl-8.21.0.1-cp39-abi3-macosx_14_0_arm64.whl |
|---|---|
| Size | 4.0 MB |
| Tags | CPython 3.9 abi3 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
76aa6f7f41a09ef7ab75a9f7b112820b609401bd8302b93d84f0204638d34343
|
|
BLAKE2b-256 checksum How to use checksums |
7baa649beae8e1a4d1d63486e42b8f087956d6b97d3987ef8f23678fa051b584
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.
Transparency log