scitex 2.15.3__py3-none-any.whl → 2.15.4__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.
- scitex/_mcp_resources/__init__.py +2 -0
- scitex/_mcp_resources/_scholar.py +148 -0
- scitex/_mcp_tools/scholar.py +50 -99
- scitex/canvas/mcp_server.py +16 -3
- scitex/capture/mcp_server.py +16 -2
- scitex/cli/scholar/__init__.py +55 -28
- scitex/cli/scholar/_crossref_scitex.py +25 -266
- scitex/cli/scholar/_openalex_scitex.py +55 -0
- scitex/scholar/__init__.py +14 -9
- scitex/scholar/_mcp/crossref_tool_schemas.py +133 -0
- scitex/scholar/_mcp/openalex_handlers.py +212 -0
- scitex/scholar/_mcp/openalex_tool_schemas.py +96 -0
- scitex/scholar/_mcp/tool_schemas.py +16 -1
- scitex/scholar/local_dbs/__init__.py +31 -0
- scitex/scholar/local_dbs/crossref_scitex.py +30 -0
- scitex/scholar/local_dbs/openalex_scitex.py +30 -0
- scitex/scholar/mcp_server.py +59 -4
- scitex/stats/mcp_server.py +16 -3
- scitex/template/mcp_server.py +16 -3
- scitex/ui/mcp_server.py +16 -3
- {scitex-2.15.3.dist-info → scitex-2.15.4.dist-info}/METADATA +1 -1
- {scitex-2.15.3.dist-info → scitex-2.15.4.dist-info}/RECORD +25 -18
- scitex/scholar/crossref_scitex.py +0 -367
- {scitex-2.15.3.dist-info → scitex-2.15.4.dist-info}/WHEEL +0 -0
- {scitex-2.15.3.dist-info → scitex-2.15.4.dist-info}/entry_points.txt +0 -0
- {scitex-2.15.3.dist-info → scitex-2.15.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -8,11 +8,12 @@ scitex/_optional_deps.py,sha256=ouMy8bw7cxl-AONRNi8xQoxwacR8irKxbcTAI18Hkzw,1014
|
|
|
8
8
|
scitex/errors.py,sha256=Pxk8TKpGRk_QBFVB46H7k1Uxetja0OEdYjJjV_lrxRM,2874
|
|
9
9
|
scitex/mcp_server.py,sha256=VNjs3N21x3_yAzfR8HhuFJJOvYOBHgvJo4tKDQdQsLE,6081
|
|
10
10
|
scitex/units.py,sha256=lm2SH4PGXz-22tjUoBQhvKJDKmPD01ykSFWoCaFC384,10356
|
|
11
|
-
scitex/_mcp_resources/__init__.py,sha256=
|
|
11
|
+
scitex/_mcp_resources/__init__.py,sha256=RomYv2wi1PYC8Z3ymAv46q0HygVErrSlViigLTWEuLY,1368
|
|
12
12
|
scitex/_mcp_resources/_cheatsheet.py,sha256=pdwzAB3IEr7UHkFv0D0-TJGeHF6ENtuq6NHeneLgKo8,3883
|
|
13
13
|
scitex/_mcp_resources/_figrecipe.py,sha256=A8oK3FwDqSNYyYI4jwfNJ2yiH_8XVnfFjoGJtuvdDLU,3581
|
|
14
14
|
scitex/_mcp_resources/_formats.py,sha256=EyNZKtmX6dg6vK1Gk0EmrSSKH5d9yc3RMqZtSP-Op0I,2923
|
|
15
15
|
scitex/_mcp_resources/_modules.py,sha256=17LZpOPSmr9XwgGJg2vRgEK596S5FoSYb320vgm9x-k,8702
|
|
16
|
+
scitex/_mcp_resources/_scholar.py,sha256=RSYt7j6bcbKtR-tOtvCtdE6J3IS8C925_c34t0Z1Es8,4689
|
|
16
17
|
scitex/_mcp_resources/_session.py,sha256=lbe9W3cfPOyoq6bPOeN-jB8MwI4DnRWMpxHmpfn97SM,4590
|
|
17
18
|
scitex/_mcp_tools/__init__.py,sha256=6krJPLr6ReVAkGoZR7vQHQrszr8AGW4dwWsY2EcmPkc,1229
|
|
18
19
|
scitex/_mcp_tools/audio.py,sha256=LBX9YQZkNGAXfoIEFljnHRk39gTyJfdaVPCRrS6F8qE,6245
|
|
@@ -21,7 +22,7 @@ scitex/_mcp_tools/capture.py,sha256=k7pwuB1vdP-VCYjutajEZEsvVAKY-8_mEYrYGWXgOo8,
|
|
|
21
22
|
scitex/_mcp_tools/diagram.py,sha256=pZNq0UTRlg7piq0YDD40qY5M2mqFYoRdFwmWeRCBieA,585
|
|
22
23
|
scitex/_mcp_tools/introspect.py,sha256=GY9j9EUAs-CKegzfPHubPT3OGpOjcY5Rb09M3OHEIwA,6562
|
|
23
24
|
scitex/_mcp_tools/plt.py,sha256=CuI6uOsyDGrLCWHWwnEKru-KCA532GVzt6rcRlxXHt8,9248
|
|
24
|
-
scitex/_mcp_tools/scholar.py,sha256=
|
|
25
|
+
scitex/_mcp_tools/scholar.py,sha256=Tp8PlcHraLvHMrQWgFgq2jdjAIM4Vsps92mVgZu9NcY,13374
|
|
25
26
|
scitex/_mcp_tools/social.py,sha256=wyyHCybx0tCUfIEGrGYhxj1thlH-dcIeq05TtUP9RFk,816
|
|
26
27
|
scitex/_mcp_tools/stats.py,sha256=U2pGC0NTfzb0stKGafVNdgZhIYovYi6ti1EoG4f4dn4,6139
|
|
27
28
|
scitex/_mcp_tools/template.py,sha256=NhfIaVYo7JvssZk_dUvzosvcc-qjnxFr69dV1DmAlgY,3102
|
|
@@ -242,7 +243,7 @@ scitex/browser/stealth/__init__.py,sha256=KVbyLjm8KnM5YwyB84A3pwLdUGkANNgwpA7YL2
|
|
|
242
243
|
scitex/canvas/README.md,sha256=jRwasTPNrmQsCyv67ul7qUIgv5xKIab1u2hi8tvlbAg,9142
|
|
243
244
|
scitex/canvas/__init__.py,sha256=k_1mqbodRgy6phbhLDqRenEEnOLvueWwj0xNNYrCyd0,9380
|
|
244
245
|
scitex/canvas/canvas.py,sha256=1aUjIqCzwKhGXukCQsHc-h-kqLNA9VqzIMazimqm2mA,12968
|
|
245
|
-
scitex/canvas/mcp_server.py,sha256=
|
|
246
|
+
scitex/canvas/mcp_server.py,sha256=fBTmtXOhO60wG-e6j-Y-WE_aWykAMsajWkidZRQ6lcU,4754
|
|
246
247
|
scitex/canvas/_mcp/__init__.py,sha256=FJRAr90vUCg4PJ8Sv-WzsKuM7aY93m6UR87fhk843MU,73
|
|
247
248
|
scitex/canvas/_mcp/handlers.py,sha256=oVZcYfEyDBl6lEKJ7vTWnrueBO-CWOiAbGNrKVFQOww,8528
|
|
248
249
|
scitex/canvas/_mcp/tool_schemas.py,sha256=Tl6CIpuW_J0QppShjZPo0DJ8wiNgLk6oHBoR74ASC7Y,8046
|
|
@@ -364,7 +365,7 @@ scitex/capture/capture.py,sha256=vDVaY2mTNxTsWbg8he78jh0NPhVULLzanREkE9EtQHE,287
|
|
|
364
365
|
scitex/capture/cli.py,sha256=bNal0BXlAM34q9OLv1ydV9lHq95pckY0XaaxsiQTkts,7201
|
|
365
366
|
scitex/capture/gif.py,sha256=Rbx-9u6zGAjImhFWp5yLm3MXCW1oaUq8OusWdPnzJAY,11278
|
|
366
367
|
scitex/capture/grid.py,sha256=LQKNyP5I1UN50rCnxi0tCf7vurLLp3mwRzCoYDa10ZQ,14189
|
|
367
|
-
scitex/capture/mcp_server.py,sha256=
|
|
368
|
+
scitex/capture/mcp_server.py,sha256=jIRAHW48jEvhhk2NYVZifkI42s-XzkGmt7UKwmJ0xDw,38059
|
|
368
369
|
scitex/capture/session.py,sha256=N-8mY6A6QmJHRCJYW4dQhrK7iVmJhYBRDt8vYyeBNYE,1972
|
|
369
370
|
scitex/capture/utils.py,sha256=WyMr8aGmWqOneT4BFTvWNY-PrMPxmKLHtUEgSk59URY,21881
|
|
370
371
|
scitex/capture/_mcp/__init__.py,sha256=MhQoN-oXeeZ-P34rJDluwSi45hf3sC4pVi8MfTW6LBc,286
|
|
@@ -397,11 +398,12 @@ scitex/cli/template.py,sha256=omoT2qzWtyqJYqrIqJ74uyDgoQTL667ONSbwSQU4sb8,12015
|
|
|
397
398
|
scitex/cli/tex.py,sha256=d_Fh9PXObuyjMgQ_Ap60aXwAztJbY3Pd2SvfV92toBg,9222
|
|
398
399
|
scitex/cli/web.py,sha256=_XwnlsOm2MD1eyJVycfsdki4IcDnglXTO5IkZ-eb3xA,13482
|
|
399
400
|
scitex/cli/writer.py,sha256=lApUnUQrclbufEMwD4m4MKMDg3ZkCBe0kTS9WuH4hsM,1953
|
|
400
|
-
scitex/cli/scholar/__init__.py,sha256=
|
|
401
|
-
scitex/cli/scholar/_crossref_scitex.py,sha256
|
|
401
|
+
scitex/cli/scholar/__init__.py,sha256=BQyPjd1jAgcHbjGPZx_amrlGOPM3UaKAdi9JyflQ9k8,8326
|
|
402
|
+
scitex/cli/scholar/_crossref_scitex.py,sha256=-ujYGB-KNtMCMoOBNsOl_qTEp6k6l75JeUqmUwjjG5o,1636
|
|
402
403
|
scitex/cli/scholar/_fetch.py,sha256=tdRXlsTjhfdOddJwWpOZ5scGGXzhesxrXX9Ri9jm7AQ,11226
|
|
403
404
|
scitex/cli/scholar/_jobs.py,sha256=hx1aoxdHaR800XC7acWE4x_pxJ7cYq6re7Zf8MxLr7E,9058
|
|
404
405
|
scitex/cli/scholar/_library.py,sha256=GP3JAtfg3zwGD810BygJLN4B0-m-RqRfyt7_JHtOeT8,4468
|
|
406
|
+
scitex/cli/scholar/_openalex_scitex.py,sha256=-KjFYxnehgJtf4Xz35U_SJqC2zXvvkmdV0ZXThxGpQI,1559
|
|
405
407
|
scitex/cli/scholar/_utils.py,sha256=SC-_wB0UFV89p-4PVdVeREbTOp6oV2ke4QRiiRzShig,770
|
|
406
408
|
scitex/cloud/__init__.py,sha256=xyzKrQGDpoCMNTLNQmCZjvVQxuPlcj306Kjn3psZCNk,5064
|
|
407
409
|
scitex/cloud/_matplotlib_hook.py,sha256=B5IEctAF1Rb7jvkZa5Xl8T1FuBcGiRjFxEtW_mmRz2I,3731
|
|
@@ -1278,17 +1280,19 @@ scitex/schema/_theme.py,sha256=1AWmJy7vim2lmIJlbjv4BCLxKmNeqw0WGEGr2z_U9Kw,10192
|
|
|
1278
1280
|
scitex/schema/_validation.py,sha256=8u4dVVfAhCzdRtcpqFxChumRMyHJQfBQgnyf1TpsQ_s,13747
|
|
1279
1281
|
scitex/scholar/.gitignore,sha256=oYROO1p7Mia9ftRowaRu3BVNm7jdMY9O4Ro1RSgSC80,381
|
|
1280
1282
|
scitex/scholar/README.md,sha256=AbE7t0qIKQY11ZSGkeQXNP_qA088q-2t-oQ3W5bDvxI,3799
|
|
1281
|
-
scitex/scholar/__init__.py,sha256=
|
|
1283
|
+
scitex/scholar/__init__.py,sha256=F7a-OTd8kqZK2vRQVhAGMTqkOGynMc7FRND_SROFTg8,10392
|
|
1282
1284
|
scitex/scholar/__main__.py,sha256=U7QKol30Vsvw_Xg4tVS5F1iFU4UluKnm1Z0Bs18zgCs,9711
|
|
1283
|
-
scitex/scholar/
|
|
1284
|
-
scitex/scholar/mcp_server.py,sha256=m-v1sjU0sJeaL0rHrihQz6alost__Koc7wyEAqP7bIY,12553
|
|
1285
|
+
scitex/scholar/mcp_server.py,sha256=z_b4pD2z1H2bG1B6ATt3B6e8uNBMl-MLz6a3KLnaCiw,14934
|
|
1285
1286
|
scitex/scholar/_mcp/__init__.py,sha256=FJRAr90vUCg4PJ8Sv-WzsKuM7aY93m6UR87fhk843MU,73
|
|
1286
1287
|
scitex/scholar/_mcp/all_handlers.py,sha256=yALfZdQhDXWPlqUB1rcncENXyVVFNDnpGqhz5iCc-5Q,1856
|
|
1287
1288
|
scitex/scholar/_mcp/crossref_handlers.py,sha256=fBN9pVzQLiGT4FWoLGAOdsm-_-gwhMo1EEl0S9MlA0c,7770
|
|
1289
|
+
scitex/scholar/_mcp/crossref_tool_schemas.py,sha256=v1VI3I2r_LWqt4IuEJo_JvXxtdY04eZ3zk6Kvqumou4,4748
|
|
1288
1290
|
scitex/scholar/_mcp/handlers.py,sha256=gMFBHPdqfWGRUDSu3wlllVBnJSzrkGm9ZUnUBhZXCY0,51088
|
|
1289
1291
|
scitex/scholar/_mcp/job_handlers.py,sha256=8ZkFRG1TOq20168DIpic3VMAMzTzieg1jnaE7eXQLlU,4970
|
|
1290
1292
|
scitex/scholar/_mcp/job_tool_schemas.py,sha256=xDTysuf3aLNxLO1O57sal5XcMeEstk0SB77wK9q6yVs,5777
|
|
1291
|
-
scitex/scholar/_mcp/
|
|
1293
|
+
scitex/scholar/_mcp/openalex_handlers.py,sha256=r9X1mwMqqwovrbx4pcgHQeISCbGqqW87neP6EW09Pnw,6503
|
|
1294
|
+
scitex/scholar/_mcp/openalex_tool_schemas.py,sha256=zu7--BZ7_aEnaJuEg-Sb1FiKNoeRthat70S9TZ70uL4,3194
|
|
1295
|
+
scitex/scholar/_mcp/tool_schemas.py,sha256=ng_lGqhwa_2BxByASZriDgnZSHTewvqpF6jOzqRxEZ0,19818
|
|
1292
1296
|
scitex/scholar/auth/README.md,sha256=YYLVVHAgHFjoYXjWJ2SV_3toOJPSnWOs6-EMKbPIu9U,3373
|
|
1293
1297
|
scitex/scholar/auth/ScholarAuthManager.py,sha256=u1t9FrTbBQyGvNmuuMprSpCLLxG0Fap-oCrm0x0iDSE,10570
|
|
1294
1298
|
scitex/scholar/auth/__init__.py,sha256=kM_iLBm00U1sVBr1TuAT7dY46kZqcOCUztMykxBlxhQ,470
|
|
@@ -1490,6 +1494,9 @@ scitex/scholar/jobs/_JobManager.py,sha256=F06vxOZoYouqgeNVmlwKpDPkWWh-PU2aLp3pqu
|
|
|
1490
1494
|
scitex/scholar/jobs/__init__.py,sha256=dXdPmFUWf-Ypl41_Z6qsduYCofygfgq2UjiIZcYiGjQ,1779
|
|
1491
1495
|
scitex/scholar/jobs/_errors.py,sha256=V7Xv4q0CDBJIQ6NSg-lRb_skFcqT-jIZ_aI5gavjDds,10211
|
|
1492
1496
|
scitex/scholar/jobs/_executors.py,sha256=kWU9uuN_8cx6oPyGakjcypsiZoUwicrHL29_aF_iZUU,11807
|
|
1497
|
+
scitex/scholar/local_dbs/__init__.py,sha256=sxCiEcOy5pC6VBpEExHgkAlu1st7EUcfw6PRFo67buQ,857
|
|
1498
|
+
scitex/scholar/local_dbs/crossref_scitex.py,sha256=Ib2JluhqyYjDPh0hZqENHNP7_eg21AQnkyWjl5pfXRs,748
|
|
1499
|
+
scitex/scholar/local_dbs/openalex_scitex.py,sha256=mnHHMnk2aJcSfXYWJh2wsbs818oU1fW63i_3VZG7wpI,748
|
|
1493
1500
|
scitex/scholar/metadata_engines/README.md,sha256=wz1fTeru9sTgkGO5T8VdDBsd4FBaZu2t6-I8MTNGifw,919
|
|
1494
1501
|
scitex/scholar/metadata_engines/ScholarEngine.py,sha256=WGOEvCiBiMm0aZNtN1AlBDCcN6XQUl76R6zedUhR7gs,20604
|
|
1495
1502
|
scitex/scholar/metadata_engines/__init__.py,sha256=qjndZBrK2tXOMCRHFeEu2BJ9Ir8nbr7cHsV4xvXUwv4,749
|
|
@@ -2408,7 +2415,7 @@ scitex/stats/__init__.py,sha256=ZD8j9RTrlwg_JNV3vcTzaovHM0eWKtsfJa5Uno4iWpE,1003
|
|
|
2408
2415
|
scitex/stats/__main__.py,sha256=Jnupr0q90w0ZKbnHSsqXmFWukMGuXzG4bPXInj8Gqmo,7815
|
|
2409
2416
|
scitex/stats/_figrecipe_integration.py,sha256=_nOD1rcITE3HGEc3-5Bu0Q2VRy3Tizil7H35GJyeOng,3076
|
|
2410
2417
|
scitex/stats/_schema.py,sha256=d12piS129kDRnHAD3XJ96d3G8ZLeYm1tK4CAlBfdtbg,1105
|
|
2411
|
-
scitex/stats/mcp_server.py,sha256=
|
|
2418
|
+
scitex/stats/mcp_server.py,sha256=_tjHu7Gubq8519Q_mfKzGGyPUINjoDpAmlszLVlKHZk,15511
|
|
2412
2419
|
scitex/stats/run_all.sh,sha256=Q_fw3q_10mlQAUBRggSNrl0gILFvTFUlFztH2Aicfhs,1381
|
|
2413
2420
|
scitex/stats/_mcp/__init__.py,sha256=FJRAr90vUCg4PJ8Sv-WzsKuM7aY93m6UR87fhk843MU,73
|
|
2414
2421
|
scitex/stats/_mcp/handlers.py,sha256=zvSep5DdTMMRmFFhSDBy-PGeoGhq7e4QAW_7V2v3_dQ,874
|
|
@@ -2500,7 +2507,7 @@ scitex/template/clone_pip_project.py,sha256=cEQkbyD8x-0iVDrL3iCIH2z5e_7mKIXe-uPQ
|
|
|
2500
2507
|
scitex/template/clone_research.py,sha256=cWwW6vQp03u19mDlit-P6yMHF30IW6DQf3xXVdd-D1M,3073
|
|
2501
2508
|
scitex/template/clone_singularity.py,sha256=CYMjaUU1Bf58tKtU5tlTKgjd1EphaZvmMpqmhIyPtyw,3103
|
|
2502
2509
|
scitex/template/clone_writer_directory.py,sha256=ibAlEkMRLTBYmxgg_LFMtFr3uLTMFhTyYyhoDkwv6xE,3058
|
|
2503
|
-
scitex/template/mcp_server.py,sha256=
|
|
2510
|
+
scitex/template/mcp_server.py,sha256=aqCOdzFOeEBjA4RPlXrPXY9O9nix0fOItENQNwdYv5Y,6096
|
|
2504
2511
|
scitex/template/_mcp/__init__.py,sha256=FJRAr90vUCg4PJ8Sv-WzsKuM7aY93m6UR87fhk843MU,73
|
|
2505
2512
|
scitex/template/_mcp/handlers.py,sha256=VqOt8Rjb2d6z0Fhlfui2KgX-coQS-eUZkBZ7z6caOjY,9073
|
|
2506
2513
|
scitex/template/_mcp/tool_schemas.py,sha256=dAuqmTrdOA8DJOtzRvhvvlLNBLLivOJW-UXiTldzt7Y,6580
|
|
@@ -2533,7 +2540,7 @@ scitex/types/__init__.py,sha256=VdI0QzASeZMy_mUCtSfNO8Ngn9PYQ-oGeweo9NfRmrg,301
|
|
|
2533
2540
|
scitex/types/_is_listed_X.py,sha256=4lSFyuqKaZytqDGuyGqUJOqkrFo0Ymql3kfWwIva5L0,1867
|
|
2534
2541
|
scitex/ui/__init__.py,sha256=YTPRgC-eLHgB1Saxml_S5CIRFR0mVTld5f1ZIe8EemI,4882
|
|
2535
2542
|
scitex/ui/_backends.py,sha256=qChJsy_2WUGfXbPd_-CyYf2kOusr4qsEFCT-rduyJ30,741
|
|
2536
|
-
scitex/ui/mcp_server.py,sha256=
|
|
2543
|
+
scitex/ui/mcp_server.py,sha256=HxTJIhsOLGM7ccuH4MvC94ueoZTVdVOv7Jw-HhRiNAs,5166
|
|
2537
2544
|
scitex/ui/_backends/__init__.py,sha256=n3oNFT7NtXrPPORJ0bYk89d-SkZdBH4-1eMR0vZ-buI,1756
|
|
2538
2545
|
scitex/ui/_backends/_audio.py,sha256=3Qq2amkGgmkqqTcEWX82aL3iLrOcY1n8zUYgRH7mzK8,2418
|
|
2539
2546
|
scitex/ui/_backends/_config.py,sha256=Qqzw8U7Ej2kkI4wmVjmixNc7KuIym5klalGiv4TxJUs,8427
|
|
@@ -2612,8 +2619,8 @@ scitex/writer/utils/_parse_latex_logs.py,sha256=K05kCJClG86-RovXG9I5e3wHP0mEGiZl
|
|
|
2612
2619
|
scitex/writer/utils/_parse_script_args.py,sha256=Fkx1ze_jlKYIpviLuT7z0hpqE4cdtXXA_7sK3sKpVs4,4593
|
|
2613
2620
|
scitex/writer/utils/_verify_tree_structure.py,sha256=Uk9NUSleR9aMHpAgUGsPZMk4a75l35EkZhQYKIfolVY,5724
|
|
2614
2621
|
scitex/writer/utils/_watch.py,sha256=nYzPQ-iPAOzbwzAPBtSrrVBLLPMl08e0qxw0mtv0Y8I,2577
|
|
2615
|
-
scitex-2.15.
|
|
2616
|
-
scitex-2.15.
|
|
2617
|
-
scitex-2.15.
|
|
2618
|
-
scitex-2.15.
|
|
2619
|
-
scitex-2.15.
|
|
2622
|
+
scitex-2.15.4.dist-info/METADATA,sha256=YhHg4lxfd6DXKl_tGIfOp6ZAXs6HkBzAo3K61emqz7U,25007
|
|
2623
|
+
scitex-2.15.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
2624
|
+
scitex-2.15.4.dist-info/entry_points.txt,sha256=ZtDrHnPNMnsSmAnQoCHNmk0xKotNyR2X_YFDDteupW8,497
|
|
2625
|
+
scitex-2.15.4.dist-info/licenses/LICENSE,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
|
|
2626
|
+
scitex-2.15.4.dist-info/RECORD,,
|
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# Timestamp: 2026-01-24
|
|
3
|
-
# File: src/scitex/scholar/crossref_scitex.py
|
|
4
|
-
"""CrossRef-SciTeX: Local CrossRef database integration for scitex.scholar.
|
|
5
|
-
|
|
6
|
-
This module provides access to the local CrossRef database (167M+ papers)
|
|
7
|
-
through the crossref-local package. Branded as "crossref-scitex" to distinguish
|
|
8
|
-
from the official CrossRef API. Supports both direct database access and HTTP
|
|
9
|
-
API mode for remote servers.
|
|
10
|
-
|
|
11
|
-
Quick Start
|
|
12
|
-
-----------
|
|
13
|
-
|
|
14
|
-
Search for papers:
|
|
15
|
-
>>> from scitex.scholar import crossref_scitex
|
|
16
|
-
>>> results = crossref_scitex.search("hippocampal sharp wave ripples")
|
|
17
|
-
>>> print(results.total, "papers found")
|
|
18
|
-
|
|
19
|
-
Get paper by DOI:
|
|
20
|
-
>>> work = crossref_scitex.get("10.1126/science.aax0758")
|
|
21
|
-
>>> print(work.title)
|
|
22
|
-
|
|
23
|
-
Configuration
|
|
24
|
-
-------------
|
|
25
|
-
|
|
26
|
-
The mode is automatically detected:
|
|
27
|
-
- If CROSSREF_LOCAL_DB is set, uses direct database access
|
|
28
|
-
- If CROSSREF_LOCAL_API_URL is set, uses HTTP API
|
|
29
|
-
- Default: tries localhost:31291 (SciTeX port scheme)
|
|
30
|
-
|
|
31
|
-
Environment variables (SCITEX_SCHOLAR_CROSSREF_* takes priority):
|
|
32
|
-
SCITEX_SCHOLAR_CROSSREF_DB: Path to local database
|
|
33
|
-
SCITEX_SCHOLAR_CROSSREF_MODE: 'db' or 'http'
|
|
34
|
-
CROSSREF_LOCAL_DB: Path to local database (fallback)
|
|
35
|
-
CROSSREF_LOCAL_API_URL: HTTP API URL (fallback)
|
|
36
|
-
|
|
37
|
-
SSH tunnel for remote database:
|
|
38
|
-
$ ssh -L 31291:127.0.0.1:31291 your-server
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
from __future__ import annotations
|
|
42
|
-
|
|
43
|
-
from typing import TYPE_CHECKING, Any, Optional
|
|
44
|
-
|
|
45
|
-
# Set environment variables for crossref-local configuration
|
|
46
|
-
# SCITEX_SCHOLAR_CROSSREF_* vars take priority in crossref-local's config.py
|
|
47
|
-
|
|
48
|
-
if TYPE_CHECKING:
|
|
49
|
-
from crossref_local import SearchResult, Work
|
|
50
|
-
from crossref_local.citations import CitationNetwork
|
|
51
|
-
|
|
52
|
-
__all__ = [
|
|
53
|
-
# Core search/retrieval
|
|
54
|
-
"search",
|
|
55
|
-
"count",
|
|
56
|
-
"get",
|
|
57
|
-
"get_many",
|
|
58
|
-
"exists",
|
|
59
|
-
# Enrichment
|
|
60
|
-
"enrich",
|
|
61
|
-
"enrich_dois",
|
|
62
|
-
# Configuration
|
|
63
|
-
"configure",
|
|
64
|
-
"configure_http",
|
|
65
|
-
"get_mode",
|
|
66
|
-
"info",
|
|
67
|
-
"is_available",
|
|
68
|
-
# Citation functions
|
|
69
|
-
"get_citing",
|
|
70
|
-
"get_cited",
|
|
71
|
-
"get_citation_count",
|
|
72
|
-
# Classes (re-exported)
|
|
73
|
-
"Work",
|
|
74
|
-
"SearchResult",
|
|
75
|
-
"CitationNetwork",
|
|
76
|
-
# Async API
|
|
77
|
-
"aio",
|
|
78
|
-
# Cache module
|
|
79
|
-
"cache",
|
|
80
|
-
]
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def _ensure_crossref_local():
|
|
84
|
-
"""Ensure crossref-local is available."""
|
|
85
|
-
try:
|
|
86
|
-
import crossref_local
|
|
87
|
-
|
|
88
|
-
return crossref_local
|
|
89
|
-
except ImportError as e:
|
|
90
|
-
raise ImportError(
|
|
91
|
-
"crossref-local not installed. Install with: pip install crossref-local"
|
|
92
|
-
) from e
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def is_available() -> bool:
|
|
96
|
-
"""Check if crossref-local is available and configured.
|
|
97
|
-
|
|
98
|
-
Returns
|
|
99
|
-
-------
|
|
100
|
-
True if crossref-local can be used (either DB or HTTP mode)
|
|
101
|
-
"""
|
|
102
|
-
try:
|
|
103
|
-
crl = _ensure_crossref_local()
|
|
104
|
-
info_result = crl.info()
|
|
105
|
-
return info_result.get("status") == "ok"
|
|
106
|
-
except Exception:
|
|
107
|
-
return False
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
# =============================================================================
|
|
111
|
-
# Core Search/Retrieval Functions (delegated to crossref-local)
|
|
112
|
-
# =============================================================================
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def search(
|
|
116
|
-
query: str,
|
|
117
|
-
limit: int = 20,
|
|
118
|
-
offset: int = 0,
|
|
119
|
-
**kwargs: Any,
|
|
120
|
-
) -> SearchResult:
|
|
121
|
-
"""Search for papers in the CrossRef database.
|
|
122
|
-
|
|
123
|
-
Args:
|
|
124
|
-
query: Search query string (full-text search)
|
|
125
|
-
limit: Maximum number of results (default: 20)
|
|
126
|
-
offset: Number of results to skip for pagination
|
|
127
|
-
**kwargs: Additional arguments passed to crossref-local
|
|
128
|
-
|
|
129
|
-
Returns
|
|
130
|
-
-------
|
|
131
|
-
SearchResult containing matching papers
|
|
132
|
-
|
|
133
|
-
Examples
|
|
134
|
-
--------
|
|
135
|
-
>>> from scitex.scholar import crossref
|
|
136
|
-
>>> results = crossref.search("deep learning")
|
|
137
|
-
>>> for work in results:
|
|
138
|
-
... print(work.title)
|
|
139
|
-
"""
|
|
140
|
-
crl = _ensure_crossref_local()
|
|
141
|
-
return crl.search(query, limit=limit, offset=offset, **kwargs)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def count(query: str) -> int:
|
|
145
|
-
"""Count papers matching a search query.
|
|
146
|
-
|
|
147
|
-
Args:
|
|
148
|
-
query: Search query string
|
|
149
|
-
|
|
150
|
-
Returns
|
|
151
|
-
-------
|
|
152
|
-
Number of matching papers
|
|
153
|
-
"""
|
|
154
|
-
crl = _ensure_crossref_local()
|
|
155
|
-
return crl.count(query)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
def get(doi: str) -> Optional[Work]:
|
|
159
|
-
"""Get a paper by DOI.
|
|
160
|
-
|
|
161
|
-
Args:
|
|
162
|
-
doi: DOI of the paper (e.g., "10.1126/science.aax0758")
|
|
163
|
-
|
|
164
|
-
Returns
|
|
165
|
-
-------
|
|
166
|
-
Work object if found, None otherwise
|
|
167
|
-
|
|
168
|
-
Examples
|
|
169
|
-
--------
|
|
170
|
-
>>> work = crossref.get("10.1038/nature12373")
|
|
171
|
-
>>> if work:
|
|
172
|
-
... print(work.title, work.year)
|
|
173
|
-
"""
|
|
174
|
-
crl = _ensure_crossref_local()
|
|
175
|
-
return crl.get(doi)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def get_many(dois: list[str]) -> list[Work]:
|
|
179
|
-
"""Get multiple papers by DOI.
|
|
180
|
-
|
|
181
|
-
Args:
|
|
182
|
-
dois: List of DOIs
|
|
183
|
-
|
|
184
|
-
Returns
|
|
185
|
-
-------
|
|
186
|
-
List of Work objects (None for DOIs not found)
|
|
187
|
-
"""
|
|
188
|
-
crl = _ensure_crossref_local()
|
|
189
|
-
return crl.get_many(dois)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def exists(doi: str) -> bool:
|
|
193
|
-
"""Check if a DOI exists in the database.
|
|
194
|
-
|
|
195
|
-
Args:
|
|
196
|
-
doi: DOI to check
|
|
197
|
-
|
|
198
|
-
Returns
|
|
199
|
-
-------
|
|
200
|
-
True if DOI exists
|
|
201
|
-
"""
|
|
202
|
-
crl = _ensure_crossref_local()
|
|
203
|
-
return crl.exists(doi)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
# =============================================================================
|
|
207
|
-
# Enrichment Functions
|
|
208
|
-
# =============================================================================
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
def enrich(results: SearchResult) -> SearchResult:
|
|
212
|
-
"""Enrich search results with citation data.
|
|
213
|
-
|
|
214
|
-
Args:
|
|
215
|
-
results: SearchResult to enrich
|
|
216
|
-
|
|
217
|
-
Returns
|
|
218
|
-
-------
|
|
219
|
-
Enriched SearchResult with citation counts and references
|
|
220
|
-
"""
|
|
221
|
-
crl = _ensure_crossref_local()
|
|
222
|
-
return crl.enrich(results)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
def enrich_dois(dois: list[str]) -> list[Work]:
|
|
226
|
-
"""Get and enrich papers by DOI with citation data.
|
|
227
|
-
|
|
228
|
-
Args:
|
|
229
|
-
dois: List of DOIs to enrich
|
|
230
|
-
|
|
231
|
-
Returns
|
|
232
|
-
-------
|
|
233
|
-
List of enriched Work objects
|
|
234
|
-
"""
|
|
235
|
-
crl = _ensure_crossref_local()
|
|
236
|
-
return crl.enrich_dois(dois)
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
# =============================================================================
|
|
240
|
-
# Citation Functions
|
|
241
|
-
# =============================================================================
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
def get_citing(doi: str) -> list[str]:
|
|
245
|
-
"""Get DOIs of papers that cite this paper.
|
|
246
|
-
|
|
247
|
-
Args:
|
|
248
|
-
doi: DOI of the paper
|
|
249
|
-
|
|
250
|
-
Returns
|
|
251
|
-
-------
|
|
252
|
-
List of DOIs that cite this paper
|
|
253
|
-
"""
|
|
254
|
-
crl = _ensure_crossref_local()
|
|
255
|
-
return crl.get_citing(doi)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
def get_cited(doi: str) -> list[str]:
|
|
259
|
-
"""Get DOIs of papers cited by this paper.
|
|
260
|
-
|
|
261
|
-
Args:
|
|
262
|
-
doi: DOI of the paper
|
|
263
|
-
|
|
264
|
-
Returns
|
|
265
|
-
-------
|
|
266
|
-
List of DOIs cited by this paper (references)
|
|
267
|
-
"""
|
|
268
|
-
crl = _ensure_crossref_local()
|
|
269
|
-
return crl.get_cited(doi)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
def get_citation_count(doi: str) -> int:
|
|
273
|
-
"""Get the citation count for a paper.
|
|
274
|
-
|
|
275
|
-
Args:
|
|
276
|
-
doi: DOI of the paper
|
|
277
|
-
|
|
278
|
-
Returns
|
|
279
|
-
-------
|
|
280
|
-
Number of citations
|
|
281
|
-
"""
|
|
282
|
-
crl = _ensure_crossref_local()
|
|
283
|
-
return crl.get_citation_count(doi)
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
# =============================================================================
|
|
287
|
-
# Configuration Functions
|
|
288
|
-
# =============================================================================
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
def configure(db_path: str) -> None:
|
|
292
|
-
"""Configure direct database access mode.
|
|
293
|
-
|
|
294
|
-
Args:
|
|
295
|
-
db_path: Path to the crossref.db file
|
|
296
|
-
"""
|
|
297
|
-
crl = _ensure_crossref_local()
|
|
298
|
-
crl.configure(db_path)
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
def configure_http(api_url: Optional[str] = None) -> None:
|
|
302
|
-
"""Configure HTTP API mode.
|
|
303
|
-
|
|
304
|
-
Args:
|
|
305
|
-
api_url: API URL (default: http://localhost:31291)
|
|
306
|
-
|
|
307
|
-
Example:
|
|
308
|
-
>>> # After setting up SSH tunnel: ssh -L 31291:127.0.0.1:31291 server
|
|
309
|
-
>>> crossref.configure_http()
|
|
310
|
-
"""
|
|
311
|
-
crl = _ensure_crossref_local()
|
|
312
|
-
crl.configure_http(api_url)
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
def get_mode() -> str:
|
|
316
|
-
"""Get the current operating mode.
|
|
317
|
-
|
|
318
|
-
Returns
|
|
319
|
-
-------
|
|
320
|
-
"db" for direct database access, "http" for API mode
|
|
321
|
-
"""
|
|
322
|
-
crl = _ensure_crossref_local()
|
|
323
|
-
return crl.get_mode()
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
def info() -> dict:
|
|
327
|
-
"""Get information about the crossref-local configuration.
|
|
328
|
-
|
|
329
|
-
Returns
|
|
330
|
-
-------
|
|
331
|
-
Dict with status, mode, version, database stats, etc.
|
|
332
|
-
"""
|
|
333
|
-
crl = _ensure_crossref_local()
|
|
334
|
-
return crl.info()
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
# =============================================================================
|
|
338
|
-
# Re-exported Classes and Modules
|
|
339
|
-
# =============================================================================
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
def __getattr__(name: str):
|
|
343
|
-
"""Lazy import for classes and modules."""
|
|
344
|
-
if name == "Work":
|
|
345
|
-
from crossref_local import Work
|
|
346
|
-
|
|
347
|
-
return Work
|
|
348
|
-
elif name == "SearchResult":
|
|
349
|
-
from crossref_local import SearchResult
|
|
350
|
-
|
|
351
|
-
return SearchResult
|
|
352
|
-
elif name == "CitationNetwork":
|
|
353
|
-
from crossref_local.citations import CitationNetwork
|
|
354
|
-
|
|
355
|
-
return CitationNetwork
|
|
356
|
-
elif name == "aio":
|
|
357
|
-
from crossref_local import aio
|
|
358
|
-
|
|
359
|
-
return aio
|
|
360
|
-
elif name == "cache":
|
|
361
|
-
from crossref_local import cache
|
|
362
|
-
|
|
363
|
-
return cache
|
|
364
|
-
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
# EOF
|
|
File without changes
|
|
File without changes
|
|
File without changes
|