httpr 0.3.2__tar.gz → 0.3.3__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 (78) hide show
  1. {httpr-0.3.2 → httpr-0.3.3}/.github/workflows/mkdocs.yml +6 -3
  2. {httpr-0.3.2 → httpr-0.3.3}/Cargo.lock +1 -1
  3. {httpr-0.3.2 → httpr-0.3.3}/Cargo.toml +1 -1
  4. {httpr-0.3.2 → httpr-0.3.3}/PKG-INFO +1 -1
  5. {httpr-0.3.2 → httpr-0.3.3}/pyproject.toml +1 -1
  6. {httpr-0.3.2 → httpr-0.3.3}/src/lib.rs +6 -3
  7. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/test_client.py +42 -0
  8. {httpr-0.3.2 → httpr-0.3.3}/.github/actions/set-version/action.yml +0 -0
  9. {httpr-0.3.2 → httpr-0.3.3}/.github/copilot-instructions.md +0 -0
  10. {httpr-0.3.2 → httpr-0.3.3}/.github/workflows/CI.yml +0 -0
  11. {httpr-0.3.2 → httpr-0.3.3}/.github/workflows/CI.yml.backup +0 -0
  12. {httpr-0.3.2 → httpr-0.3.3}/.github/workflows/benchmark.yml +0 -0
  13. {httpr-0.3.2 → httpr-0.3.3}/.github/workflows/claude-code-review.yml +0 -0
  14. {httpr-0.3.2 → httpr-0.3.3}/.github/workflows/claude.yml +0 -0
  15. {httpr-0.3.2 → httpr-0.3.3}/.github/workflows/copilot-setup-steps.yml +0 -0
  16. {httpr-0.3.2 → httpr-0.3.3}/.github/workflows/set_version.py +0 -0
  17. {httpr-0.3.2 → httpr-0.3.3}/.gitignore +0 -0
  18. {httpr-0.3.2 → httpr-0.3.3}/.pre-commit-config.yaml +0 -0
  19. {httpr-0.3.2 → httpr-0.3.3}/CLAUDE.md +0 -0
  20. {httpr-0.3.2 → httpr-0.3.3}/LICENSE +0 -0
  21. {httpr-0.3.2 → httpr-0.3.3}/README.md +0 -0
  22. {httpr-0.3.2 → httpr-0.3.3}/Taskfile.yaml +0 -0
  23. {httpr-0.3.2 → httpr-0.3.3}/benchmark/README.md +0 -0
  24. {httpr-0.3.2 → httpr-0.3.3}/benchmark/__init__.py +0 -0
  25. {httpr-0.3.2 → httpr-0.3.3}/benchmark/benchmark.py +0 -0
  26. {httpr-0.3.2 → httpr-0.3.3}/benchmark/benchmark_cbor.py +0 -0
  27. {httpr-0.3.2 → httpr-0.3.3}/benchmark/generate_image.py +0 -0
  28. {httpr-0.3.2 → httpr-0.3.3}/benchmark/server.py +0 -0
  29. {httpr-0.3.2 → httpr-0.3.3}/benchmark.jpg +0 -0
  30. {httpr-0.3.2 → httpr-0.3.3}/docs/advanced/cookies.md +0 -0
  31. {httpr-0.3.2 → httpr-0.3.3}/docs/advanced/index.md +0 -0
  32. {httpr-0.3.2 → httpr-0.3.3}/docs/advanced/proxy.md +0 -0
  33. {httpr-0.3.2 → httpr-0.3.3}/docs/advanced/ssl-tls.md +0 -0
  34. {httpr-0.3.2 → httpr-0.3.3}/docs/api/async-client.md +0 -0
  35. {httpr-0.3.2 → httpr-0.3.3}/docs/api/client.md +0 -0
  36. {httpr-0.3.2 → httpr-0.3.3}/docs/api/functions.md +0 -0
  37. {httpr-0.3.2 → httpr-0.3.3}/docs/api/index.md +0 -0
  38. {httpr-0.3.2 → httpr-0.3.3}/docs/api/response.md +0 -0
  39. {httpr-0.3.2 → httpr-0.3.3}/docs/index.md +0 -0
  40. {httpr-0.3.2 → httpr-0.3.3}/docs/quickstart.md +0 -0
  41. {httpr-0.3.2 → httpr-0.3.3}/docs/tutorial/async.md +0 -0
  42. {httpr-0.3.2 → httpr-0.3.3}/docs/tutorial/authentication.md +0 -0
  43. {httpr-0.3.2 → httpr-0.3.3}/docs/tutorial/index.md +0 -0
  44. {httpr-0.3.2 → httpr-0.3.3}/docs/tutorial/making-requests.md +0 -0
  45. {httpr-0.3.2 → httpr-0.3.3}/docs/tutorial/response-handling.md +0 -0
  46. {httpr-0.3.2 → httpr-0.3.3}/docs/writings/index.md +0 -0
  47. {httpr-0.3.2 → httpr-0.3.3}/docs/writings/posts/2025-02-24-python-http-clients-suck.md +0 -0
  48. {httpr-0.3.2 → httpr-0.3.3}/httpr/__init__.py +0 -0
  49. {httpr-0.3.2 → httpr-0.3.3}/httpr/httpr.pyi +0 -0
  50. {httpr-0.3.2 → httpr-0.3.3}/httpr/py.typed +0 -0
  51. {httpr-0.3.2 → httpr-0.3.3}/httpr.code-workspace +0 -0
  52. {httpr-0.3.2 → httpr-0.3.3}/mkdocs.yml +0 -0
  53. {httpr-0.3.2 → httpr-0.3.3}/scripts/generate_certs.py +0 -0
  54. {httpr-0.3.2 → httpr-0.3.3}/src/exceptions.rs +0 -0
  55. {httpr-0.3.2 → httpr-0.3.3}/src/response.rs +0 -0
  56. {httpr-0.3.2 → httpr-0.3.3}/src/traits.rs +0 -0
  57. {httpr-0.3.2 → httpr-0.3.3}/src/utils.rs +0 -0
  58. {httpr-0.3.2 → httpr-0.3.3}/tests/benchmark/__init__.py +0 -0
  59. {httpr-0.3.2 → httpr-0.3.3}/tests/benchmark/test_performance.py +0 -0
  60. {httpr-0.3.2 → httpr-0.3.3}/tests/conftest.py +0 -0
  61. {httpr-0.3.2 → httpr-0.3.3}/tests/e2e/__init__.py +0 -0
  62. {httpr-0.3.2 → httpr-0.3.3}/tests/e2e/test_async.py +0 -0
  63. {httpr-0.3.2 → httpr-0.3.3}/tests/e2e/test_auth.py +0 -0
  64. {httpr-0.3.2 → httpr-0.3.3}/tests/e2e/test_redirects.py +0 -0
  65. {httpr-0.3.2 → httpr-0.3.3}/tests/e2e/test_ssl.py +0 -0
  66. {httpr-0.3.2 → httpr-0.3.3}/tests/e2e/test_streaming.py +0 -0
  67. {httpr-0.3.2 → httpr-0.3.3}/tests/e2e/test_uploads.py +0 -0
  68. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/__init__.py +0 -0
  69. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/cbor_test_server.py +0 -0
  70. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/httpx_conns.py +0 -0
  71. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/test_asyncclient.py +0 -0
  72. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/test_cbor.py +0 -0
  73. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/test_defs.py +0 -0
  74. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/test_docs.py +0 -0
  75. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/test_exceptions.py +0 -0
  76. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/test_ssl.py +0 -0
  77. {httpr-0.3.2 → httpr-0.3.3}/tests/unit/test_streaming.py +0 -0
  78. {httpr-0.3.2 → httpr-0.3.3}/uv.lock +0 -0
