paperstack-cli 0.4.1__py3-none-any.whl → 0.4.2__py3-none-any.whl

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.
@@ -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:
paperstack/metadata.py CHANGED
@@ -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()
paperstack/tls.py ADDED
@@ -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
@@ -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
@@ -9,12 +9,13 @@ paperstack/dblp_catalog.py,sha256=BZNV_DpHiiJKveV9m-2o5Ha6Dt9hR1knClvnn70mg0A,33
9
9
  paperstack/dblp_index.py,sha256=FRDjMAjRxaUdsKB3FXX2mJCyW6ce-sBgUb4Pk3dSSXA,20340
10
10
  paperstack/entry_types.py,sha256=Iw9_K2_2w2Has4dOi_4fxYYFdWr-Kc_3i4Qj40-Fgjw,12540
11
11
  paperstack/entrypoint.py,sha256=VWHY4qb3ZwlTY6fnZvBSZ5L28IYwxNbUv5uCO0IdQRc,891
12
- paperstack/metadata.py,sha256=EB1jbb9IUbPLdRKmRjpncelbG-Gts9G-vGufF97FQ9E,22156
12
+ paperstack/metadata.py,sha256=PQcY7luhhy2eC58vOPEND8lnrc3oi8lak_tRNg8BbbI,22282
13
13
  paperstack/semantic_scholar.py,sha256=SGJpmy4zcuwptq1Joowg_ykusyrCxA85lLFIYPvCEb8,6089
14
+ paperstack/tls.py,sha256=XEi4Re_MX4t2TChB_Yj8GvF_bdqVKOUGQmYK-w68Z_Y,452
14
15
  paperstack/viewer.py,sha256=vGQSZjzQCParjzOydPQD5WaxjUbrsj1r8EoeaFbxmZU,7277
15
16
  paperstack/content/__init__.py,sha256=rPAfhJSpEpOFyKlPNbbfEZ9-oDTbfJDEqxJHnCgHVp0,54
16
- paperstack/content/arxiv_pdf.py,sha256=m18-8CL0FAenJ0jo77QYbjpp5mKAbQ9hhyGOnNgPeUc,8778
17
- paperstack/content/arxiv_source.py,sha256=6LPMGGfi7UzKBUJglMBQWhiHVjXSrIzKRxDqjC1O_zA,15122
17
+ paperstack/content/arxiv_pdf.py,sha256=ESGZWPdqU9EpJrEsNOtzhgBlI2XWnHvhmn_bkE5IIiY,8836
18
+ paperstack/content/arxiv_source.py,sha256=E4lIx3jHtjCOhIC2WqrIJS4RhQWgm11kSZfI2ghcK5w,15180
18
19
  paperstack/content/vendor/latexpand,sha256=Z-ylXQmz-5gt7iNE5jF_fhDp8Vg5EC5qHbOOUY-DMDw,23338
19
20
  paperstack/content/vendor/latexpand.LICENSE,sha256=hpipH1rQQwKFd1DYN_FtpxSBbYqCBBjsgCKr8YuYJhQ,1529
20
21
  paperstack/viewer_assets/site/app.js,sha256=Q8kZMIy_1WECLoWQcuUHsXOuz0oANdZ3RvhoR0ORSXU,23329
@@ -24,8 +25,8 @@ paperstack/viewer_assets/site/index.html,sha256=L-RUqIQODuEYxCfky-KjdYnT8VlHuo4v
24
25
  paperstack/viewer_assets/site/style.css,sha256=MdQthEKaslRDPvEVIqB6PVkS6N9030AHGMITuSaUU24,9378
25
26
  paperstack/viewer_assets/vendor/marked.LICENSE,sha256=0XnNx76Kb3YqkDWVF6gJiKaROm5OA3MhIvCeF74B9-Y,2679
26
27
  paperstack/viewer_assets/vendor/marked.min.js,sha256=k04-Nuni2gr7Gm51B1uw8JrwUpOoROhKdHfvQJEcNJo,39589
27
- paperstack_cli-0.4.1.dist-info/METADATA,sha256=tBWM4EP5orDoWIq3dGTq_oYwyFRWEkFnJgI2PBdxLkI,9319
28
- paperstack_cli-0.4.1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
29
- paperstack_cli-0.4.1.dist-info/entry_points.txt,sha256=0716S7tM1TuT4_aj291u3335bww-f0K0wQ1u8pS7VxU,58
30
- paperstack_cli-0.4.1.dist-info/licenses/LICENSE,sha256=_i01vK4EN87TL8E1Fo6RsNIkMi9-_t-wzHTFiqfg9xk,11357
31
- paperstack_cli-0.4.1.dist-info/RECORD,,
28
+ paperstack_cli-0.4.2.dist-info/METADATA,sha256=yl3a_MAmWZnJR7PqWFvxSbzDGcoBTuytEQmI_piFljI,9319
29
+ paperstack_cli-0.4.2.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
30
+ paperstack_cli-0.4.2.dist-info/entry_points.txt,sha256=0716S7tM1TuT4_aj291u3335bww-f0K0wQ1u8pS7VxU,58
31
+ paperstack_cli-0.4.2.dist-info/licenses/LICENSE,sha256=_i01vK4EN87TL8E1Fo6RsNIkMi9-_t-wzHTFiqfg9xk,11357
32
+ paperstack_cli-0.4.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.32.0
2
+ Generator: hatchling 1.32.4
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any