paperstack-cli 0.4.1__tar.gz → 0.4.2__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 (32) hide show
  1. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/PKG-INFO +1 -1
  2. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/content/arxiv_pdf.py +3 -1
  3. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/content/arxiv_source.py +3 -1
  4. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/metadata.py +3 -1
  5. paperstack_cli-0.4.2/src/paperstack/tls.py +15 -0
  6. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/.gitignore +0 -0
  7. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/LICENSE +0 -0
  8. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/README.md +0 -0
  9. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/pyproject.toml +0 -0
  10. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/scripts/build/site/app.js +0 -0
  11. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/scripts/build/site/entry.html +0 -0
  12. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/scripts/build/site/favicon.svg +0 -0
  13. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/scripts/build/site/index.html +0 -0
  14. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/scripts/build/site/style.css +0 -0
  15. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/scripts/build/vendor/marked.LICENSE +0 -0
  16. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/scripts/build/vendor/marked.min.js +0 -0
  17. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/__init__.py +0 -0
  18. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/arxiv.py +0 -0
  19. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/citations.py +0 -0
  20. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/cli.py +0 -0
  21. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/content/__init__.py +0 -0
  22. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/content/vendor/latexpand +0 -0
  23. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/content/vendor/latexpand.LICENSE +0 -0
  24. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/corpora.py +0 -0
  25. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/credentials.py +0 -0
  26. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/dblp_build.py +0 -0
  27. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/dblp_catalog.py +0 -0
  28. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/dblp_index.py +0 -0
  29. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/entry_types.py +0 -0
  30. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/entrypoint.py +0 -0
  31. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/semantic_scholar.py +0 -0
  32. {paperstack_cli-0.4.1 → paperstack_cli-0.4.2}/src/paperstack/viewer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: paperstack-cli
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: Review, inspect, and retrieve research sources from one CLI
5
5
  Project-URL: Repository, https://github.com/MilkClouds/paperstack
6
6
  Project-URL: Issues, https://github.com/MilkClouds/paperstack/issues
@@ -16,6 +16,8 @@ import urllib.error
16
16
  import urllib.request
17
17
  from pathlib import Path
18
18
 
19
+ from ..tls import arxiv_context
20
+
19
21
  _CACHE_ROOT = Path(os.environ.get("XDG_CACHE_HOME", Path.home() / ".cache"))
20
22
  CACHE_DIR = Path(os.environ.get("PAPERSTACK_PAPERS_DIR", _CACHE_ROOT / "paperstack" / "papers"))
21
23
  CONVERTER = "pdf-inspector"
@@ -27,7 +29,7 @@ def _fetch(url: str, timeout: int = 60) -> bytes | None:
27
29
  req = urllib.request.Request(url, headers={"User-Agent": "paperstack/1.0 (+arxiv pdf fetch)"})
28
30
  for attempt in range(3):
29
31
  try:
30
- with urllib.request.urlopen(req, timeout=timeout) as resp:
32
+ with urllib.request.urlopen(req, timeout=timeout, context=arxiv_context()) as resp:
31
33
  return resp.read()
32
34
  except urllib.error.HTTPError as e:
33
35
  if e.code == 429:
@@ -22,6 +22,8 @@ import urllib.request
22
22
  import zlib
23
23
  from pathlib import Path
24
24
 
25
+ from ..tls import arxiv_context
26
+
25
27
  _CACHE_ROOT = Path(os.environ.get("XDG_CACHE_HOME", Path.home() / ".cache"))
26
28
  CACHE_DIR = Path(os.environ.get("PAPERSTACK_PAPERS_DIR", _CACHE_ROOT / "paperstack" / "papers"))
27
29
 
@@ -43,7 +45,7 @@ def _fetch_bytes(url: str, timeout: int = 60) -> bytes | None:
43
45
  )
44
46
  for attempt in range(3):
45
47
  try:
46
- with urllib.request.urlopen(req, timeout=timeout) as resp:
48
+ with urllib.request.urlopen(req, timeout=timeout, context=arxiv_context()) as resp:
47
49
  return resp.read()
48
50
  except urllib.error.HTTPError as e:
49
51
  if e.code == 429:
@@ -20,6 +20,7 @@ from pathlib import Path
20
20
  from filelock import FileLock
21
21
 
22
22
  from . import credentials
23
+ from .tls import arxiv_context
23
24
 
24
25
  ARXIV_NS = {"atom": "http://www.w3.org/2005/Atom", "arxiv": "http://arxiv.org/schemas/atom"}
25
26
  SOURCES = ("semantic_scholar", "dblp", "crossref", "openreview", "acl_anthology", "arxiv")
@@ -123,6 +124,7 @@ def request(
123
124
  **(headers or {}),
124
125
  }
125
126
  req = urllib.request.Request(url, headers=request_headers, data=data)
127
+ open_options = {"context": arxiv_context()} if "arxiv.org" in host else {}
126
128
  with _request_slot(request_key) as shared_timestamp:
127
129
  for attempt in range(3):
128
130
  elapsed = min(
@@ -132,7 +134,7 @@ def request(
132
134
  if elapsed < interval:
133
135
  time.sleep(interval - elapsed)
134
136
  try:
135
- with urllib.request.urlopen(req, timeout=30) as response:
137
+ with urllib.request.urlopen(req, timeout=30, **open_options) as response:
136
138
  _last_request[request_key] = time.monotonic()
137
139
  _mark_request(shared_timestamp)
138
140
  return response.read()
@@ -0,0 +1,15 @@
1
+ """TLS settings for hosts that reject some client handshakes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import functools
6
+ import ssl
7
+
8
+
9
+ @functools.cache
10
+ def arxiv_context() -> ssl.SSLContext:
11
+ # arXiv's Fastly edge answers uncached requests with 406 when the TLS 1.3
12
+ # ClientHello offers the X25519MLKEM768 hybrid key share (OpenSSL >= 3.5 default).
13
+ context = ssl.create_default_context()
14
+ context.set_ecdh_curve("X25519")
15
+ return context
File without changes
File without changes