pymcurl 8.18.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Ganesh Viswanathan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ include mcurl/cacert.pem
@@ -0,0 +1,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: pymcurl
3
+ Version: 8.18.0.1
4
+ Summary: Manage outbound HTTP connections using Curl & CurlMulti
5
+ Author-email: Ganesh Viswanathan <dev@genotrance.com>
6
+ Project-URL: Homepage, https://github.com/genotrance/mcurl
7
+ Project-URL: Repository, https://github.com/genotrance/mcurl
8
+ Project-URL: Issues, https://github.com/genotrance/mcurl/issues
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: Win32 (MS Windows)
11
+ Classifier: Environment :: MacOS X
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Natural Language :: English
16
+ Classifier: Operating System :: MacOS :: MacOS X
17
+ Classifier: Operating System :: Microsoft :: Windows
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Topic :: Internet :: WWW/HTTP
26
+ Requires-Python: >=3.9
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE.txt
29
+ Requires-Dist: cffi; implementation_name == "cpython"
30
+ Dynamic: license-file
31
+
32
+ # mcurl
33
+
34
+ [![Build status](https://img.shields.io/github/actions/workflow/status/genotrance/mcurl/main.yml?branch=main)](https://github.com/genotrance/mcurl/actions/workflows/main.yml?query=branch%3Amain)
35
+ [![PyPI version](https://img.shields.io/pypi/v/pymcurl)](https://pypi.org/project/pymcurl/)
36
+ [![License](https://img.shields.io/github/license/genotrance/mcurl)](https://github.com/genotrance/mcurl/blob/main/LICENSE.txt)
37
+
38
+ Python wrapper for [libcurl](https://curl.haxx.se/libcurl/) with a high-level
39
+ API for the easy and multi interfaces. Originally created for the
40
+ [Px](https://github.com/genotrance/px) proxy server.
41
+
42
+ ## Installation
43
+
44
+ mcurl can be installed using pip:
45
+
46
+ ```bash
47
+ pip install pymcurl
48
+ ```
49
+
50
+ Binary [packages](https://pypi.org/project/pymcurl) are provided for the following platforms:
51
+ - aarch64-linux-gnu
52
+ - aarch64-linux-musl
53
+ - arm64-mac
54
+ - i686-linux-gnu
55
+ - x86_64-linux-gnu
56
+ - x86_64-linux-musl
57
+ - x86_64-windows
58
+
59
+ mcurl leverages [cffi](https://pypi.org/project/cffi) to interface with libcurl
60
+ and all binary dependencies are sourced from [binarybuilder.org](https://binarybuilder.org/).
61
+ auditwheel on Linux, delocate on macOS and delvewheel on Windows are used to bundle
62
+ the shared libraries into the wheels.
63
+
64
+ Thanks to [cffi](https://cffi.readthedocs.io/en/latest/cdef.html#ffibuilder-compile-etc-compiling-out-of-line-modules)
65
+ and [Py_LIMITED_API](https://docs.python.org/3/c-api/stable.html#limited-c-api),
66
+ the CPython wheel works on any CPython ≥ 3.9. Separate wheels are provided for
67
+ PyPy.
68
+
69
+ ## Usage
70
+
71
+ ### Easy interface
72
+
73
+ ```python
74
+ import mcurl
75
+
76
+ mcurl.dprint = print
77
+
78
+ c = mcurl.Curl('http://httpbin.org/get')
79
+ c.set_debug()
80
+ c.buffer()
81
+ ret = c.perform()
82
+ if ret == 0:
83
+ ret, resp = c.get_response()
84
+ headers = c.get_headers()
85
+ data = c.get_data()
86
+ print(f"Response: {resp}\n\n{headers}{data}")
87
+ ```
88
+
89
+ ### Multi interface
90
+
91
+ ```python
92
+ import mcurl
93
+
94
+ mcurl.dprint = print
95
+
96
+ m = mcurl.MCurl()
97
+
98
+ c1 = mcurl.Curl('http://httpbin.org/get')
99
+ c1.set_debug()
100
+ c1.buffer()
101
+ m.add(c1)
102
+
103
+ data = "test8192".encode("utf-8")
104
+ c2 = mcurl.Curl('https://httpbin.org/post', 'POST')
105
+ c2.set_debug()
106
+ c2.buffer(data=data)
107
+ c2.set_headers({"Content-Length": len(data)})
108
+ m.add(c2)
109
+
110
+ ret1 = m.do(c1)
111
+ ret2 = m.do(c2)
112
+
113
+ if ret1:
114
+ print(f"Response: {c1.get_response()}\n\n" +
115
+ f"{c1.get_headers()}{c1.get_data()}")
116
+ else:
117
+ print(f"Failed with error: {c1.errstr}")
118
+
119
+ if ret2:
120
+ print(f"Response: {c2.get_response()}\n\n" +
121
+ f"{c2.get_headers()}{c2.get_data()}")
122
+ else:
123
+ print(f"Failed with error: {c2.errstr}")
124
+
125
+ m.close()
126
+ ```
127
+
128
+ ### Raw libcurl API
129
+
130
+ The [libcurl C API](https://curl.se/libcurl/c/) can also be accessed directly:
131
+
132
+ ```python
133
+ from _libcurl_cffi import lib as libcurl
134
+ from _libcurl_cffi import ffi
135
+
136
+ url = "http://httpbin.org/get"
137
+ curl = ffi.new("char []", url.encode("utf-8"))
138
+
139
+ easy = libcurl.curl_easy_init()
140
+ libcurl.curl_easy_setopt(easy, libcurl.CURLOPT_URL, curl)
141
+ cerr = libcurl.curl_easy_perform(easy)
142
+ ```
143
+
144
+ ## Threading
145
+
146
+ 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.
147
+
148
+ **Recommended patterns:**
149
+
150
+ - **MCurl per thread** — create a separate `MCurl` in each thread for maximum parallelism:
151
+
152
+ ```python
153
+ import threading, mcurl
154
+
155
+ def worker(url):
156
+ m = mcurl.MCurl()
157
+ c = mcurl.Curl(url)
158
+ c.buffer()
159
+ m.do(c)
160
+ print(c.get_data())
161
+ m.close()
162
+
163
+ threads = [threading.Thread(target=worker, args=(f"http://httpbin.org/get?id={i}",)) for i in range(4)]
164
+ for t in threads: t.start()
165
+ for t in threads: t.join()
166
+ ```
167
+
168
+ - **Shared MCurl** — multiple threads can share one `MCurl` instance (internally locked):
169
+
170
+ ```python
171
+ m = mcurl.MCurl()
172
+
173
+ def worker(url):
174
+ c = mcurl.Curl(url)
175
+ c.buffer()
176
+ m.do(c)
177
+ print(c.get_data())
178
+ m.remove(c)
179
+
180
+ threads = [threading.Thread(target=worker, args=(f"http://httpbin.org/get?id={i}",)) for i in range(4)]
181
+ for t in threads: t.start()
182
+ for t in threads: t.join()
183
+ m.close()
184
+ ```
185
+
186
+ ## Versioning
187
+
188
+ 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](https://github.com/genotrance/LibCURL_jll.jl) release is detected.
189
+
190
+ ## Documentation
191
+
192
+ See the [`docs/`](docs/) folder for detailed documentation:
193
+
194
+ - [**Build system**](docs/build.md) — `pyproject.toml`, `setup.py`, cffi, cibuildwheel, wheel matrix
195
+ - [**CI & GitHub Actions**](docs/ci.md) — workflows, deployment flow
196
+ - [**API reference**](docs/api.md) — `Curl`, `MCurl`, utility functions
197
+ - [**Changelog**](docs/changelog.md) — release history
198
+ - [**Testing**](docs/testing.md) — test layout, running tests, fixtures
199
+
200
+ ## Development
201
+
202
+ Requires a C compiler and [uv](https://docs.astral.sh/uv/).
203
+
204
+ ```bash
205
+ git clone https://github.com/genotrance/mcurl.git
206
+ cd mcurl
207
+ make install
208
+ make test
209
+ ```
210
+
211
+ | Target | Description |
212
+ |----------------|----------------------------------------------------|
213
+ | `make install` | Create venv, build C extension, install pre-commit |
214
+ | `make test` | Run tests with coverage |
215
+ | `make check` | Run linters and type checking |
216
+ | `make build` | Build sdist and wheel |
217
+ | `make clean` | Remove build artifacts |
218
+ | `make env` | Print LD_LIBRARY_PATH for local development |
219
+
220
+ ## Contributing
221
+
222
+ Bug reports and pull requests are welcome at <https://github.com/genotrance/mcurl/issues>.
223
+
224
+ 1. Fork and clone the repository.
225
+ 2. Run `make install` to set up the venv, build the C extension, and install pre-commit hooks.
226
+ 3. Create a feature branch, make changes, add tests in `tests/`.
227
+ 4. Run `make check && make test` — all checks must pass.
228
+ 5. Open a pull request. CI runs on Ubuntu, Windows, and macOS across Python 3.9–3.14 and PyPy 3.10/3.11.
229
+
230
+ ## Building
231
+
232
+ mcurl is built using gcc on Linux, clang on macOS and mingw-x64 on Windows. The
233
+ shared libraries are downloaded from [binarybuilder.org](https://binarybuilder.org/)
234
+ using [jbb](https://pypi.org/project/jbb) for Linux and Windows. Custom libcurl
235
+ binaries that include `kerberos` support on Linux and remove the `libssh2` dependency
236
+ are [available](https://github.com/genotrance/LibCURL_jll.jl). macOS uses the
237
+ libcurl binaries and dependencies installed via Homebrew.
238
+
239
+ [cibuildwheel](https://cibuildwheel.pypa.io/) is used to build wheels for all
240
+ platforms and architectures via GitHub Actions. See [docs/build.md](docs/build.md)
241
+ for details.
242
+
243
+ ## Acknowledgments
244
+
245
+ The modernization of this project — including expanded test suite, CI/CD infrastructure, and comprehensive documentation — was developed with the assistance of LLMs.
246
+
247
+ ## License
248
+
249
+ MIT
@@ -0,0 +1,218 @@
1
+ # mcurl
2
+
3
+ [![Build status](https://img.shields.io/github/actions/workflow/status/genotrance/mcurl/main.yml?branch=main)](https://github.com/genotrance/mcurl/actions/workflows/main.yml?query=branch%3Amain)
4
+ [![PyPI version](https://img.shields.io/pypi/v/pymcurl)](https://pypi.org/project/pymcurl/)
5
+ [![License](https://img.shields.io/github/license/genotrance/mcurl)](https://github.com/genotrance/mcurl/blob/main/LICENSE.txt)
6
+
7
+ Python wrapper for [libcurl](https://curl.haxx.se/libcurl/) with a high-level
8
+ API for the easy and multi interfaces. Originally created for the
9
+ [Px](https://github.com/genotrance/px) proxy server.
10
+
11
+ ## Installation
12
+
13
+ mcurl can be installed using pip:
14
+
15
+ ```bash
16
+ pip install pymcurl
17
+ ```
18
+
19
+ Binary [packages](https://pypi.org/project/pymcurl) are provided for the following platforms:
20
+ - aarch64-linux-gnu
21
+ - aarch64-linux-musl
22
+ - arm64-mac
23
+ - i686-linux-gnu
24
+ - x86_64-linux-gnu
25
+ - x86_64-linux-musl
26
+ - x86_64-windows
27
+
28
+ mcurl leverages [cffi](https://pypi.org/project/cffi) to interface with libcurl
29
+ and all binary dependencies are sourced from [binarybuilder.org](https://binarybuilder.org/).
30
+ auditwheel on Linux, delocate on macOS and delvewheel on Windows are used to bundle
31
+ the shared libraries into the wheels.
32
+
33
+ Thanks to [cffi](https://cffi.readthedocs.io/en/latest/cdef.html#ffibuilder-compile-etc-compiling-out-of-line-modules)
34
+ and [Py_LIMITED_API](https://docs.python.org/3/c-api/stable.html#limited-c-api),
35
+ the CPython wheel works on any CPython ≥ 3.9. Separate wheels are provided for
36
+ PyPy.
37
+
38
+ ## Usage
39
+
40
+ ### Easy interface
41
+
42
+ ```python
43
+ import mcurl
44
+
45
+ mcurl.dprint = print
46
+
47
+ c = mcurl.Curl('http://httpbin.org/get')
48
+ c.set_debug()
49
+ c.buffer()
50
+ ret = c.perform()
51
+ if ret == 0:
52
+ ret, resp = c.get_response()
53
+ headers = c.get_headers()
54
+ data = c.get_data()
55
+ print(f"Response: {resp}\n\n{headers}{data}")
56
+ ```
57
+
58
+ ### Multi interface
59
+
60
+ ```python
61
+ import mcurl
62
+
63
+ mcurl.dprint = print
64
+
65
+ m = mcurl.MCurl()
66
+
67
+ c1 = mcurl.Curl('http://httpbin.org/get')
68
+ c1.set_debug()
69
+ c1.buffer()
70
+ m.add(c1)
71
+
72
+ data = "test8192".encode("utf-8")
73
+ c2 = mcurl.Curl('https://httpbin.org/post', 'POST')
74
+ c2.set_debug()
75
+ c2.buffer(data=data)
76
+ c2.set_headers({"Content-Length": len(data)})
77
+ m.add(c2)
78
+
79
+ ret1 = m.do(c1)
80
+ ret2 = m.do(c2)
81
+
82
+ if ret1:
83
+ print(f"Response: {c1.get_response()}\n\n" +
84
+ f"{c1.get_headers()}{c1.get_data()}")
85
+ else:
86
+ print(f"Failed with error: {c1.errstr}")
87
+
88
+ if ret2:
89
+ print(f"Response: {c2.get_response()}\n\n" +
90
+ f"{c2.get_headers()}{c2.get_data()}")
91
+ else:
92
+ print(f"Failed with error: {c2.errstr}")
93
+
94
+ m.close()
95
+ ```
96
+
97
+ ### Raw libcurl API
98
+
99
+ The [libcurl C API](https://curl.se/libcurl/c/) can also be accessed directly:
100
+
101
+ ```python
102
+ from _libcurl_cffi import lib as libcurl
103
+ from _libcurl_cffi import ffi
104
+
105
+ url = "http://httpbin.org/get"
106
+ curl = ffi.new("char []", url.encode("utf-8"))
107
+
108
+ easy = libcurl.curl_easy_init()
109
+ libcurl.curl_easy_setopt(easy, libcurl.CURLOPT_URL, curl)
110
+ cerr = libcurl.curl_easy_perform(easy)
111
+ ```
112
+
113
+ ## Threading
114
+
115
+ 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.
116
+
117
+ **Recommended patterns:**
118
+
119
+ - **MCurl per thread** — create a separate `MCurl` in each thread for maximum parallelism:
120
+
121
+ ```python
122
+ import threading, mcurl
123
+
124
+ def worker(url):
125
+ m = mcurl.MCurl()
126
+ c = mcurl.Curl(url)
127
+ c.buffer()
128
+ m.do(c)
129
+ print(c.get_data())
130
+ m.close()
131
+
132
+ threads = [threading.Thread(target=worker, args=(f"http://httpbin.org/get?id={i}",)) for i in range(4)]
133
+ for t in threads: t.start()
134
+ for t in threads: t.join()
135
+ ```
136
+
137
+ - **Shared MCurl** — multiple threads can share one `MCurl` instance (internally locked):
138
+
139
+ ```python
140
+ m = mcurl.MCurl()
141
+
142
+ def worker(url):
143
+ c = mcurl.Curl(url)
144
+ c.buffer()
145
+ m.do(c)
146
+ print(c.get_data())
147
+ m.remove(c)
148
+
149
+ threads = [threading.Thread(target=worker, args=(f"http://httpbin.org/get?id={i}",)) for i in range(4)]
150
+ for t in threads: t.start()
151
+ for t in threads: t.join()
152
+ m.close()
153
+ ```
154
+
155
+ ## Versioning
156
+
157
+ 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](https://github.com/genotrance/LibCURL_jll.jl) release is detected.
158
+
159
+ ## Documentation
160
+
161
+ See the [`docs/`](docs/) folder for detailed documentation:
162
+
163
+ - [**Build system**](docs/build.md) — `pyproject.toml`, `setup.py`, cffi, cibuildwheel, wheel matrix
164
+ - [**CI & GitHub Actions**](docs/ci.md) — workflows, deployment flow
165
+ - [**API reference**](docs/api.md) — `Curl`, `MCurl`, utility functions
166
+ - [**Changelog**](docs/changelog.md) — release history
167
+ - [**Testing**](docs/testing.md) — test layout, running tests, fixtures
168
+
169
+ ## Development
170
+
171
+ Requires a C compiler and [uv](https://docs.astral.sh/uv/).
172
+
173
+ ```bash
174
+ git clone https://github.com/genotrance/mcurl.git
175
+ cd mcurl
176
+ make install
177
+ make test
178
+ ```
179
+
180
+ | Target | Description |
181
+ |----------------|----------------------------------------------------|
182
+ | `make install` | Create venv, build C extension, install pre-commit |
183
+ | `make test` | Run tests with coverage |
184
+ | `make check` | Run linters and type checking |
185
+ | `make build` | Build sdist and wheel |
186
+ | `make clean` | Remove build artifacts |
187
+ | `make env` | Print LD_LIBRARY_PATH for local development |
188
+
189
+ ## Contributing
190
+
191
+ Bug reports and pull requests are welcome at <https://github.com/genotrance/mcurl/issues>.
192
+
193
+ 1. Fork and clone the repository.
194
+ 2. Run `make install` to set up the venv, build the C extension, and install pre-commit hooks.
195
+ 3. Create a feature branch, make changes, add tests in `tests/`.
196
+ 4. Run `make check && make test` — all checks must pass.
197
+ 5. Open a pull request. CI runs on Ubuntu, Windows, and macOS across Python 3.9–3.14 and PyPy 3.10/3.11.
198
+
199
+ ## Building
200
+
201
+ mcurl is built using gcc on Linux, clang on macOS and mingw-x64 on Windows. The
202
+ shared libraries are downloaded from [binarybuilder.org](https://binarybuilder.org/)
203
+ using [jbb](https://pypi.org/project/jbb) for Linux and Windows. Custom libcurl
204
+ binaries that include `kerberos` support on Linux and remove the `libssh2` dependency
205
+ are [available](https://github.com/genotrance/LibCURL_jll.jl). macOS uses the
206
+ libcurl binaries and dependencies installed via Homebrew.
207
+
208
+ [cibuildwheel](https://cibuildwheel.pypa.io/) is used to build wheels for all
209
+ platforms and architectures via GitHub Actions. See [docs/build.md](docs/build.md)
210
+ for details.
211
+
212
+ ## Acknowledgments
213
+
214
+ The modernization of this project — including expanded test suite, CI/CD infrastructure, and comprehensive documentation — was developed with the assistance of LLMs.
215
+
216
+ ## License
217
+
218
+ MIT