redc 0.1.1.dev0__tar.gz → 0.1.1.dev2__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.
Files changed (31) hide show
  1. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/.github/workflows/before-all.sh +1 -1
  2. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/CMakeLists.txt +1 -1
  3. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/PKG-INFO +2 -2
  4. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/README.md +1 -1
  5. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/pyproject.toml +3 -2
  6. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/__init__.py +1 -1
  7. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/client.py +28 -3
  8. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/ext/redc.cpp +7 -3
  9. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/ext/redc.h +3 -0
  10. redc-0.1.1.dev0/wheelhouse/redc-0.1.1.dev0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl → redc-0.1.1.dev2/wheelhouse/redc-0.1.1.dev2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
  11. redc-0.1.1.dev0/wheelhouse/redc-0.1.1.dev0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl → redc-0.1.1.dev2/wheelhouse/redc-0.1.1.dev2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
  12. redc-0.1.1.dev0/wheelhouse/redc-0.1.1.dev0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl → redc-0.1.1.dev2/wheelhouse/redc-0.1.1.dev2-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
  13. redc-0.1.1.dev2/wheelhouse/redc-0.1.1.dev2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
  14. redc-0.1.1.dev0/wheelhouse/redc-0.1.1.dev0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl → redc-0.1.1.dev2/wheelhouse/redc-0.1.1.dev2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
  15. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/.clang-format +0 -0
  16. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/.github/workflows/build_wheels.yml +0 -0
  17. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/.gitignore +0 -0
  18. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/CMake/PreventInSourceBuild.cmake +0 -0
  19. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/LICENSE +0 -0
  20. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/assets/images/redc-logo.png +0 -0
  21. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/callback.py +0 -0
  22. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/callbacks.py +0 -0
  23. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/codes.py +0 -0
  24. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/exceptions/__init__.py +0 -0
  25. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/ext/utils/concurrentqueue.h +0 -0
  26. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/ext/utils/curl_utils.h +0 -0
  27. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/response.py +0 -0
  28. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/utils/__init__.py +0 -0
  29. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/utils/headers.py +0 -0
  30. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/utils/http.py +0 -0
  31. {redc-0.1.1.dev0 → redc-0.1.1.dev2}/redc/utils/json_encoder.py +0 -0
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- CURL_VERSION="8.11.1"
3
+ CURL_VERSION="8.12.0"
4
4
 
5
5
  # deps
6
6
  yum install wget gcc make libpsl-devel libidn-devel zlib-devel libnghttp2-devel perl-IPC-Cmd -y
@@ -43,7 +43,7 @@ if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
43
43
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
44
44
  endif()
45
45
 
46
- nanobind_add_module(redc_ext STABLE_ABI LTO redc/ext/redc.cpp)
46
+ nanobind_add_module(redc_ext STABLE_ABI FREE_THREADED NOMINSIZE LTO redc/ext/redc.cpp)
47
47
 
48
48
  target_link_libraries(redc_ext PRIVATE CURL::libcurl)
49
49
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: redc
3
- Version: 0.1.1.dev0
3
+ Version: 0.1.1.dev2
4
4
  Summary: RedC is a high-performance, asynchronous HTTP client library for Python, built on top of the powerful curl library
5
5
  Keywords: asyncio,http,client,http-client,curl,libcurl
6
6
  Author-Email: AYMEN Mohammed <let.me.code.safe@gmail.com>
@@ -14,7 +14,7 @@ Description-Content-Type: text/markdown
14
14
  <img src="https://raw.githubusercontent.com/AYMENJD/redc/refs/heads/main/assets/images/redc-logo.png">
15
15
  </div>
16
16
 
17
- [![Version](https://img.shields.io/pypi/v/redc?style=flat&logo=curl&logoColor=red&color=red)](https://pypi.org/project/RedC) [![CURL version](https://img.shields.io/badge/Curl-v8.11.1-red?logo=curl)](https://curl.se/ch/8.11.1.html) [![Downloads](https://static.pepy.tech/personalized-badge/redc?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/redc)
17
+ [![Version](https://img.shields.io/pypi/v/redc?style=flat&logo=curl&logoColor=red&color=red)](https://pypi.org/project/RedC) [![CURL version](https://img.shields.io/badge/Curl-v8.12.0-red?logo=curl)](https://curl.se/ch/8.12.0.html) [![Downloads](https://static.pepy.tech/personalized-badge/redc?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/redc)
18
18
 
19
19
  **RedC** is a **high-performance**, asynchronous **HTTP** client library for **Python**, built on top of the powerful **curl** library. It provides a simple and intuitive interface for making HTTP requests and handling responses
20
20
 
@@ -2,7 +2,7 @@
2
2
  <img src="https://raw.githubusercontent.com/AYMENJD/redc/refs/heads/main/assets/images/redc-logo.png">
3
3
  </div>
4
4
 
5
- [![Version](https://img.shields.io/pypi/v/redc?style=flat&logo=curl&logoColor=red&color=red)](https://pypi.org/project/RedC) [![CURL version](https://img.shields.io/badge/Curl-v8.11.1-red?logo=curl)](https://curl.se/ch/8.11.1.html) [![Downloads](https://static.pepy.tech/personalized-badge/redc?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/redc)
5
+ [![Version](https://img.shields.io/pypi/v/redc?style=flat&logo=curl&logoColor=red&color=red)](https://pypi.org/project/RedC) [![CURL version](https://img.shields.io/badge/Curl-v8.12.0-red?logo=curl)](https://curl.se/ch/8.12.0.html) [![Downloads](https://static.pepy.tech/personalized-badge/redc?period=month&units=none&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/redc)
6
6
 
7
7
  **RedC** is a **high-performance**, asynchronous **HTTP** client library for **Python**, built on top of the powerful **curl** library. It provides a simple and intuitive interface for making HTTP requests and handling responses
8
8
 
@@ -1,10 +1,10 @@
1
1
  [build-system]
2
- requires = ["scikit-build-core >=0.10", "nanobind >=1.3.2"]
2
+ requires = ["scikit-build-core >=0.10", "nanobind >=2.2.0"]
3
3
  build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "redc"
7
- version = "0.1.1.dev0"
7
+ version = "0.1.1.dev2"
8
8
  description = "RedC is a high-performance, asynchronous HTTP client library for Python, built on top of the powerful curl library"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "AYMEN Mohammed", email = "let.me.code.safe@gmail.com" }]
@@ -23,6 +23,7 @@ wheel.py-api = "cp312"
23
23
  [tool.cibuildwheel]
24
24
  build-verbosity = 1
25
25
  build = "cp39* cp310* cp311* cp312* cp313*"
26
+ free-threaded-support = true
26
27
  skip = "*musllinux*"
27
28
  archs = ["x86_64"]
28
29
 
@@ -15,7 +15,7 @@ __all__ = [
15
15
  "utils",
16
16
  ]
17
17
 
18
- __version__ = "0.1.1.dev0"
18
+ __version__ = "0.1.1.dev2"
19
19
  __copyright__ = "Copyright (c) 2025 RedC, AYMENJD"
20
20
  __license__ = "MIT License"
21
21
 
@@ -3,7 +3,10 @@ from urllib.parse import urlencode
3
3
  from .callbacks import StreamCallback, ProgressCallback
4
4
  from .redc_ext import RedC
5
5
  from .response import Response
6
- from .utils import json_dumps, parse_base_url
6
+ from .utils import json_dumps, parse_base_url, Headers
7
+
8
+ import asyncio
9
+ import redc
7
10
 
8
11
 
9
12
  class Client:
@@ -77,12 +80,15 @@ class Client:
77
80
  self.__base_url = (
78
81
  parse_base_url(base_url) if isinstance(base_url, str) else None
79
82
  )
80
- self.__default_headers = headers if isinstance(headers, dict) else {}
83
+ self.__default_headers = Headers(headers if isinstance(headers, dict) else {})
81
84
  self.__timeout = timeout
82
85
  self.__ca_cert_path = ca_cert_path if isinstance(ca_cert_path, str) else ""
83
86
  self.__json_encoder = json_encoder
87
+ self.__loop = asyncio.get_event_loop()
84
88
  self.__redc_ext = RedC(buffer_size)
85
89
 
90
+ self.__set_default_headers()
91
+
86
92
  async def __aenter__(self):
87
93
  return self
88
94
 
@@ -99,6 +105,12 @@ class Client:
99
105
 
100
106
  return self.__redc_ext.is_running()
101
107
 
108
+ @property
109
+ def default_headers(self):
110
+ """Returns default headers that are set on all requests"""
111
+
112
+ return self.__default_headers
113
+
102
114
  async def request(
103
115
  self,
104
116
  method: str,
@@ -362,6 +374,7 @@ class Client:
362
374
  Returns:
363
375
  :class:`redc.Response`
364
376
  """
377
+
365
378
  return await self.request(
366
379
  method="HEAD",
367
380
  url=url,
@@ -445,6 +458,7 @@ class Client:
445
458
  Returns:
446
459
  :class:`redc.Response`
447
460
  """
461
+
448
462
  return await self.request(
449
463
  method="POST",
450
464
  url=url,
@@ -534,6 +548,7 @@ class Client:
534
548
  Returns:
535
549
  :class:`redc.Response`
536
550
  """
551
+
537
552
  return await self.request(
538
553
  method="PUT",
539
554
  url=url,
@@ -693,6 +708,7 @@ class Client:
693
708
  Returns:
694
709
  :class:`redc.Response`
695
710
  """
711
+
696
712
  return await self.request(
697
713
  method="DELETE",
698
714
  url=url,
@@ -750,6 +766,7 @@ class Client:
750
766
  Returns:
751
767
  :class:`redc.Response`
752
768
  """
769
+
753
770
  return await self.request(
754
771
  method="OPTIONS",
755
772
  url=url,
@@ -768,4 +785,12 @@ class Client:
768
785
  This method must be called when the client is no longer needed to avoid memory leaks
769
786
  or unexpected behavior
770
787
  """
771
- self.__redc_ext.close()
788
+
789
+ return await self.__loop.run_in_executor(None, self.__redc_ext.close)
790
+
791
+ def __set_default_headers(self):
792
+ if "user-agent" not in self.__default_headers:
793
+ self.__default_headers["user-agent"] = f"redc/{redc.__version__}"
794
+
795
+ if "connection" not in self.__default_headers:
796
+ self.__default_headers["connection"] = "keep-alive"
@@ -73,6 +73,7 @@ py_object RedC::request(const char *method, const char *url, const char *raw_dat
73
73
  curl_easy_setopt(easy, CURLOPT_BUFFERSIZE, buffer_size_);
74
74
  curl_easy_setopt(easy, CURLOPT_URL, url);
75
75
  curl_easy_setopt(easy, CURLOPT_CUSTOMREQUEST, method);
76
+ curl_easy_setopt(easy, CURLOPT_NOSIGNAL, 1L);
76
77
 
77
78
  curl_easy_setopt(easy, CURLOPT_TIMEOUT_MS, timeout_ms);
78
79
 
@@ -177,10 +178,12 @@ py_object RedC::request(const char *method, const char *url, const char *raw_dat
177
178
 
178
179
  if (!stream_callback.is_none()) {
179
180
  d.stream_callback = stream_callback;
181
+ d.has_stream_callback = true;
180
182
  }
181
183
 
182
184
  if (!progress_callback.is_none()) {
183
185
  d.progress_callback = progress_callback;
186
+ d.has_progress_callback = true;
184
187
 
185
188
  curl_easy_setopt(easy, CURLOPT_XFERINFODATA, &d);
186
189
  curl_easy_setopt(easy, CURLOPT_NOPROGRESS, 0L);
@@ -316,9 +319,10 @@ size_t RedC::header_callback(char *buffer, size_t size, size_t nitems, Data *cli
316
319
 
317
320
  size_t RedC::progress_callback(Data *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal,
318
321
  curl_off_t ulnow) {
319
- if (!clientp->progress_callback.is_none()) {
322
+ if (clientp->has_progress_callback) {
320
323
  try {
321
- acq_gil gil;
324
+ acq_gil
325
+ gil; //TODO: this sometimes hangs on exit, which lead to other functions to block such as curl_multi_perform and worker_loop never exit
322
326
  clientp->progress_callback(dltotal, dlnow, ultotal, ulnow);
323
327
  } catch (const std::exception &e) {
324
328
  std::cerr << "Error in progress_callback: " << e.what() << std::endl;
@@ -331,7 +335,7 @@ size_t RedC::progress_callback(Data *clientp, curl_off_t dltotal, curl_off_t dln
331
335
  size_t RedC::write_callback(char *data, size_t size, size_t nmemb, Data *clientp) {
332
336
  size_t total_size = size * nmemb;
333
337
 
334
- if (!clientp->stream_callback.is_none()) {
338
+ if (clientp->has_stream_callback) {
335
339
  try {
336
340
  acq_gil gil;
337
341
  clientp->stream_callback(py_bytes(data, total_size), total_size);
@@ -38,6 +38,9 @@ struct Data {
38
38
  py_object stream_callback{nb::none()};
39
39
  py_object progress_callback{nb::none()};
40
40
 
41
+ bool has_stream_callback{false};
42
+ bool has_progress_callback{false};
43
+
41
44
  std::vector<char> headers;
42
45
  CurlSlist request_headers;
43
46
  CurlMime curl_mime_;
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes