crossref-local 0.3.1__py3-none-any.whl → 0.4.0__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.
@@ -20,19 +20,19 @@ Async usage:
20
20
  Configuration
21
21
  -------------
22
22
 
23
- Local mode (direct database access):
23
+ DB mode (direct database access):
24
24
  >>> from crossref_local import configure
25
25
  >>> configure("/path/to/crossref.db")
26
26
  Or set CROSSREF_LOCAL_DB environment variable.
27
27
 
28
- Remote mode (API access via HTTP):
29
- >>> from crossref_local import configure_remote
30
- >>> configure_remote("http://localhost:3333")
31
- Or set CROSSREF_LOCAL_API environment variable.
28
+ HTTP mode (API access via HTTP):
29
+ >>> from crossref_local import configure_http
30
+ >>> configure_http("http://localhost:8333")
31
+ Or set CROSSREF_LOCAL_API_URL environment variable.
32
32
 
33
33
  Typical setup with SSH tunnel:
34
- $ ssh -L 3333:127.0.0.1:3333 nas # In terminal
35
- >>> configure_remote() # Uses default localhost:3333
34
+ $ ssh -L 8333:127.0.0.1:8333 your-server # In terminal
35
+ >>> configure_http() # Uses default localhost:8333
36
36
 
37
37
  Public API
38
38
  ----------
@@ -43,6 +43,8 @@ Functions:
43
43
  get(doi) -> Work | None
44
44
  get_many(dois) -> list[Work]
45
45
  exists(doi) -> bool
46
+ enrich(results) -> SearchResult
47
+ enrich_dois(dois) -> list[Work]
46
48
  configure(db_path) -> None
47
49
  configure_remote(api_url) -> None
48
50
  get_mode() -> str
@@ -71,8 +73,11 @@ from .api import (
71
73
  get,
72
74
  get_many,
73
75
  exists,
76
+ enrich,
77
+ enrich_dois,
74
78
  configure,
75
- configure_remote,
79
+ configure_http,
80
+ configure_remote, # Backward compatibility alias
76
81
  get_mode,
77
82
  info,
78
83
  )
@@ -86,6 +91,9 @@ from . import aio
86
91
  # Citation network (public functions and classes)
87
92
  from .citations import get_citing, get_cited, get_citation_count, CitationNetwork
88
93
 
94
+ # Cache module (public)
95
+ from . import cache
96
+
89
97
 
90
98
  # Public API - what users should import
91
99
  __all__ = [
@@ -97,9 +105,13 @@ __all__ = [
97
105
  "get",
98
106
  "get_many",
99
107
  "exists",
108
+ # Enrichment (add citations/references to search results)
109
+ "enrich",
110
+ "enrich_dois",
100
111
  # Configuration
101
112
  "configure",
102
- "configure_remote",
113
+ "configure_http",
114
+ "configure_remote", # Backward compatibility alias
103
115
  "get_mode",
104
116
  "info",
105
117
  # Data models
@@ -107,6 +119,8 @@ __all__ = [
107
119
  "SearchResult",
108
120
  # Async API
109
121
  "aio",
122
+ # Cache module
123
+ "cache",
110
124
  # Citation network
111
125
  "get_citing",
112
126
  "get_cited",
File without changes
crossref_local/aio.py CHANGED
File without changes
crossref_local/api.py CHANGED
@@ -1,13 +1,13 @@
1
1
  """Main API for crossref_local.
2
2
 
3
3
  Supports two modes:
4
- - local: Direct database access (requires database file)
5
- - remote: HTTP API access (requires API server)
4
+ - db: Direct database access (requires database file)
5
+ - http: HTTP API access (requires API server)
6
6
 
7
7
  Mode is auto-detected or can be set explicitly via:
8
- - CROSSREF_LOCAL_MODE environment variable ("local" or "remote")
9
- - CROSSREF_LOCAL_API environment variable (API URL)
10
- - configure() or configure_remote() functions
8
+ - CROSSREF_LOCAL_MODE environment variable ("db" or "http")
9
+ - CROSSREF_LOCAL_API_URL environment variable (API URL)
10
+ - configure() or configure_http() functions
11
11
  """
12
12
 
13
13
  from typing import List, Optional
@@ -18,8 +18,8 @@ from .models import Work, SearchResult
18
18
  from . import fts
19
19
 
20
20
 
21
- def _get_remote_client():
22
- """Get remote client (lazy import to avoid circular dependency)."""
21
+ def _get_http_client():
22
+ """Get HTTP client (lazy import to avoid circular dependency)."""
23
23
  from .remote import RemoteClient
24
24
 
25
25
  return RemoteClient(Config.get_api_url())
@@ -48,8 +48,8 @@ def search(
48
48
  >>> results = search("machine learning")
49
49
  >>> print(f"Found {results.total} matches")
50
50
  """
51
- if Config.get_mode() == "remote":
52
- client = _get_remote_client()
51
+ if Config.get_mode() == "http":
52
+ client = _get_http_client()
53
53
  return client.search(query=query, limit=limit)
54
54
  return fts.search(query, limit, offset)
55
55
 
@@ -64,8 +64,8 @@ def count(query: str) -> int:
64
64
  Returns:
65
65
  Number of matching works
66
66
  """
67
- if Config.get_mode() == "remote":
68
- client = _get_remote_client()
67
+ if Config.get_mode() == "http":
68
+ client = _get_http_client()
69
69
  result = client.search(query=query, limit=1)
70
70
  return result.total
71
71
  return fts.count(query)
@@ -86,8 +86,8 @@ def get(doi: str) -> Optional[Work]:
86
86
  >>> work = get("10.1038/nature12373")
87
87
  >>> print(work.title)
88
88
  """
89
- if Config.get_mode() == "remote":
90
- client = _get_remote_client()
89
+ if Config.get_mode() == "http":
90
+ client = _get_http_client()
91
91
  return client.get(doi)
92
92
  db = get_db()
93
93
  metadata = db.get_metadata(doi)
@@ -106,8 +106,8 @@ def get_many(dois: List[str]) -> List[Work]:
106
106
  Returns:
107
107
  List of Work objects (missing DOIs are skipped)
108
108
  """
109
- if Config.get_mode() == "remote":
110
- client = _get_remote_client()
109
+ if Config.get_mode() == "http":
110
+ client = _get_http_client()
111
111
  return client.get_many(dois)
112
112
  db = get_db()
113
113
  works = []
@@ -128,8 +128,8 @@ def exists(doi: str) -> bool:
128
128
  Returns:
129
129
  True if DOI exists
130
130
  """
131
- if Config.get_mode() == "remote":
132
- client = _get_remote_client()
131
+ if Config.get_mode() == "http":
132
+ client = _get_http_client()
133
133
  return client.exists(doi)
134
134
  db = get_db()
135
135
  row = db.fetchone("SELECT 1 FROM works WHERE doi = ?", (doi,))
@@ -151,29 +151,104 @@ def configure(db_path: str) -> None:
151
151
  close_db() # Reset singleton to use new path
152
152
 
153
153
 
154
- def configure_remote(api_url: str = "http://localhost:3333") -> None:
154
+ def configure_http(api_url: str = "http://localhost:8333") -> None:
155
155
  """
156
- Configure for remote API access.
156
+ Configure for HTTP API access.
157
157
 
158
158
  Args:
159
159
  api_url: URL of CrossRef Local API server
160
160
 
161
161
  Example:
162
- >>> from crossref_local import configure_remote
163
- >>> configure_remote("http://localhost:3333")
162
+ >>> from crossref_local import configure_http
163
+ >>> configure_http("http://localhost:8333")
164
164
  >>> # Or via SSH tunnel:
165
- >>> # ssh -L 3333:127.0.0.1:3333 nas
166
- >>> configure_remote() # Uses default localhost:3333
165
+ >>> # ssh -L 8333:127.0.0.1:8333 your-server
166
+ >>> configure_http() # Uses default localhost:8333
167
167
  """
168
168
  Config.set_api_url(api_url)
169
169
 
170
170
 
171
+ # Backward compatibility alias
172
+ configure_remote = configure_http
173
+
174
+
175
+ def enrich(
176
+ results: SearchResult,
177
+ include_citations: bool = True,
178
+ include_references: bool = True,
179
+ ) -> SearchResult:
180
+ """
181
+ Enrich search results with full metadata (citations, references).
182
+
183
+ The search() function returns basic metadata for speed. This function
184
+ fetches full metadata for each work, adding citation counts and references.
185
+
186
+ Args:
187
+ results: SearchResult from search()
188
+ include_citations: Include citation counts
189
+ include_references: Include reference DOIs
190
+
191
+ Returns:
192
+ SearchResult with enriched works
193
+
194
+ Example:
195
+ >>> from crossref_local import search, enrich
196
+ >>> results = search("machine learning", limit=10)
197
+ >>> enriched = enrich(results)
198
+ >>> for work in enriched:
199
+ ... print(f"{work.title}: {work.citation_count} citations")
200
+ """
201
+ enriched_works = []
202
+ for work in results.works:
203
+ full_work = get(work.doi)
204
+ if full_work:
205
+ enriched_works.append(full_work)
206
+ else:
207
+ # Keep original if full metadata not available
208
+ enriched_works.append(work)
209
+
210
+ return SearchResult(
211
+ works=enriched_works,
212
+ total=results.total,
213
+ query=results.query,
214
+ elapsed_ms=results.elapsed_ms,
215
+ )
216
+
217
+
218
+ def enrich_dois(
219
+ dois: List[str],
220
+ include_citations: bool = True,
221
+ include_references: bool = True,
222
+ ) -> List[Work]:
223
+ """
224
+ Enrich a list of DOIs with full metadata.
225
+
226
+ Fetches complete metadata for each DOI including citation counts
227
+ and reference lists.
228
+
229
+ Args:
230
+ dois: List of DOIs to enrich
231
+ include_citations: Include citation counts
232
+ include_references: Include reference DOIs
233
+
234
+ Returns:
235
+ List of Work objects with full metadata
236
+
237
+ Example:
238
+ >>> from crossref_local import enrich_dois
239
+ >>> works = enrich_dois(["10.1038/nature12373", "10.1126/science.aax0758"])
240
+ >>> for w in works:
241
+ ... print(f"{w.doi}: {w.citation_count} citations, {len(w.references)} refs")
242
+ """
243
+ return get_many(dois)
244
+
245
+
171
246
  def get_mode() -> str:
172
247
  """
173
248
  Get current mode.
174
249
 
175
250
  Returns:
176
- "local" or "remote"
251
+ "db" or "http"
177
252
  """
178
253
  return Config.get_mode()
179
254
 
@@ -187,10 +262,10 @@ def info() -> dict:
187
262
  """
188
263
  mode = Config.get_mode()
189
264
 
190
- if mode == "remote":
191
- client = _get_remote_client()
192
- remote_info = client.info()
193
- return {"mode": "remote", **remote_info}
265
+ if mode == "http":
266
+ client = _get_http_client()
267
+ http_info = client.info()
268
+ return {"mode": "http", **http_info}
194
269
 
195
270
  db = get_db()
196
271
 
@@ -213,7 +288,7 @@ def info() -> dict:
213
288
  citation_count = 0
214
289
 
215
290
  return {
216
- "mode": "local",
291
+ "mode": "db",
217
292
  "db_path": str(Config.get_db_path()),
218
293
  "works": work_count,
219
294
  "fts_indexed": fts_count,