@@ -36,6 +36,9 @@ jobs:
36
36
  # Capture source commit BEFORE switching branches
37
37
  SOURCE_COMMIT=$(git rev-parse --short HEAD)
38
38
 
39
+ # Save the built site before switching branches
40
+ cp -r site /tmp/site-backup
41
+
39
42
  # Fetch gh-pages branch
40
43
  git fetch origin gh-pages:gh-pages || true
41
44
 
@@ -58,12 +61,12 @@ jobs:
58
61
  # Remove all tracked files
59
62
  git rm -rf . || true
60
63
 
61
- # Copy new docs from site/ directory
62
- if [ ! -d "site" ] || [ -z "$(ls -A site 2>/dev/null)" ]; then
64
+ # Copy new docs from backup
65
+ if [ ! -d "/tmp/site-backup" ] || [ -z "$(ls -A /tmp/site-backup 2>/dev/null)" ]; then
63
66
  echo "Error: site/ directory is empty or missing"
64
67
  exit 1
65
68
  fi
66
- cp -r site/* .
69
+ cp -r /tmp/site-backup/* .
67
70
 
68
71
  # Restore benchmark data if it existed
69
72
  if [ -f /tmp/bench-backup/data.js ] || [ -f /tmp/bench-backup/index.html ]; then
@@ -481,7 +481,7 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
481
481
 
482
482
  [[package]]
483
483
  name = "httpr"
484
- version = "0.3.2"
484
+ version = "0.3.3"
485
485
  dependencies = [
486
486
  "anyhow",
487
487
  "bytes",
@@ -2,7 +2,7 @@
2
2
  name = "httpr"
3
3
  # Version is set dynamically by CI from git tags (e.g., v1.2.3 -> 1.2.3).
4
4
  # Do not edit manually. See .github/actions/set-version/ for details.
5
- version = "0.3.2"
5
+ version = "0.3.3"
6
6
  edition = "2021"
7
7
  description = "Fast HTTP client for python"
8
8
  authors = ["thomasht86"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httpr
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -11,7 +11,7 @@ keywords = [ "python", "request",]
11
11
  classifiers = [ "Programming Language :: Rust", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules",]
12
12
  # Version is set dynamically by CI from git tags (e.g., v1.2.3 -> 1.2.3).
13
13
  # Do not edit manually. See .github/actions/set-version/ for details.
14
- version = "0.3.2"
14
+ version = "0.3.3"
15
15
  dependencies = []
16
16
  [[project.authors]]
17
17
  name = "thomasht86"
@@ -145,7 +145,7 @@ impl RClient {
145
145
  let mut client_builder = reqwest::Client::builder();
146
146
 
147
147
  // Headers || Cookies
148
- if headers.is_some() || cookies.is_some() {
148
+ let headers_headermap = if headers.is_some() || cookies.is_some() {
149
149
  let headers = headers.unwrap_or_else(|| IndexMap::with_hasher(RandomState::default()));
150
150
  let mut headers_headermap = headers.to_headermap();
151
151
  if let Some(cookies) = cookies {
@@ -156,7 +156,10 @@ impl RClient {
156
156
  .map_err(|e| map_anyhow_error(anyhow::Error::new(e)))?,
157
157
  );
158
158
  }
159
- client_builder = client_builder.default_headers(headers_headermap);
159
+ client_builder = client_builder.default_headers(headers_headermap.clone());
160
+ headers_headermap
161
+ } else {
162
+ reqwest::header::HeaderMap::new()
160
163
  };
161
164
 
162
165
  // Cookie_store
@@ -231,7 +234,7 @@ impl RClient {
231
234
  let client = Arc::new(Mutex::new(
232
235
  client_builder.build().map_err(map_reqwest_error)?,
233
236
  ));
234
- let headers = Arc::new(Mutex::new(reqwest::header::HeaderMap::new()));
237
+ let headers = Arc::new(Mutex::new(headers_headermap));
235
238
 
236
239
  Ok(RClient {
237
240
  client,
@@ -278,6 +278,48 @@ def test_client_post_files(test_files):
278
278
  assert json_data["files"] == {"file1": "aaa111", "file2": "bbb222"}
279
279
 
280
280
 
281
+ def test_constructor_headers_accessible():
282
+ """Test that headers passed to constructor are accessible via the headers property."""
283
+ client = httpr.Client(headers={"X-Custom": "value", "User-Agent": "test-agent"})
284
+ assert client.headers == {"x-custom": "value", "user-agent": "test-agent"}
285
+ client.close()
286
+
287
+
288
+ def test_constructor_headers_with_cookies():
289
+ """Test that cookies are excluded from headers getter when passed to constructor."""
290
+ client = httpr.Client(
291
+ headers={"X-Custom": "value"},
292
+ cookies={"session": "abc123"},
293
+ )
294
+ # Cookies should not appear in headers getter
295
+ assert client.headers == {"x-custom": "value"}
296
+ # But cookies should be accessible via cookies getter
297
+ assert client.cookies == {"session": "abc123"}
298
+ client.close()
299
+
300
+
301
+ def test_constructor_cookies_only():
302
+ """Test that cookies-only constructor doesn't expose Cookie header."""
303
+ client = httpr.Client(cookies={"session": "abc123"})
304
+ # Headers should be empty (no Cookie header exposed)
305
+ assert client.headers == {}
306
+ # Cookies should be accessible
307
+ assert client.cookies == {"session": "abc123"}
308
+ client.close()
309
+
310
+
311
+ def test_setter_overwrites_constructor_headers():
312
+ """Test that setting headers overwrites constructor headers."""
313
+ client = httpr.Client(headers={"X-Original": "original"})
314
+ assert client.headers == {"x-original": "original"}
315
+ # Overwrite with new headers
316
+ client.headers = {"X-New": "new"}
317
+ assert client.headers == {"x-new": "new"}
318
+ # Original header should be gone
319
+ assert "x-original" not in client.headers
320
+ client.close()
321
+
322
+
281
323
  def test_graceful_invalid_header_handling(base_url_ssl, ca_bundle):
282
324
  """Test that invalid header values are handled gracefully without crashing."""
283
325
  client = httpr.Client(ca_cert_file=ca_bundle)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes