rnet 2.4.0__tar.gz → 2.4.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.

Potentially problematic release.


This version of rnet might be problematic. Click here for more details.

Files changed (111) hide show
  1. rnet-2.4.1/.github/FUNDING.yml +15 -0
  2. {rnet-2.4.0 → rnet-2.4.1}/Cargo.lock +29 -18
  3. {rnet-2.4.0 → rnet-2.4.1}/Cargo.toml +4 -4
  4. {rnet-2.4.0 → rnet-2.4.1}/PKG-INFO +1 -2
  5. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/__init__.pyi +55 -13
  6. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/blocking.pyi +42 -0
  7. {rnet-2.4.0 → rnet-2.4.1}/src/buffer.rs +3 -4
  8. rnet-2.4.0/src/async_impl/client.rs → rnet-2.4.1/src/client/async_impl/mod.rs +53 -25
  9. {rnet-2.4.0/src → rnet-2.4.1/src/client}/async_impl/response/http.rs +8 -6
  10. {rnet-2.4.0/src → rnet-2.4.1/src/client}/async_impl/response/ws/mod.rs +7 -5
  11. rnet-2.4.0/src/blocking/client.rs → rnet-2.4.1/src/client/blocking/mod.rs +12 -10
  12. {rnet-2.4.0/src → rnet-2.4.1/src/client}/blocking/response/http.rs +8 -7
  13. {rnet-2.4.0/src → rnet-2.4.1/src/client}/blocking/response/ws.rs +10 -10
  14. rnet-2.4.0/src/async_impl/mod.rs → rnet-2.4.1/src/client/default.rs +12 -14
  15. {rnet-2.4.0/src → rnet-2.4.1/src/client}/dns.rs +6 -3
  16. rnet-2.4.1/src/client/mod.rs +127 -0
  17. {rnet-2.4.0/src/typing → rnet-2.4.1/src/client}/param/client.rs +12 -2
  18. rnet-2.4.1/src/client/param/mod.rs +9 -0
  19. {rnet-2.4.0/src/typing → rnet-2.4.1/src/client}/param/request.rs +4 -3
  20. {rnet-2.4.0/src/typing → rnet-2.4.1/src/client}/param/ws.rs +9 -8
  21. rnet-2.4.0/src/async_impl/request.rs → rnet-2.4.1/src/client/request_ops.rs +8 -7
  22. {rnet-2.4.0 → rnet-2.4.1}/src/lib.rs +10 -122
  23. {rnet-2.4.0 → rnet-2.4.1}/src/typing/body.rs +7 -4
  24. {rnet-2.4.0 → rnet-2.4.1}/src/typing/cookie.rs +9 -7
  25. {rnet-2.4.0 → rnet-2.4.1}/src/typing/header.rs +5 -5
  26. {rnet-2.4.0 → rnet-2.4.1}/src/typing/mod.rs +7 -6
  27. {rnet-2.4.0 → rnet-2.4.1}/src/typing/multipart/form.rs +3 -2
  28. {rnet-2.4.0 → rnet-2.4.1}/src/typing/multipart/part.rs +7 -5
  29. {rnet-2.4.0 → rnet-2.4.1}/src/typing/proxy.rs +3 -2
  30. {rnet-2.4.0 → rnet-2.4.1}/src/typing/ssl.rs +2 -1
  31. {rnet-2.4.0/src → rnet-2.4.1/src/typing}/stream.rs +2 -1
  32. rnet-2.4.0/src/blocking/mod.rs +0 -7
  33. rnet-2.4.0/src/typing/param/mod.rs +0 -7
  34. {rnet-2.4.0 → rnet-2.4.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  35. {rnet-2.4.0 → rnet-2.4.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  36. {rnet-2.4.0 → rnet-2.4.1}/.github/assets/capsolver.jpg +0 -0
  37. {rnet-2.4.0 → rnet-2.4.1}/.github/dependabot.yml +0 -0
  38. {rnet-2.4.0 → rnet-2.4.1}/.github/musl_build.sh +0 -0
  39. {rnet-2.4.0 → rnet-2.4.1}/.github/workflows/ci.yml +0 -0
  40. {rnet-2.4.0 → rnet-2.4.1}/.gitignore +0 -0
  41. {rnet-2.4.0 → rnet-2.4.1}/LICENSE +0 -0
  42. {rnet-2.4.0 → rnet-2.4.1}/README.md +0 -0
  43. {rnet-2.4.0 → rnet-2.4.1}/benchmark/README.md +0 -0
  44. {rnet-2.4.0 → rnet-2.4.1}/benchmark/bench.py +0 -0
  45. {rnet-2.4.0 → rnet-2.4.1}/benchmark/benchmark_multi.jpg +0 -0
  46. {rnet-2.4.0 → rnet-2.4.1}/benchmark/benchmark_multi_threaded.jpg +0 -0
  47. {rnet-2.4.0 → rnet-2.4.1}/benchmark/benchmark_results.csv +0 -0
  48. {rnet-2.4.0 → rnet-2.4.1}/benchmark/requirements.txt +0 -0
  49. {rnet-2.4.0 → rnet-2.4.1}/benchmark/server.py +0 -0
  50. {rnet-2.4.0 → rnet-2.4.1}/pyproject.toml +0 -0
  51. {rnet-2.4.0 → rnet-2.4.1}/python/README.md +0 -0
  52. {rnet-2.4.0 → rnet-2.4.1}/python/examples/auth.py +0 -0
  53. {rnet-2.4.0 → rnet-2.4.1}/python/examples/basic_auth.py +0 -0
  54. {rnet-2.4.0 → rnet-2.4.1}/python/examples/bearer_auth.py +0 -0
  55. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/auth.py +0 -0
  56. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/basic_auth.py +0 -0
  57. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/bearer_auth.py +0 -0
  58. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/body.py +0 -0
  59. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/client.py +0 -0
  60. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/cookie.py +0 -0
  61. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/form.py +0 -0
  62. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/get.py +0 -0
  63. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/impersonate.py +0 -0
  64. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/json.py +0 -0
  65. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/multipart.py +0 -0
  66. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/proxy.py +0 -0
  67. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/query.py +0 -0
  68. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/stream.py +0 -0
  69. {rnet-2.4.0 → rnet-2.4.1}/python/examples/blocking/ws.py +0 -0
  70. {rnet-2.4.0 → rnet-2.4.1}/python/examples/body.py +0 -0
  71. {rnet-2.4.0 → rnet-2.4.1}/python/examples/client.py +0 -0
  72. {rnet-2.4.0 → rnet-2.4.1}/python/examples/exceptions.py +0 -0
  73. {rnet-2.4.0 → rnet-2.4.1}/python/examples/form.py +0 -0
  74. {rnet-2.4.0 → rnet-2.4.1}/python/examples/get.py +0 -0
  75. {rnet-2.4.0 → rnet-2.4.1}/python/examples/header_map.py +0 -0
  76. {rnet-2.4.0 → rnet-2.4.1}/python/examples/impersonate.py +0 -0
  77. {rnet-2.4.0 → rnet-2.4.1}/python/examples/json.py +0 -0
  78. {rnet-2.4.0 → rnet-2.4.1}/python/examples/multipart.py +0 -0
  79. {rnet-2.4.0 → rnet-2.4.1}/python/examples/proxy.py +0 -0
  80. {rnet-2.4.0 → rnet-2.4.1}/python/examples/query.py +0 -0
  81. {rnet-2.4.0 → rnet-2.4.1}/python/examples/request.py +0 -0
  82. {rnet-2.4.0 → rnet-2.4.1}/python/examples/stream.py +0 -0
  83. {rnet-2.4.0 → rnet-2.4.1}/python/examples/ws.py +0 -0
  84. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/__init__.py +0 -0
  85. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/blocking.py +0 -0
  86. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/cookie.py +0 -0
  87. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/cookie.pyi +0 -0
  88. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/exceptions.py +0 -0
  89. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/exceptions.pyi +0 -0
  90. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/header.py +0 -0
  91. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/header.pyi +0 -0
  92. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/impersonate.py +0 -0
  93. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/impersonate.pyi +0 -0
  94. {rnet-2.4.0 → rnet-2.4.1}/python/rnet/py.typed +0 -0
  95. {rnet-2.4.0/src → rnet-2.4.1/src/client}/async_impl/response/mod.rs +0 -0
  96. {rnet-2.4.0/src → rnet-2.4.1/src/client}/async_impl/response/ws/message.rs +0 -0
  97. {rnet-2.4.0/src → rnet-2.4.1/src/client}/blocking/response/mod.rs +0 -0
  98. {rnet-2.4.0 → rnet-2.4.1}/src/error.rs +0 -0
  99. {rnet-2.4.0 → rnet-2.4.1}/src/macros.rs +0 -0
  100. {rnet-2.4.0 → rnet-2.4.1}/src/typing/enums.rs +0 -0
  101. {rnet-2.4.0 → rnet-2.4.1}/src/typing/ipaddr.rs +0 -0
  102. {rnet-2.4.0 → rnet-2.4.1}/src/typing/json.rs +0 -0
  103. {rnet-2.4.0 → rnet-2.4.1}/src/typing/multipart/mod.rs +0 -0
  104. {rnet-2.4.0 → rnet-2.4.1}/src/typing/status.rs +0 -0
  105. {rnet-2.4.0 → rnet-2.4.1}/tests/auth_test.py +0 -0
  106. {rnet-2.4.0 → rnet-2.4.1}/tests/badssl_test.py +0 -0
  107. {rnet-2.4.0 → rnet-2.4.1}/tests/client_test.py +0 -0
  108. {rnet-2.4.0 → rnet-2.4.1}/tests/decompress_test.py +0 -0
  109. {rnet-2.4.0 → rnet-2.4.1}/tests/header_map_test.py +0 -0
  110. {rnet-2.4.0 → rnet-2.4.1}/tests/request_test.py +0 -0
  111. {rnet-2.4.0 → rnet-2.4.1}/tests/response_test.py +0 -0
@@ -0,0 +1,15 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: '0x676e67'
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12
+ polar: # Replace with a single Polar username
13
+ buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14
+ thanks_dev: # Replace with a single thanks.dev username
15
+ custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
@@ -980,7 +980,7 @@ version = "0.3.2"
980
980
  source = "registry+https://github.com/rust-lang/crates.io-index"
981
981
  checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
982
982
  dependencies = [
983
- "socket2",
983
+ "socket2 0.5.10",
984
984
  "widestring",
985
985
  "windows-sys 0.48.0",
986
986
  "winreg",
@@ -1046,7 +1046,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1046
1046
  checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
1047
1047
  dependencies = [
1048
1048
  "cfg-if",
1049
- "windows-targets 0.53.2",
1049
+ "windows-targets 0.53.3",
1050
1050
  ]
1051
1051
 
1052
1052
  [[package]]
@@ -1072,9 +1072,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
1072
1072
 
1073
1073
  [[package]]
1074
1074
  name = "litrs"
1075
- version = "0.4.1"
1075
+ version = "0.4.2"
1076
1076
  source = "registry+https://github.com/rust-lang/crates.io-index"
1077
- checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
1077
+ checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed"
1078
1078
 
1079
1079
  [[package]]
1080
1080
  name = "lock_api"
@@ -1500,9 +1500,9 @@ dependencies = [
1500
1500
 
1501
1501
  [[package]]
1502
1502
  name = "redox_syscall"
1503
- version = "0.5.15"
1503
+ version = "0.5.17"
1504
1504
  source = "registry+https://github.com/rust-lang/crates.io-index"
1505
- checksum = "7e8af0dde094006011e6a740d4879319439489813bd0bcdc7d821beaeeff48ec"
1505
+ checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
1506
1506
  dependencies = [
1507
1507
  "bitflags",
1508
1508
  ]
@@ -1573,7 +1573,7 @@ dependencies = [
1573
1573
 
1574
1574
  [[package]]
1575
1575
  name = "rnet"
1576
- version = "2.4.0"
1576
+ version = "2.4.1"
1577
1577
  dependencies = [
1578
1578
  "arc-swap",
1579
1579
  "bytes",
@@ -1592,9 +1592,9 @@ dependencies = [
1592
1592
 
1593
1593
  [[package]]
1594
1594
  name = "rustc-demangle"
1595
- version = "0.1.25"
1595
+ version = "0.1.26"
1596
1596
  source = "registry+https://github.com/rust-lang/crates.io-index"
1597
- checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
1597
+ checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
1598
1598
 
1599
1599
  [[package]]
1600
1600
  name = "rustc-hash"
@@ -1739,6 +1739,16 @@ dependencies = [
1739
1739
  "windows-sys 0.52.0",
1740
1740
  ]
1741
1741
 
1742
+ [[package]]
1743
+ name = "socket2"
1744
+ version = "0.6.0"
1745
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1746
+ checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
1747
+ dependencies = [
1748
+ "libc",
1749
+ "windows-sys 0.59.0",
1750
+ ]
1751
+
1742
1752
  [[package]]
1743
1753
  name = "stable_deref_trait"
1744
1754
  version = "1.2.0"
@@ -1954,9 +1964,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
1954
1964
 
1955
1965
  [[package]]
1956
1966
  name = "tokio"
1957
- version = "1.46.1"
1967
+ version = "1.47.0"
1958
1968
  source = "registry+https://github.com/rust-lang/crates.io-index"
1959
- checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
1969
+ checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35"
1960
1970
  dependencies = [
1961
1971
  "backtrace",
1962
1972
  "bytes",
@@ -1965,9 +1975,9 @@ dependencies = [
1965
1975
  "mio",
1966
1976
  "pin-project-lite",
1967
1977
  "slab",
1968
- "socket2",
1978
+ "socket2 0.6.0",
1969
1979
  "tokio-macros",
1970
- "windows-sys 0.52.0",
1980
+ "windows-sys 0.59.0",
1971
1981
  ]
1972
1982
 
1973
1983
  [[package]]
@@ -2525,10 +2535,11 @@ dependencies = [
2525
2535
 
2526
2536
  [[package]]
2527
2537
  name = "windows-targets"
2528
- version = "0.53.2"
2538
+ version = "0.53.3"
2529
2539
  source = "registry+https://github.com/rust-lang/crates.io-index"
2530
- checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
2540
+ checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
2531
2541
  dependencies = [
2542
+ "windows-link",
2532
2543
  "windows_aarch64_gnullvm 0.53.0",
2533
2544
  "windows_aarch64_msvc 0.53.0",
2534
2545
  "windows_i686_gnu 0.53.0",
@@ -2707,9 +2718,9 @@ dependencies = [
2707
2718
 
2708
2719
  [[package]]
2709
2720
  name = "wreq"
2710
- version = "5.2.0"
2721
+ version = "5.3.0"
2711
2722
  source = "registry+https://github.com/rust-lang/crates.io-index"
2712
- checksum = "975005bd1599111e7acd5b854373ce49f04f5eebd0ee7a7677f48785d16e2ef4"
2723
+ checksum = "137ed11c4c418fb3dc41db7323ebc49aa9b6fe6a24ce152e6b2de9d6fadd9c8f"
2713
2724
  dependencies = [
2714
2725
  "antidote",
2715
2726
  "arc-swap",
@@ -2738,7 +2749,7 @@ dependencies = [
2738
2749
  "serde",
2739
2750
  "serde_json",
2740
2751
  "serde_urlencoded",
2741
- "socket2",
2752
+ "socket2 0.5.10",
2742
2753
  "sync_wrapper",
2743
2754
  "system-configuration",
2744
2755
  "tokio",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rnet"
3
- version = "2.4.0"
3
+ version = "2.4.1"
4
4
  description = "A blazing-fast Python HTTP client with TLS fingerprint"
5
5
  edition = "2024"
6
6
  rust-version = "1.85.0"
@@ -15,7 +15,7 @@ crate-type = ["cdylib"]
15
15
  doctest = false
16
16
 
17
17
  [dependencies]
18
- tokio = { version = "1.46.0", features = ["sync"] }
18
+ tokio = "1.47.0"
19
19
  pyo3 = { version = "0.25.0", features = [
20
20
  "indexmap",
21
21
  "multiple-pymethods",
@@ -32,7 +32,7 @@ arc-swap = "1.7.1"
32
32
  url = "2.5"
33
33
  bytes = "1.10.1"
34
34
  futures-util = { version = "0.3.31", default-features = false }
35
- wreq = { version = "5.2.0", features = [
35
+ wreq = { version = "5.3.0", features = [
36
36
  "full",
37
37
  "multipart",
38
38
  "websocket",
@@ -41,7 +41,7 @@ wreq = { version = "5.2.0", features = [
41
41
  "cookies-preserve-order",
42
42
  "cookies-multiple",
43
43
  ] }
44
- wreq-util = { version = "2.2.6", features = ["emulation-rand"]}
44
+ wreq-util = { version = "2.2.6", features = ["emulation-rand"] }
45
45
 
46
46
  [target.'cfg(all(not(target_env = "msvc"), not(all(target_os = "linux", target_env = "gnu"))) )'.dependencies]
47
47
  jemallocator = { package = "tikv-jemallocator", version = "0.6", features = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rnet
3
- Version: 2.4.0
3
+ Version: 2.4.1
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -22,7 +22,6 @@ Classifier: Operating System :: MacOS
22
22
  License-File: LICENSE
23
23
  Summary: A blazing-fast Python HTTP client with TLS fingerprint
24
24
  Keywords: http,client,websocket,ja3,ja4
25
- Author: 0x676e67 <gngppz@gmail.com>
26
25
  Author-email: 0x676e67 <gngppz@gmail.com>
27
26
  License: GPL-3.0
28
27
  Requires-Python: >=3.7
@@ -125,6 +125,9 @@ class Client:
125
125
  read_timeout: Optional[int] = None,
126
126
  no_keepalive: Optional[bool] = None,
127
127
  tcp_keepalive: Optional[int] = None,
128
+ tcp_keepalive_interval: Optional[int] = None,
129
+ tcp_keepalive_retries: Optional[int] = None,
130
+ tcp_user_timeout: Optional[int] = None,
128
131
  pool_idle_timeout: Optional[int] = None,
129
132
  pool_max_idle_per_host: Optional[int] = None,
130
133
  pool_max_size: Optional[int] = None,
@@ -151,19 +154,58 @@ class Client:
151
154
  r"""
152
155
  Creates a new Client instance.
153
156
 
154
- # Examples
155
-
156
- ```python
157
- import asyncio
158
- import rnet
159
-
160
- client = rnet.Client(
161
- user_agent="my-app/0.0.1",
162
- timeout=10,
163
- )
164
- response = await client.get('https://httpbin.org/get')
165
- print(response.text)
166
- ```
157
+ Args:
158
+ impersonate: Browser fingerprint/impersonation config.
159
+ user_agent: Default User-Agent string.
160
+ default_headers: Default request headers.
161
+ headers_order: Custom header order.
162
+ referer: Automatically set Referer.
163
+ allow_redirects: Allow automatic redirects.
164
+ max_redirects: Maximum number of redirects.
165
+ cookie_store: Enable cookie store.
166
+ lookup_ip_strategy: IP lookup strategy.
167
+ timeout: Total timeout (seconds).
168
+ connect_timeout: Connection timeout (seconds).
169
+ read_timeout: Read timeout (seconds).
170
+ no_keepalive: Disable HTTP keep-alive.
171
+ tcp_keepalive: TCP keepalive time (seconds).
172
+ tcp_keepalive_interval: TCP keepalive interval (seconds).
173
+ tcp_keepalive_retries: TCP keepalive retry count.
174
+ tcp_user_timeout: TCP user timeout (seconds).
175
+ pool_idle_timeout: Connection pool idle timeout (seconds).
176
+ pool_max_idle_per_host: Max idle connections per host.
177
+ pool_max_size: Max total connections in pool.
178
+ http1_only: Enable HTTP/1.1 only.
179
+ http2_only: Enable HTTP/2 only.
180
+ https_only: Enable HTTPS only.
181
+ tcp_nodelay: Enable TCP_NODELAY.
182
+ http2_max_retry_count: Max HTTP/2 retry count.
183
+ verify: Verify SSL or specify CA path.
184
+ tls_info: Return TLS info.
185
+ min_tls_version: Minimum TLS version.
186
+ max_tls_version: Maximum TLS version.
187
+ no_proxy: Disable proxy.
188
+ proxies: Proxy server list.
189
+ local_address: Local bind address.
190
+ interface: Local network interface.
191
+ gzip: Enable gzip decompression.
192
+ brotli: Enable brotli decompression.
193
+ deflate: Enable deflate decompression.
194
+ zstd: Enable zstd decompression.
195
+
196
+ Examples:
197
+
198
+ ```python
199
+ import asyncio
200
+ import rnet
201
+
202
+ client = rnet.Client(
203
+ user_agent="my-app/0.0.1",
204
+ timeout=10,
205
+ )
206
+ response = await client.get('https://httpbin.org/get')
207
+ print(response.text)
208
+ ```
167
209
  """
168
210
 
169
211
  def get_cookies(self, url: str) -> Optional[bytes]:
@@ -45,6 +45,9 @@ class BlockingClient:
45
45
  read_timeout: Optional[int] = None,
46
46
  no_keepalive: Optional[bool] = None,
47
47
  tcp_keepalive: Optional[int] = None,
48
+ tcp_keepalive_interval: Optional[int] = None,
49
+ tcp_keepalive_retries: Optional[int] = None,
50
+ tcp_user_timeout: Optional[int] = None,
48
51
  pool_idle_timeout: Optional[int] = None,
49
52
  pool_max_idle_per_host: Optional[int] = None,
50
53
  pool_max_size: Optional[int] = None,
@@ -71,6 +74,45 @@ class BlockingClient:
71
74
  r"""
72
75
  Creates a new BlockingClient instance.
73
76
 
77
+ Args:
78
+ impersonate: Browser fingerprint/impersonation config.
79
+ user_agent: Default User-Agent string.
80
+ default_headers: Default request headers.
81
+ headers_order: Custom header order.
82
+ referer: Automatically set Referer.
83
+ allow_redirects: Allow automatic redirects.
84
+ max_redirects: Maximum number of redirects.
85
+ cookie_store: Enable cookie store.
86
+ lookup_ip_strategy: IP lookup strategy.
87
+ timeout: Total timeout (seconds).
88
+ connect_timeout: Connection timeout (seconds).
89
+ read_timeout: Read timeout (seconds).
90
+ no_keepalive: Disable HTTP keep-alive.
91
+ tcp_keepalive: TCP keepalive time (seconds).
92
+ tcp_keepalive_interval: TCP keepalive interval (seconds).
93
+ tcp_keepalive_retries: TCP keepalive retry count.
94
+ tcp_user_timeout: TCP user timeout (seconds).
95
+ pool_idle_timeout: Connection pool idle timeout (seconds).
96
+ pool_max_idle_per_host: Max idle connections per host.
97
+ pool_max_size: Max total connections in pool.
98
+ http1_only: Enable HTTP/1.1 only.
99
+ http2_only: Enable HTTP/2 only.
100
+ https_only: Enable HTTPS only.
101
+ tcp_nodelay: Enable TCP_NODELAY.
102
+ http2_max_retry_count: Max HTTP/2 retry count.
103
+ verify: Verify SSL or specify CA path.
104
+ tls_info: Return TLS info.
105
+ min_tls_version: Minimum TLS version.
106
+ max_tls_version: Maximum TLS version.
107
+ no_proxy: Disable proxy.
108
+ proxies: Proxy server list.
109
+ local_address: Local bind address.
110
+ interface: Local network interface.
111
+ gzip: Enable gzip decompression.
112
+ brotli: Enable brotli decompression.
113
+ deflate: Enable deflate decompression.
114
+ zstd: Enable zstd decompression.
115
+
74
116
  # Examples
75
117
 
76
118
  ```python
@@ -18,11 +18,10 @@
18
18
  // This ignores bug warnings for macro-generated code
19
19
  #![allow(unsafe_op_in_unsafe_fn)]
20
20
 
21
- use bytes::Bytes;
22
- use pyo3::IntoPyObjectExt;
23
- use pyo3::ffi;
24
- use pyo3::prelude::*;
25
21
  use std::os::raw::c_int;
22
+
23
+ use bytes::Bytes;
24
+ use pyo3::{IntoPyObjectExt, ffi, prelude::*};
26
25
  use wreq::header::{HeaderName, HeaderValue};
27
26
 
28
27
  /// A trait to define common buffer behavior
@@ -1,23 +1,26 @@
1
- use super::request::{execute_request, execute_websocket_request};
2
- use crate::{
3
- buffer::{HeaderValueBuffer, PyBufferProtocol},
4
- dns,
5
- error::Error,
6
- typing::{
7
- Cookie, HeaderMap, Method, SslVerify, TlsVersion,
8
- param::{ClientParams, RequestParams, UpdateClientParams, WebSocketParams},
9
- },
10
- };
1
+ pub mod response;
2
+
3
+ use std::{ops::Deref, time::Duration};
4
+
11
5
  use pyo3::{prelude::*, pybacked::PyBackedStr};
12
6
  use pyo3_async_runtimes::tokio::future_into_py;
13
- use std::ops::Deref;
14
- use std::time::Duration;
15
7
  use wreq::{
16
8
  CertStore, Url,
17
9
  header::{Entry, OccupiedEntry},
18
10
  redirect::Policy,
19
11
  };
20
12
 
13
+ use super::{
14
+ dns,
15
+ param::{ClientParams, RequestParams, UpdateClientParams, WebSocketParams},
16
+ request_ops::{execute_request, execute_websocket_request},
17
+ };
18
+ use crate::{
19
+ buffer::{HeaderValueBuffer, PyBufferProtocol},
20
+ error::Error,
21
+ typing::{Cookie, HeaderMap, Method, SslVerify, TlsVersion},
22
+ };
23
+
21
24
  /// A client for making HTTP requests.
22
25
  #[pyclass(subclass)]
23
26
  pub struct Client(wreq::Client);
@@ -215,42 +218,67 @@ impl Client {
215
218
  dns_resolver
216
219
  );
217
220
 
218
- // Timeout options.
221
+ // TCP options.
222
+ apply_option!(
223
+ apply_option_or_default,
224
+ builder,
225
+ params.no_keepalive,
226
+ no_keepalive,
227
+ false
228
+ );
219
229
  apply_option!(
220
230
  apply_transformed_option,
221
231
  builder,
222
- params.timeout,
223
- timeout,
232
+ params.tcp_keepalive,
233
+ tcp_keepalive,
224
234
  Duration::from_secs
225
235
  );
226
236
  apply_option!(
227
237
  apply_transformed_option,
228
238
  builder,
229
- params.connect_timeout,
230
- connect_timeout,
239
+ params.tcp_keepalive_interval,
240
+ tcp_keepalive_interval,
231
241
  Duration::from_secs
232
242
  );
243
+ apply_option!(
244
+ apply_if_some,
245
+ builder,
246
+ params.tcp_keepalive_retries,
247
+ tcp_keepalive_retries
248
+ );
249
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
233
250
  apply_option!(
234
251
  apply_transformed_option,
235
252
  builder,
236
- params.read_timeout,
237
- read_timeout,
253
+ params.tcp_user_timeout,
254
+ tcp_user_timeout,
238
255
  Duration::from_secs
239
256
  );
257
+
258
+ // Timeout options.
240
259
  apply_option!(
241
- apply_option_or_default,
260
+ apply_transformed_option,
242
261
  builder,
243
- params.no_keepalive,
244
- no_keepalive,
245
- false
262
+ params.timeout,
263
+ timeout,
264
+ Duration::from_secs
246
265
  );
247
266
  apply_option!(
248
267
  apply_transformed_option,
249
268
  builder,
250
- params.tcp_keepalive,
251
- tcp_keepalive,
269
+ params.connect_timeout,
270
+ connect_timeout,
271
+ Duration::from_secs
272
+ );
273
+ apply_option!(
274
+ apply_transformed_option,
275
+ builder,
276
+ params.read_timeout,
277
+ read_timeout,
252
278
  Duration::from_secs
253
279
  );
280
+
281
+ // Pool options.
254
282
  apply_option!(
255
283
  apply_transformed_option,
256
284
  builder,
@@ -1,17 +1,19 @@
1
- use crate::{
2
- buffer::{Buffer, BytesBuffer, PyBufferProtocol},
3
- error::Error,
4
- typing::{Cookie, HeaderMap, Json, SocketAddr, StatusCode, Version},
5
- };
1
+ use std::{ops::Deref, pin::Pin, sync::Arc};
2
+
6
3
  use arc_swap::ArcSwapOption;
7
4
  use futures_util::{Stream, TryStreamExt};
8
5
  use mime::Mime;
9
6
  use pyo3::{IntoPyObjectExt, prelude::*, pybacked::PyBackedStr};
10
7
  use pyo3_async_runtimes::tokio::future_into_py;
11
- use std::{ops::Deref, pin::Pin, sync::Arc};
12
8
  use tokio::sync::Mutex;
13
9
  use wreq::{TlsInfo, Url, header};
14
10
 
11
+ use crate::{
12
+ buffer::{Buffer, BytesBuffer, PyBufferProtocol},
13
+ error::Error,
14
+ typing::{Cookie, HeaderMap, Json, SocketAddr, StatusCode, Version},
15
+ };
16
+
15
17
  /// A response from a request.
16
18
  #[pyclass(subclass)]
17
19
  pub struct Response {
@@ -1,9 +1,7 @@
1
1
  mod message;
2
2
 
3
- use crate::{
4
- error::Error,
5
- typing::{Cookie, HeaderMap, SocketAddr, StatusCode, Version},
6
- };
3
+ use std::sync::Arc;
4
+
7
5
  use bytes::Bytes;
8
6
  use futures_util::{
9
7
  SinkExt, StreamExt, TryStreamExt,
@@ -12,10 +10,14 @@ use futures_util::{
12
10
  pub use message::Message;
13
11
  use pyo3::{IntoPyObjectExt, prelude::*, pybacked::PyBackedStr};
14
12
  use pyo3_async_runtimes::tokio::future_into_py;
15
- use std::sync::Arc;
16
13
  use tokio::sync::Mutex;
17
14
  use wreq::{Utf8Bytes, header::HeaderValue};
18
15
 
16
+ use crate::{
17
+ error::Error,
18
+ typing::{Cookie, HeaderMap, SocketAddr, StatusCode, Version},
19
+ };
20
+
19
21
  type Sender = Arc<Mutex<Option<SplitSink<wreq::WebSocket, wreq::Message>>>>;
20
22
  type Receiver = Arc<Mutex<Option<SplitStream<wreq::WebSocket>>>>;
21
23
 
@@ -1,16 +1,18 @@
1
- use super::{BlockingResponse, BlockingWebSocket};
2
- use crate::{
3
- async_impl::{self, execute_request, execute_websocket_request},
4
- typing::{
5
- Cookie, HeaderMap, Method,
6
- param::{ClientParams, RequestParams, UpdateClientParams, WebSocketParams},
7
- },
8
- };
1
+ mod response;
2
+
9
3
  use pyo3::{prelude::*, pybacked::PyBackedStr};
10
4
 
5
+ pub use self::response::{BlockingResponse, BlockingStreamer, BlockingWebSocket};
6
+ use super::{
7
+ async_impl::Client,
8
+ param::{ClientParams, RequestParams, UpdateClientParams, WebSocketParams},
9
+ request_ops::{execute_request, execute_websocket_request},
10
+ };
11
+ use crate::typing::{Cookie, HeaderMap, Method};
12
+
11
13
  /// A blocking client for making HTTP requests.
12
14
  #[pyclass(subclass)]
13
- pub struct BlockingClient(async_impl::Client);
15
+ pub struct BlockingClient(Client);
14
16
 
15
17
  #[pymethods]
16
18
  impl BlockingClient {
@@ -142,7 +144,7 @@ impl BlockingClient {
142
144
  #[new]
143
145
  #[pyo3(signature = (**kwds))]
144
146
  fn new(py: Python, kwds: Option<ClientParams>) -> PyResult<BlockingClient> {
145
- async_impl::Client::new(py, kwds).map(BlockingClient)
147
+ Client::new(py, kwds).map(BlockingClient)
146
148
  }
147
149
 
148
150
  /// Returns the user agent of the client.
@@ -1,19 +1,20 @@
1
1
  use std::ops::Deref;
2
2
 
3
+ use pyo3::{prelude::*, pybacked::PyBackedStr};
4
+
3
5
  use crate::{
4
- async_impl::{self},
5
6
  buffer::{BytesBuffer, PyBufferProtocol},
7
+ client::async_impl::response::{Response, Streamer},
6
8
  error::Error,
7
9
  typing::{Cookie, HeaderMap, Json, SocketAddr, StatusCode, Version},
8
10
  };
9
- use pyo3::{prelude::*, pybacked::PyBackedStr};
10
11
 
11
12
  /// A blocking response from a request.
12
13
  #[pyclass(subclass)]
13
- pub struct BlockingResponse(async_impl::Response);
14
+ pub struct BlockingResponse(Response);
14
15
 
15
- impl From<async_impl::Response> for BlockingResponse {
16
- fn from(response: async_impl::Response) -> Self {
16
+ impl From<Response> for BlockingResponse {
17
+ fn from(response: Response) -> Self {
17
18
  Self(response)
18
19
  }
19
20
  }
@@ -171,7 +172,7 @@ impl BlockingResponse {
171
172
  /// Employed in the `stream` method of the `Response` class.
172
173
  /// Utilized in an asynchronous for loop in Python.
173
174
  #[pyclass(subclass)]
174
- pub struct BlockingStreamer(async_impl::Streamer);
175
+ pub struct BlockingStreamer(Streamer);
175
176
 
176
177
  #[pymethods]
177
178
  impl BlockingStreamer {
@@ -182,7 +183,7 @@ impl BlockingStreamer {
182
183
  fn __next__(&self, py: Python) -> PyResult<Py<PyAny>> {
183
184
  py.allow_threads(|| {
184
185
  pyo3_async_runtimes::tokio::get_runtime()
185
- .block_on(async_impl::Streamer::_anext(self.0.deref().clone(), || {
186
+ .block_on(Streamer::_anext(self.0.deref().clone(), || {
186
187
  Error::StopIteration.into()
187
188
  }))
188
189
  })
@@ -1,16 +1,17 @@
1
+ use pyo3::{prelude::*, pybacked::PyBackedStr};
2
+
1
3
  use crate::{
2
- async_impl::{self, Message},
4
+ client::async_impl::response::{Message, WebSocket},
3
5
  error::Error,
4
6
  typing::{Cookie, HeaderMap, SocketAddr, StatusCode, Version},
5
7
  };
6
- use pyo3::{prelude::*, pybacked::PyBackedStr};
7
8
 
8
9
  /// A blocking WebSocket response.
9
10
  #[pyclass(subclass)]
10
- pub struct BlockingWebSocket(async_impl::WebSocket);
11
+ pub struct BlockingWebSocket(WebSocket);
11
12
 
12
- impl From<async_impl::WebSocket> for BlockingWebSocket {
13
- fn from(inner: async_impl::WebSocket) -> Self {
13
+ impl From<WebSocket> for BlockingWebSocket {
14
+ fn from(inner: WebSocket) -> Self {
14
15
  Self(inner)
15
16
  }
16
17
  }
@@ -68,8 +69,7 @@ impl BlockingWebSocket {
68
69
  /// Receives a message from the WebSocket.
69
70
  pub fn recv(&self, py: Python) -> PyResult<Option<Message>> {
70
71
  py.allow_threads(|| {
71
- pyo3_async_runtimes::tokio::get_runtime()
72
- .block_on(async_impl::WebSocket::_recv(self.0.receiver()))
72
+ pyo3_async_runtimes::tokio::get_runtime().block_on(WebSocket::_recv(self.0.receiver()))
73
73
  })
74
74
  }
75
75
 
@@ -78,7 +78,7 @@ impl BlockingWebSocket {
78
78
  pub fn send(&self, py: Python, message: Message) -> PyResult<()> {
79
79
  py.allow_threads(|| {
80
80
  pyo3_async_runtimes::tokio::get_runtime()
81
- .block_on(async_impl::WebSocket::_send(self.0.sender(), message))
81
+ .block_on(WebSocket::_send(self.0.sender(), message))
82
82
  })
83
83
  }
84
84
 
@@ -91,7 +91,7 @@ impl BlockingWebSocket {
91
91
  reason: Option<PyBackedStr>,
92
92
  ) -> PyResult<()> {
93
93
  py.allow_threads(|| {
94
- pyo3_async_runtimes::tokio::get_runtime().block_on(async_impl::WebSocket::_close(
94
+ pyo3_async_runtimes::tokio::get_runtime().block_on(WebSocket::_close(
95
95
  self.0.receiver(),
96
96
  self.0.sender(),
97
97
  code,
@@ -110,7 +110,7 @@ impl BlockingWebSocket {
110
110
  fn __next__(&self, py: Python) -> PyResult<Message> {
111
111
  py.allow_threads(|| {
112
112
  pyo3_async_runtimes::tokio::get_runtime()
113
- .block_on(async_impl::WebSocket::_anext(self.0.receiver(), || {
113
+ .block_on(WebSocket::_anext(self.0.receiver(), || {
114
114
  Error::StopIteration.into()
115
115
  }))
116
116
  })