-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from metaodi/develop
Release 1.0.0
- Loading branch information
Showing
20 changed files
with
4,971 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
.DEFAULT_GOAL := help | ||
.PHONY: coverage deps help lint test | ||
|
||
coverage: ## Run tests with coverage | ||
python -m coverage erase | ||
python -m coverage run --include=sruthi/* -m pytest -ra | ||
python -m coverage report -m | ||
|
||
deps: ## Install dependencies | ||
python -m pip install --upgrade pip | ||
python -m pip install -r requirements.txt | ||
python -m pip install -r test-requirements.txt | ||
|
||
lint: ## Linting of source code | ||
python -m flake8 --statistics --show-source . | ||
|
||
test: ## Run tests | ||
python -m pytest --cov=sruthi tests/ | ||
|
||
help: SHELL := /bin/bash | ||
help: ## Show help message | ||
@IFS=$$'\n' ; \ | ||
help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##/:/'`); \ | ||
printf "%s\n\n" "Usage: make [task]"; \ | ||
printf "%-20s %s\n" "task" "help" ; \ | ||
printf "%-20s %s\n" "------" "----" ; \ | ||
for help_line in $${help_lines[@]}; do \ | ||
IFS=$$':' ; \ | ||
help_split=($$help_line) ; \ | ||
help_command=`echo $${help_split[0]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \ | ||
help_info=`echo $${help_split[2]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \ | ||
printf '\033[36m'; \ | ||
printf "%-20s %s" $$help_command ; \ | ||
printf '\033[0m'; \ | ||
printf "%s\n" $$help_info; \ | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,21 @@ | ||
[![PyPI Version](https://img.shields.io/pypi/v/sruthi)](https://pypi.org/project/sruthi/) | ||
[![Tests + Linting Python](https://github.com/metaodi/sruthi/actions/workflows/lint_python.yml/badge.svg)](https://github.com/metaodi/sruthi/actions/workflows/lint_python.yml) | ||
|
||
# sruthi | ||
|
||
**sru**thi is a client for python to make [SRU requests (Search/Retrieve via URL)](http://www.loc.gov/standards/sru/). | ||
|
||
Currently only SRU 1.2 is supported. | ||
Currently only **SRU 1.1 and 1.2** is supported. | ||
|
||
## Table of Contents | ||
|
||
* [Installation](#installation) | ||
* [Usage](#usage) | ||
* [`searchretrieve` operation](#searchretrieve-operation) | ||
* [`explain` operation](#explain-operation) | ||
* [Request for SRU 1.1](#request-for-sru-11) | ||
* [Schemas](#schemas) | ||
* [Development](#development) | ||
* [Release](#release) | ||
|
||
## Installation | ||
|
@@ -28,30 +33,38 @@ See the [`examples` directory](https://github.com/metaodi/sruthi/tree/master/exa | |
### `searchretrieve` operation | ||
|
||
```python | ||
import sruthi | ||
|
||
records = sruthi.searchretrieve('https://suche.staatsarchiv.djiktzh.ch/SRU/', query='Zurich') | ||
|
||
for record in records: | ||
# print fields from schema | ||
print(record['reference']) | ||
print(record['title']) | ||
print(record['date']) | ||
print(record['extra']['link']) # extra record data is available at the 'extra' key | ||
``` | ||
|
||
```python | ||
# you can get more information at each step | ||
import sruthi | ||
|
||
# note: records is an iterator | ||
records = sruthi.searchretrieve('https://suche.staatsarchiv.djiktzh.ch/SRU/', query='Human') | ||
print(records.sru_version) | ||
print(records.count) | ||
|
||
for record in records: | ||
print(record) | ||
print(record['schema']) | ||
>>> import sruthi | ||
>>> records = sruthi.searchretrieve('https://suche.staatsarchiv.djiktzh.ch/SRU/', query='Brettspiel') | ||
>>> print(records) | ||
SearchRetrieveResponse(sru_version='1.2',count=500,next_start_record=11) | ||
>>> print(records.count) | ||
4 | ||
>>> print(record[0]) | ||
{'schema': 'isad', 'reference': 'PAT 2, 54 d, Nr. 253492', 'title': 'Schlumberger, Jean, Zürich: Brettspiel', 'date': '08.03.1946', 'descriptionlevel': 'Dossier', 'extent': None, 'creator': None, 'extra': {'score': '0.4', 'link': 'https://suche.staatsarchiv.djiktzh.ch/detail.aspx?Id=1114641', 'beginDateISO': '1946-03-08', 'beginApprox': '0', 'endDateISO': '1946-03-08', 'endApprox': '0', 'hasDigitizedItems': '0'}} | ||
>>> | ||
>>> for record in records: | ||
... # print fields from schema | ||
... print(record['reference']) | ||
... print(record['title']) | ||
... print(record['date']) | ||
... print(record['extra']['link']) # extra record data is available at the 'extra' key | ||
PAT 2, 54 d, Nr. 253492 | ||
Schlumberger, Jean, Zürich: Brettspiel | ||
08.03.1946 | ||
https://suche.staatsarchiv.djiktzh.ch/detail.aspx?Id=1114641 | ||
PAT 2, 54 d, Nr. 246025 | ||
Frei, K. H., Weisslingen: Brettspiel | ||
26.10.1945 | ||
https://suche.staatsarchiv.djiktzh.ch/detail.aspx?Id=1114639 | ||
DS 107.2.37 | ||
UZH Magazin | ||
Die Wissenschaftszeitschrift | ||
2019 | ||
https://suche.staatsarchiv.djiktzh.ch/detail.aspx?Id=4612939 | ||
G I 1, Nr. 34 | ||
Verordnung der Stadt Zürich betreffend die Erfüllung von Amtspflichten durch die Chorherren des Grossmünsterstifts | ||
24.09.1485 | ||
https://suche.staatsarchiv.djiktzh.ch/detail.aspx?Id=3796980 | ||
``` | ||
|
||
The return value of `searchretrieve` is iterable, so you can easily loop over it. Or you can use indices to access elements, e.g. `records[1]` to get the second elemenet, or `records[-1]` to get the last one. | ||
|
@@ -65,14 +78,48 @@ for records in records[:5]: | |
|
||
### `explain` operation | ||
|
||
The `explain` operation returns a dict-like object. | ||
The values can either be accessed as keys `info['sru_version']` or as attributes `info.sru_version`. | ||
|
||
```python | ||
import sruthi | ||
>>> import sruthi | ||
>>> info = sruthi.explain('https://suche.staatsarchiv.djiktzh.ch/SRU/') | ||
>>> info | ||
{'sru_version': '1.2', 'server': {'host': 'https://suche.staatsarchiv.djiktzh.ch/Sru', 'port': 80, 'database': 'sru'}, 'database': {'title': 'Staatsarchiv Zürich Online Search', 'description': 'Durchsuchen der Bestände des Staatsarchiv Zürichs.', 'contact': '[email protected]'}, 'index': {'isad': {'title': 'Title', 'reference': 'Reference Code', 'date': 'Date', 'descriptionlevel': 'Level'}}, 'schema': {'isad': {'identifier': 'http://www.expertisecentrumdavid.be/xmlschemas/isad.xsd', 'name': 'isad', 'title': 'ISAD(G)'}}, 'config': {'maximumRecords': 99, 'defaults': {'numberOfRecords': 99}}} | ||
>>> info.server | ||
{'host': 'https://suche.staatsarchiv.djiktzh.ch/Sru', 'port': 80, 'database': 'sru'} | ||
>>> info.database | ||
{'title': 'Staatsarchiv Zürich Online Search', 'description': 'Durchsuchen der Bestände des Staatsarchiv Zürichs.', 'contact': '[email protected]'} | ||
>>> info['index'] | ||
{'isad': {'title': 'Title', 'reference': 'Reference Code', 'date': 'Date', 'descriptionlevel': 'Level'}} | ||
>>> info['schema'] | ||
{'isad': {'identifier': 'http://www.expertisecentrumdavid.be/xmlschemas/isad.xsd', 'name': 'isad', 'title': 'ISAD(G)'}} | ||
``` | ||
|
||
### Request for SRU 1.1 | ||
|
||
By default sruthi uses SRU 1.2 to make requests, but you can specify the SRU version for each call or when you create a new client instance: | ||
|
||
info = sruthi.explain('https://suche.staatsarchiv.djiktzh.ch/SRU/') | ||
print(info.server) | ||
print(info.database) | ||
print(info.index) | ||
print(info.schema) | ||
```python | ||
>>> import sruthi | ||
>>> # create a client | ||
>>> client = sruthi.Client( | ||
... 'https://services.dnb.de/sru/dnb', | ||
... record_schema='oai_dc', | ||
... sru_version='1.1' | ||
>>> ) | ||
>>> records = client.searchretrieve(query="Zurich") | ||
>>> records.count | ||
8985 | ||
>>> # ...or pass the version directly to the call | ||
>>> records = sruthi.searchretrieve( | ||
... 'https://services.dnb.de/sru/dnb', | ||
... query="Zurich", | ||
... record_schema='oai_dc', | ||
... sru_version='1.1' | ||
>>> ) | ||
>>> records.count | ||
8985 | ||
``` | ||
|
||
## Schemas | ||
|
@@ -85,6 +132,13 @@ sruthi has been tested with the following schemas: | |
* [MARCXML: The MARC 21 XML Schema](http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd) (marcxml) | ||
* [ISAD(G): General International Standard Archival Description, Second edition](http://www.expertisecentrumdavid.be/xmlschemas/isad.xsd) (isad) | ||
|
||
## Development | ||
|
||
To contribute to sruthi simply clone this repository and follow the instructions in [CONTRIBUTING.md](/CONTRIBUTING.md). | ||
|
||
This project ha a Makefile with the most common commands. | ||
Type `make help` to get an overview. | ||
|
||
## Release | ||
|
||
To create a new release, follow these steps (please respect [Semantic Versioning](http://semver.org/)): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import sruthi | ||
import sys | ||
|
||
LOC_BASE = 'http://lx2.loc.gov:210/LCDB?' | ||
|
||
|
||
def loc_search(isbn, sru_base): | ||
loc_lcc = None | ||
try: | ||
records = sruthi.searchretrieve(sru_base, query=isbn) | ||
record = records[0] | ||
fields = record.get('datafield', []) | ||
for field in fields: | ||
if field['tag'] != '050': | ||
continue | ||
if len(field.get('subfield', [])) > 0: | ||
loc_lcc = (field['subfield'][0]['text']) | ||
break | ||
except Exception as e: | ||
print("Error: %s" % e, file=sys.stderr) | ||
return None | ||
return loc_lcc | ||
|
||
|
||
isbn = '0062509470' | ||
result = loc_search(isbn, LOC_BASE) | ||
print(f"Tag 050 of ISBN '{isbn}': {result}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import sruthi | ||
from pprint import pprint | ||
|
||
# check supported schemas of server | ||
server_url = 'https://services.dnb.de/sru/dnb' | ||
|
||
# create sruthi client | ||
client = sruthi.Client(server_url, record_schema='oai_dc', sru_version='1.1') | ||
|
||
explain = client.explain() | ||
print(f'SRU version: {explain.sru_version}') | ||
pprint(explain.server) | ||
pprint(explain.config) | ||
pprint(explain.index, depth=1) | ||
pprint(explain.schema, depth=1) | ||
pprint(explain.database) | ||
|
||
|
||
print(20 * '=') | ||
print('=') | ||
print(f"= Record with schema: {client.record_schema}") | ||
print('=') | ||
print(20 * '=') | ||
records = client.searchretrieve( | ||
query='Zurich' | ||
) | ||
print(f'Total records: {records.count}') | ||
pprint(records[0]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,24 @@ | ||
__version__ = '0.1.2' | ||
__all__ = ['client', 'errors', 'response', 'sru', 'xmlparse'] | ||
__version__ = '1.0.0' | ||
__all__ = ['client', 'errors', 'response', 'xmlparse'] | ||
|
||
from .errors import SruthiError, ServerIncompatibleError, SruError, NoMoreRecordsError # noqa | ||
from .errors import SruthiWarning, WrongNamespaceWarning # noqa | ||
from .sru import searchretrieve, explain # noqa | ||
from .client import Client # noqa | ||
|
||
|
||
def searchretrieve(url, query, **kwargs): | ||
search_params = ['query', 'start_record', 'requests_kwargs'] | ||
search_kwargs = {k: v for k, v in kwargs.items() if k in search_params} | ||
search_kwargs['query'] = query | ||
|
||
# assume all others kwargs are for the client | ||
client_kwargs = {k: v for k, v in kwargs.items() if k not in search_params} | ||
client_kwargs['url'] = url | ||
|
||
c = Client(**client_kwargs) | ||
return c.searchretrieve(**search_kwargs) | ||
|
||
|
||
def explain(url, **kwargs): | ||
c = Client(url, **kwargs) | ||
return c.explain() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.