scholarly / providers
Unified PHP SDK for scholarly data providers with adapters, caching, and graph exporter.
Requires
- php: ^8.3
- ext-curl: *
- ext-json: *
- mbsoft31/graph-algorithms: ^1.0
- mbsoft31/graph-core: ^1.0
- psr/cache: ^3.0
- psr/http-client: ^1.0
- psr/http-factory: ^1.0
- psr/http-message: ^1.1
- psr/log: ^3.0
- psr/simple-cache: ^3.0
Requires (Dev)
- fakerphp/faker: ^1.23
- friendsofphp/php-cs-fixer: ^3.50
- mockery/mockery: ^1.6
- nyholm/psr7: ^1.8
- orchestra/testbench: ^9.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-mutate: ^2.0@beta
- pestphp/pest-plugin-type-coverage: ^2.0
- php-http/mock-client: ^1.6
- phpstan/phpstan: ^1.11
- symfony/http-client: ^7.1
- symfony/var-dumper: ^7.1
- vlucas/phpdotenv: ^5.6
README
Unified PHP SDK for scholarly data providers (OpenAlex, Semantic Scholar, Crossref) with a clean contracts layer, robust HTTP client with retries and caching, and a graph exporter powered by mbsoft/graph-core and mbsoft/graph-algorithms.
โจ Features
- ๐ Provider adapters: OpenAlex, Semantic Scholar (S2), Crossref
- ๐งฉ Clean contracts:
Query
,Paginator
,ScholarlyDataSource
- ๐ Resilient HTTP: jittered backoff, retry-after handling, 4xx/5xx classification
- ๐ง Normalization utils: DOI, arXiv, PubMed, ORCID helpers
- ๐๏ธ Caching: PSR-16 and PSR-6 support via a simple
CacheLayer
- ๐ Graph export: citation and collaboration graphs as mbsoft/graph
Graph
- ๐งช Well-tested: Pest test suite, static analysis with PHPStan
- ๐งฐ Framework-friendly: Laravel service provider + facade
๐ Requirements
- PHP 8.3+
- ext-json, ext-curl
- PSR-18 HTTP client and PSR-17 factories (or use Symfony HttpClient + Nyholm PSR-7)
๐ฆ Installation
Install via Composer:
composer require scholarly/providers
Optional (Laravel): package discovery registers Scholarly\Laravel\ScholarlyServiceProvider
. If you disable discovery, register it manually in config/app.php
.
๐ Quick Start
use Scholarly\Contracts\Query; use Scholarly\Factory\AdapterFactory; $factory = AdapterFactory::make(); $openAlex = $factory->adapter('openalex'); // Search works $results = $openAlex->searchWorks(Query::from(['q' => 'graph neural networks', 'limit' => 25])); foreach ($results as $work) { // each $work is array<string, mixed> } // Build a citation graph around a seed set $graph = $factory ->graphExporter($openAlex) ->buildWorkCitationGraph(['openalex:W123'], Query::from(['limit' => 50])); // Export using mbsoft/graph exporters (e.g., Cytoscape JSON) // use Mbsoft\Graph\IO\CytoscapeJsonExporter; // $json = (new CytoscapeJsonExporter())->export($graph);
PSR-first design: inject your own PSR-18 client, PSR-17 factories, PSR-16/PSR-6 cache, or PSR-3 logger via AdapterFactory::make([...], $container)
.
๐ Advanced Features
- Caching: wrap a PSR-16 or PSR-6 store with
CacheLayer
and pass to the exporter to reuse reference/citation lookups between runs. - Retries & backoff: the client honors
Retry-After
headers and applies jittered exponential backoff for transient errors. - Batching & pagination: iterate
Paginator
instances (searchWorks
,listReferences
,listCitations
) or usebatchWorksByIds
. - Identifier helpers:
getWorkByDoi
,getWorkByArxiv
,getWorkByPubmed
,getAuthorByOrcid
normalize inputs and handle not-found paths.
๐งฑ Architecture
src/Contracts
:Query
value object,Paginator
,ScholarlyDataSource
contractsrc/Core
: HTTP client, backoff, cache layer, identity normalizationsrc/Adapters
: OpenAlex, S2, Crossref implementations and paginatorssrc/Exporter
: Graph exporter building mbsoft/graphGraph
instancessrc/Factory
: Adapter factory, configuration objects, Laravel bindingssrc/Laravel
: Service provider and facade
See docs/
for architecture notes, provider specifics, and Laravel usage.
โ๏ธ Configuration
Environment variables (or publish config/scholarly.php
in Laravel):
SCHOLARLY_DEFAULT_ADAPTER
(e.g.,openalex
)SCHOLARLY_CACHE_STORE
(Laravel) or provideCacheInterface
/CacheItemPoolInterface
SCHOLARLY_HTTP_TIMEOUT
(seconds)- Provider settings:
OPENALEX_MAILTO
,S2_API_KEY
,CROSSREF_MAILTO
Graph exporter query flags:
work_ids
(seed set),limit
(page sizes),max_works
(author graph cap),min_collaborations
(edge threshold)
๐งฐ Laravel Usage
use Scholarly\Laravel\Facades\Scholarly; // Resolve the default provider (configured via scholarly.default) $adapter = Scholarly::adapter(); // Export graphs $exporter = Scholarly::graphExporter(); $graph = $exporter->buildWorkCitationGraph(['openalex:W1'], Query::from(['limit' => 50]));
Publish config if needed:
php artisan vendor:publish --tag=scholarly-config
๐งช Testing
Run the test suite:
composer test
With coverage:
composer test-coverage
Static analysis and coding style:
composer stan composer cs-check
Fixtures for provider responses live under tests/Fixtures/
. Guard any live API tests with SCHOLARLY_LIVE_TESTS=1
.
๐ Documentation
- Start here:
docs/index.md
- Quick start guide:
docs/getting-started.md
- Contracts reference:
docs/contracts.md
- Graphs & algorithms:
docs/graph.md
- Adapters:
docs/adapters/openalex.md
,docs/adapters/s2.md
,docs/adapters/crossref.md
- Extending:
docs/extending.md
Hosted docs (GitHub Pages): https://mbsoft31.github.io/scholarly-providers/
๐ฏ Use Cases
- Research discovery and enrichment workflows
- Building literature citation graphs for analysis/visualization
- Author collaboration network analysis
- Data pipelines integrating multiple scholarly sources via one API
๐ค Contributing
Contributions are welcome! Please open an issue or PR.
- Fork the repository
- Create your feature branch (
git checkout -b feat/awesome
) - Ensure quality gates pass (
composer quality
) - Push and open a Pull Request
๐ License
This library is open-sourced software licensed under the MIT license.