From c6f699f11142841dbc0a4cec6e3dd899840e1227 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Mon, 15 Jun 2020 09:33:57 +0200 Subject: [PATCH 01/14] Update README ToC --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index b044761..6df8693 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,10 @@ Currently only SRU 1.2 is supported. * [Installation](#installation) * [Usage](#usage) +** [`searchretrieve` operation](#searchretrieve-operation) +** [`explian` operation](#explain-operation) * [Schemas](#schemas) +* [Release](#release) ## Installation From 82b7f29fd6e19cc283a2ba132deb29c60e79d947 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Wed, 9 Sep 2020 11:41:25 +0200 Subject: [PATCH 02/14] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6df8693..b40a00c 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ Currently only SRU 1.2 is supported. * [Installation](#installation) * [Usage](#usage) -** [`searchretrieve` operation](#searchretrieve-operation) -** [`explian` operation](#explain-operation) + * [`searchretrieve` operation](#searchretrieve-operation) + * [`explain` operation](#explain-operation) * [Schemas](#schemas) * [Release](#release) From 73be14bed16255af207ba5dd024b7885ea6009f7 Mon Sep 17 00:00:00 2001 From: Emmanuel Di Pretoro Date: Thu, 1 Oct 2020 18:06:00 +0200 Subject: [PATCH 03/14] Fixing a typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b40a00c..942dfbe 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ for record in records: 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. -Even [slicing](https://python-reference.readthedocs.io/en/latest/docs/brackets/slicing.html) is supported, so can can do things like only iterate over the first 5 elements using +Even [slicing](https://python-reference.readthedocs.io/en/latest/docs/brackets/slicing.html) is supported, so you can do things like only iterate over the first 5 elements using ```python for records in records[:5]: From 38472765c4a651bc7748ce32df68774ef652099a Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Fri, 2 Oct 2020 13:35:46 +0200 Subject: [PATCH 04/14] Accept record_schema parameter --- sruthi/client.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sruthi/client.py b/sruthi/client.py index 745182a..4149612 100644 --- a/sruthi/client.py +++ b/sruthi/client.py @@ -7,19 +7,24 @@ class Client(object): - def __init__(self, url=None, maximum_records=10): + def __init__(self, url=None, maximum_records=10, record_schema=None): self.url = url self.maximum_records = maximum_records self.sru_version = '1.2' + self.record_schema = record_schema def searchretrieve(self, query, start_record=1): params = { - 'operation': 'searchretrieve', + 'operation': 'searchRetrieve', 'version': self.sru_version, 'query': query, 'startRecord': start_record, 'maximumRecords': self.maximum_records, } + + if self.record_schema: + params['recordSchema'] = self.record_schema + data_loader = DataLoader(self.url, params) return response.SearchRetrieveResponse(data_loader) @@ -62,10 +67,11 @@ def _get_content(self, url, params): def _check_errors(self, xml): sru = '{http://www.loc.gov/zing/srw/}' + diag = '{http://www.loc.gov/zing/srw/diagnostic/}' diagnostics = self.xmlparser.find( xml, - f'{sru}diagnostics/{sru}diagnostic' + f'{sru}diagnostics/{diag}diagnostic' ) if diagnostics: - error_msg = " ".join([d.find('detail').text for d in diagnostics]) + error_msg = ", ".join([d.text for d in diagnostics]) raise errors.SruError(error_msg) From f9117eb2407bd91be45fd72fdc35cf08410cf39e Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Fri, 2 Oct 2020 13:36:05 +0200 Subject: [PATCH 05/14] Pass through parameters from `sru` module --- sruthi/sru.py | 14 +++++++++++--- tests/sru_test.py | 12 ++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/sruthi/sru.py b/sruthi/sru.py index 9210a02..c22aaa1 100644 --- a/sruthi/sru.py +++ b/sruthi/sru.py @@ -3,9 +3,17 @@ from . import client -def searchretrieve(url, query): - c = client.Client(url) - return c.searchretrieve(query) +def searchretrieve(url, query, **kwargs): + search_params = ['query', 'start_record'] + 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(**client_kwargs) + return c.searchretrieve(**search_kwargs) def explain(url): diff --git a/tests/sru_test.py b/tests/sru_test.py index fe20e01..a1d53da 100644 --- a/tests/sru_test.py +++ b/tests/sru_test.py @@ -7,6 +7,18 @@ def test_searchretrieve(self): r = sruthi.searchretrieve('http://test.com/sru/', 'Test-Query') self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + def test_searchretrieve_with_maximum_records(self): + r = sruthi.searchretrieve('http://test.com/sru/', 'Test-Query', maximum_records=100) + self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + + def test_searchretrieve_with_record_schema(self): + r = sruthi.searchretrieve('http://test.com/sru/', 'Test-Query', record_schema='isad') + self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + + def test_searchretrieve_with_start_record(self): + r = sruthi.searchretrieve('http://test.com/sru/', 'Test-Query', start_record=10) + self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + def test_explain(self): info = sruthi.explain('http://test.com/sru/') self.assertIsInstance(info, sruthi.response.ExplainResponse) From 062047801ae7c616bb5bbf82a807af319cdea855 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Fri, 2 Oct 2020 13:36:41 +0200 Subject: [PATCH 06/14] Create flat response from xml --- sruthi/response.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/sruthi/response.py b/sruthi/response.py index 17c9db9..e54d4ae 100644 --- a/sruthi/response.py +++ b/sruthi/response.py @@ -127,7 +127,7 @@ def _extract_records(self, xml): record_data = self.xmlparser.find(xml_rec, './sru:recordData') extra_data = self.xmlparser.find(xml_rec, './sru:extraRecordData') - for elem in record_data.iter(): + for elem in record_data: record = self._tag_data(record, elem) extra = defaultdict() @@ -142,15 +142,36 @@ def _extract_records(self, xml): new_records.append(record) self.records.extend(new_records) - def _tag_data(self, record, elem): - ns_pattern = re.compile('{.+}') - tag_name = ns_pattern.sub('', elem.tag) + def _tag_data(self, record, elem, child=False): + tag_name = self._remove_namespace(elem) + print(elem) if elem.text and elem.text.strip(): - record[tag_name] = elem.text.strip() + entry = { + 'text': elem.text.strip() + } + entry.update(elem.attrib) + + # get all children (flat) + if not child: + for child in elem.iter(): + child_tag = self._remove_namespace(child) + entry[child_tag] = self._tag_data(entry, child, child=True) + + if tag_name in record and isinstance(record[tag_name], list): + record[tag_name].append(entry) + elif tag_name in record: + record[tag_name] = [record[tag_name]] + else: + record[tag_name] = entry elif len(list(elem)) == 0: # leaf element record[tag_name] = None return record + def _remove_namespace(self, elem): + ns_pattern = re.compile('{.+}') + tag_name = ns_pattern.sub('', elem.tag) + return tag_name + class ExplainResponse(Response): def __repr__(self): From 58da91bb0a76a8f9f33f536a66ef4bd614c66e53 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Fri, 2 Oct 2020 13:37:13 +0200 Subject: [PATCH 07/14] Handle record data - Add example code for schema - Add xmltodict to parse record data - if possible flatten the record data dict - if this is not possible a slim dict from xmltodict is returned - Add xml namespace to ignore list --- examples/isad.py | 24 ++ examples/schemas.py | 26 ++ requirements.txt | 2 + sruthi/response.py | 65 ++-- sruthi/xmlparse.py | 32 ++ tests/client_test.py | 34 +- ...s.xml => test_passing_maximum_records.xml} | 0 tests/fixtures/test_passing_record_schema.xml | 343 ++++++++++++++++++ tests/fixtures/test_passing_start_record.xml | 343 ++++++++++++++++++ ...st_searchretrieve_with_maximum_records.xml | 343 ++++++++++++++++++ ...test_searchretrieve_with_record_schema.xml | 343 ++++++++++++++++++ .../test_searchretrieve_with_start_record.xml | 343 ++++++++++++++++++ 12 files changed, 1863 insertions(+), 35 deletions(-) create mode 100644 examples/isad.py create mode 100644 examples/schemas.py rename tests/fixtures/{test_passing_params.xml => test_passing_maximum_records.xml} (100%) create mode 100644 tests/fixtures/test_passing_record_schema.xml create mode 100644 tests/fixtures/test_passing_start_record.xml create mode 100644 tests/fixtures/test_searchretrieve_with_maximum_records.xml create mode 100644 tests/fixtures/test_searchretrieve_with_record_schema.xml create mode 100644 tests/fixtures/test_searchretrieve_with_start_record.xml diff --git a/examples/isad.py b/examples/isad.py new file mode 100644 index 0000000..a86f316 --- /dev/null +++ b/examples/isad.py @@ -0,0 +1,24 @@ +import sruthi +import yaml +import sys +from pprint import pprint + +# check supported schemas of server +server_url = 'https://suche.staatsarchiv.djiktzh.ch/SRU/' +schema = 'isad' +server = sruthi.explain(server_url) + + +print(20 * '=') +print('=') +print(f"= Record with schema: {schema}") +print('=') +print(20 * '=') +records = sruthi.searchretrieve( + server_url, + query='Zurich', + record_schema=schema +) +pprint(records[0]) + + diff --git a/examples/schemas.py b/examples/schemas.py new file mode 100644 index 0000000..681753d --- /dev/null +++ b/examples/schemas.py @@ -0,0 +1,26 @@ +import sruthi +import yaml +import sys +from pprint import pprint + +# check supported schemas of server +server = sruthi.explain('http://lx2.loc.gov:210/LCDB?') + +print(f"Supported schemas: {', '.join(server.schema.keys())}") + + +for schema in server.schema.keys(): + print(20 * '=') + print('=') + print(f"= Record with schema: {schema}") + print('=') + print(20 * '=') + records = sruthi.searchretrieve( + 'http://lx2.loc.gov:210/LCDB?', + query="human", + record_schema=schema + ) + pprint(records[0]) + #print(yaml.dump(records[0], allow_unicode=True, default_flow_style=False)) + print('') + print('') diff --git a/requirements.txt b/requirements.txt index df7eaf0..d5b78bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ requests defusedxml +xmltodict +flatten-dict diff --git a/sruthi/response.py b/sruthi/response.py index e54d4ae..a5b119c 100644 --- a/sruthi/response.py +++ b/sruthi/response.py @@ -3,6 +3,7 @@ from collections import defaultdict import re import warnings +from flatten_dict import flatten from . import xmlparse from . import errors @@ -127,45 +128,41 @@ def _extract_records(self, xml): record_data = self.xmlparser.find(xml_rec, './sru:recordData') extra_data = self.xmlparser.find(xml_rec, './sru:extraRecordData') - for elem in record_data: - record = self._tag_data(record, elem) - - extra = defaultdict() - for elem in extra_data.iter(): - extra = self._tag_data(extra, elem) - record['extra'] = dict(extra) - - record.pop('recordData', None) - record.pop('extraRecordData', None) + record.update(self._tag_data(record_data, 'sru:recordData') or {}) + record['extra'] = self._tag_data(extra_data, 'sru:extraRecordData') record = dict(record) new_records.append(record) self.records.extend(new_records) - def _tag_data(self, record, elem, child=False): - tag_name = self._remove_namespace(elem) - print(elem) - if elem.text and elem.text.strip(): - entry = { - 'text': elem.text.strip() - } - entry.update(elem.attrib) - - # get all children (flat) - if not child: - for child in elem.iter(): - child_tag = self._remove_namespace(child) - entry[child_tag] = self._tag_data(entry, child, child=True) - - if tag_name in record and isinstance(record[tag_name], list): - record[tag_name].append(entry) - elif tag_name in record: - record[tag_name] = [record[tag_name]] - else: - record[tag_name] = entry - elif len(list(elem)) == 0: # leaf element - record[tag_name] = None - return record + def _tag_data(self, elem, parent): + if not elem: + return None + + record_data = self.xmlparser.todict(elem, xml_attribs=True).get(parent) + if not record_data: + return None + + # check if there is only one element on the top level + keys = list(record_data.keys()) + if len(record_data) == 1 and len(keys) > 0 and len(record_data[keys[0]]) > 0: + record_data = record_data[keys[0]] + + record_data.pop('schemaLocation', None) + record_data.pop('xmlns', None) + + def leaf_reducer(k1, k2): + # only use key of leaf element + return k2 + + try: + record_data = flatten(record_data, reducer=leaf_reducer) + except ValueError: + # if the keys of the leaf elements are not unique + # the dict will not be flattened + pass + + return record_data def _remove_namespace(self, elem): ns_pattern = re.compile('{.+}') diff --git a/sruthi/xmlparse.py b/sruthi/xmlparse.py index b5819dd..988ceef 100644 --- a/sruthi/xmlparse.py +++ b/sruthi/xmlparse.py @@ -1,5 +1,7 @@ import re +from xml.etree.ElementTree import Element import defusedxml.ElementTree as etree +import xmltodict from . import errors @@ -25,6 +27,20 @@ def __init__(self): 'ap': 'http://www.archivportal.ch/srw/extension/', 'zr': 'http://explain.z3950.org/dtd/2.1/', } + self.dict_namespaces = { + 'http://www.loc.gov/zing/srw/': 'sru', + 'http://explain.z3950.org/dtd/2.1/': 'zr', + 'info:srw/extension/2/relevancy-1.0': None, + 'http://www.archivportal.ch/srw/extension/': None, + 'http://www.loc.gov/MARC21/slim': None, + 'http://www.loc.gov/mods/v3': None, + 'http://www.loc.gov/standards/mods/v3/mods-3-6.xsd': None, + 'http://www.loc.gov/standards/mods/v3/mods-3-6.xsd': None, + 'http://purl.org/dc/elements/1.1/': None, + 'http://www.expertisecentrumdavid.be/xmlschemas/isad.xsd': None, + 'http://www.w3.org/2001/XMLSchema-instance': None, + 'http://www.w3.org/XML/1998/namespace': None, + } def parse(self, content): try: @@ -50,6 +66,22 @@ def findall(self, xml, path): def tostring(self, xml): return etree.tostring(xml) + def todict(self, xml, **kwargs): + if isinstance(xml, XMLNone): + return None + if isinstance(xml, Element): + xml = self.tostring(xml) + + dict_args = { + 'dict_constructor': dict, + 'process_namespaces': True, + 'namespaces': self.dict_namespaces, + 'attr_prefix': '', + 'cdata_key': 'text', + } + dict_args.update(kwargs) + return dict(xmltodict.parse(xml, **dict_args)) + def namespace(self, element): m = re.match(r'\{(.*)\}', element.tag) return m.group(1) if m else '' diff --git a/tests/client_test.py b/tests/client_test.py index 6aa05ff..6c51b2c 100644 --- a/tests/client_test.py +++ b/tests/client_test.py @@ -110,7 +110,7 @@ def test_explain(self): self.assertEqual(config['my-test-config'], 'test123') self.assertEqual(config['defaults']['numberOfRecords'], 99) - def test_passing_params(self): + def test_passing_maximum_records(self): client = Client('http://my-param.com/sru', maximum_records=111) self.assertEqual(client.maximum_records, 111) @@ -125,3 +125,35 @@ def test_passing_params(self): 'maximumRecords': 111, } ) + + def test_passing_record_schema(self): + client = Client('http://my-param.com/sru', record_schema='dc') + self.assertEqual(client.record_schema, 'dc') + + client.searchretrieve('test-query') + self.session_mock.return_value.get.assert_called_once_with( + 'http://my-param.com/sru', + params={ + 'operation': 'searchretrieve', + 'version': '1.2', + 'query': 'test-query', + 'startRecord': 1, + 'recordSchema': 'dc', + 'maximumRecords': 10, + } + ) + + def test_passing_start_record(self): + client = Client('http://my-param.com/sru') + + client.searchretrieve('test-query', start_record=10) + self.session_mock.return_value.get.assert_called_once_with( + 'http://my-param.com/sru', + params={ + 'operation': 'searchretrieve', + 'version': '1.2', + 'query': 'test-query', + 'startRecord': 10, + 'maximumRecords': 10, + } + ) diff --git a/tests/fixtures/test_passing_params.xml b/tests/fixtures/test_passing_maximum_records.xml similarity index 100% rename from tests/fixtures/test_passing_params.xml rename to tests/fixtures/test_passing_maximum_records.xml diff --git a/tests/fixtures/test_passing_record_schema.xml b/tests/fixtures/test_passing_record_schema.xml new file mode 100644 index 0000000..e7c2509 --- /dev/null +++ b/tests/fixtures/test_passing_record_schema.xml @@ -0,0 +1,343 @@ + + + 1.2 + 12 + + + isad + xml + + + + VII.335.:2.34.8. + Podium "Frauen und Politik" beim Jubiläumsanlass "Frauenrechte-Menschenrechte" des Bundes Schweizerischer Frauenorganisationen BSF zu 150 Jahre Bundesstaat, 50 Jahre UNO-Menschenrechtserklärung und 27 Jahre politische Gleichberechtigung im Nationalratssaal in Bern vom 4. April 1998 + 1998 + Dossier + + + + + + + + 1 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=410130 + 1998-01-01 + 0 + 1998-12-31 + 0 + 0 + + + + isad + xml + + + + VII.424.:3.2.4.8. + Menschenrechte, Matinee der Schauspielunion, 18.04. (vor) 1964 + s. d. (sine dato) + Dossier + + + + + + + + 2 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=495785 + 0001-01-01 + 0 + 9999-12-31 + 0 + 0 + + + + isad + xml + + + + V.E.c.63. + Stadtpolizei, Kriminalkommissariat KK III. Staatsschutzakten Registratur 1 und 2 + 1920 - 1990 + Bestand + + + + + + + + 3 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=9514 + 1920-01-01 + 0 + 1990-12-31 + 0 + 1 + + + + isad + xml + + + + V.E.c.73. + Stadtpolizei, Bewilligungen. Akten + 1906 - 2014 + Bestand + + + + + + + + 4 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=207460 + 1906-01-01 + 0 + 2014-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.64. + Präsidialabteilung. Akten + 1955 - 1995 + Bestand + + + + + + + + 5 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8336 + 1955-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.900.:3.2. + Stadthaus. Drucksachen + 1951 - 2019 + Bestand + + + + + + + + 6 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8362 + 1951-01-01 + 0 + 2019-12-31 + 0 + 1 + + + + isad + xml + + + + VII.12. + Aktientheater, Stadttheater, Opernhaus Zürich AG. Theaterarchiv + 1830 - 1995 + Bestand + + + + + + + + 7 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11494 + 1830-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + VII.335. + Emilie Lieberherr (1924-2011), Stadträtin. Nachlass + approx. 1900 - 2004 + Bestand + + + + + + + + 8 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11736 + 1900-01-01 + 1 + 2004-12-31 + 0 + 1 + + + + isad + xml + + + + VII.424. + Dr. Peter Löffler (1926-2015), Dramaturg, Regisseur, künstlerischer Direktor am Schauspielhaus Zürich (1969/70). Nachlass + 1867 - 2012 + Bestand + + + + + + + + 9 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11835 + 1867-01-01 + 0 + 2012-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.42. + Ausstellungen. Dokumentation + from 1846 + Bestand + + + + + + + + 10 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11389 + 1846-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.105. + Kongresse und Tagungen. Dokumentation + from 1899 + Bestand + + + + + + + + 11 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11243 + 1899-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + VII.103. + Alexander M. Kaiser (1887-1971) alias A. M. Cay, Karikaturist. Nachlass + 1945 - 1967 + Bestand + + + + + + + + 12 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11476 + 1945-01-01 + 0 + 1967-12-31 + 0 + 1 + + + + diff --git a/tests/fixtures/test_passing_start_record.xml b/tests/fixtures/test_passing_start_record.xml new file mode 100644 index 0000000..e7c2509 --- /dev/null +++ b/tests/fixtures/test_passing_start_record.xml @@ -0,0 +1,343 @@ + + + 1.2 + 12 + + + isad + xml + + + + VII.335.:2.34.8. + Podium "Frauen und Politik" beim Jubiläumsanlass "Frauenrechte-Menschenrechte" des Bundes Schweizerischer Frauenorganisationen BSF zu 150 Jahre Bundesstaat, 50 Jahre UNO-Menschenrechtserklärung und 27 Jahre politische Gleichberechtigung im Nationalratssaal in Bern vom 4. April 1998 + 1998 + Dossier + + + + + + + + 1 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=410130 + 1998-01-01 + 0 + 1998-12-31 + 0 + 0 + + + + isad + xml + + + + VII.424.:3.2.4.8. + Menschenrechte, Matinee der Schauspielunion, 18.04. (vor) 1964 + s. d. (sine dato) + Dossier + + + + + + + + 2 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=495785 + 0001-01-01 + 0 + 9999-12-31 + 0 + 0 + + + + isad + xml + + + + V.E.c.63. + Stadtpolizei, Kriminalkommissariat KK III. Staatsschutzakten Registratur 1 und 2 + 1920 - 1990 + Bestand + + + + + + + + 3 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=9514 + 1920-01-01 + 0 + 1990-12-31 + 0 + 1 + + + + isad + xml + + + + V.E.c.73. + Stadtpolizei, Bewilligungen. Akten + 1906 - 2014 + Bestand + + + + + + + + 4 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=207460 + 1906-01-01 + 0 + 2014-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.64. + Präsidialabteilung. Akten + 1955 - 1995 + Bestand + + + + + + + + 5 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8336 + 1955-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.900.:3.2. + Stadthaus. Drucksachen + 1951 - 2019 + Bestand + + + + + + + + 6 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8362 + 1951-01-01 + 0 + 2019-12-31 + 0 + 1 + + + + isad + xml + + + + VII.12. + Aktientheater, Stadttheater, Opernhaus Zürich AG. Theaterarchiv + 1830 - 1995 + Bestand + + + + + + + + 7 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11494 + 1830-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + VII.335. + Emilie Lieberherr (1924-2011), Stadträtin. Nachlass + approx. 1900 - 2004 + Bestand + + + + + + + + 8 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11736 + 1900-01-01 + 1 + 2004-12-31 + 0 + 1 + + + + isad + xml + + + + VII.424. + Dr. Peter Löffler (1926-2015), Dramaturg, Regisseur, künstlerischer Direktor am Schauspielhaus Zürich (1969/70). Nachlass + 1867 - 2012 + Bestand + + + + + + + + 9 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11835 + 1867-01-01 + 0 + 2012-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.42. + Ausstellungen. Dokumentation + from 1846 + Bestand + + + + + + + + 10 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11389 + 1846-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.105. + Kongresse und Tagungen. Dokumentation + from 1899 + Bestand + + + + + + + + 11 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11243 + 1899-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + VII.103. + Alexander M. Kaiser (1887-1971) alias A. M. Cay, Karikaturist. Nachlass + 1945 - 1967 + Bestand + + + + + + + + 12 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11476 + 1945-01-01 + 0 + 1967-12-31 + 0 + 1 + + + + diff --git a/tests/fixtures/test_searchretrieve_with_maximum_records.xml b/tests/fixtures/test_searchretrieve_with_maximum_records.xml new file mode 100644 index 0000000..e7c2509 --- /dev/null +++ b/tests/fixtures/test_searchretrieve_with_maximum_records.xml @@ -0,0 +1,343 @@ + + + 1.2 + 12 + + + isad + xml + + + + VII.335.:2.34.8. + Podium "Frauen und Politik" beim Jubiläumsanlass "Frauenrechte-Menschenrechte" des Bundes Schweizerischer Frauenorganisationen BSF zu 150 Jahre Bundesstaat, 50 Jahre UNO-Menschenrechtserklärung und 27 Jahre politische Gleichberechtigung im Nationalratssaal in Bern vom 4. April 1998 + 1998 + Dossier + + + + + + + + 1 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=410130 + 1998-01-01 + 0 + 1998-12-31 + 0 + 0 + + + + isad + xml + + + + VII.424.:3.2.4.8. + Menschenrechte, Matinee der Schauspielunion, 18.04. (vor) 1964 + s. d. (sine dato) + Dossier + + + + + + + + 2 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=495785 + 0001-01-01 + 0 + 9999-12-31 + 0 + 0 + + + + isad + xml + + + + V.E.c.63. + Stadtpolizei, Kriminalkommissariat KK III. Staatsschutzakten Registratur 1 und 2 + 1920 - 1990 + Bestand + + + + + + + + 3 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=9514 + 1920-01-01 + 0 + 1990-12-31 + 0 + 1 + + + + isad + xml + + + + V.E.c.73. + Stadtpolizei, Bewilligungen. Akten + 1906 - 2014 + Bestand + + + + + + + + 4 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=207460 + 1906-01-01 + 0 + 2014-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.64. + Präsidialabteilung. Akten + 1955 - 1995 + Bestand + + + + + + + + 5 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8336 + 1955-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.900.:3.2. + Stadthaus. Drucksachen + 1951 - 2019 + Bestand + + + + + + + + 6 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8362 + 1951-01-01 + 0 + 2019-12-31 + 0 + 1 + + + + isad + xml + + + + VII.12. + Aktientheater, Stadttheater, Opernhaus Zürich AG. Theaterarchiv + 1830 - 1995 + Bestand + + + + + + + + 7 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11494 + 1830-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + VII.335. + Emilie Lieberherr (1924-2011), Stadträtin. Nachlass + approx. 1900 - 2004 + Bestand + + + + + + + + 8 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11736 + 1900-01-01 + 1 + 2004-12-31 + 0 + 1 + + + + isad + xml + + + + VII.424. + Dr. Peter Löffler (1926-2015), Dramaturg, Regisseur, künstlerischer Direktor am Schauspielhaus Zürich (1969/70). Nachlass + 1867 - 2012 + Bestand + + + + + + + + 9 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11835 + 1867-01-01 + 0 + 2012-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.42. + Ausstellungen. Dokumentation + from 1846 + Bestand + + + + + + + + 10 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11389 + 1846-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.105. + Kongresse und Tagungen. Dokumentation + from 1899 + Bestand + + + + + + + + 11 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11243 + 1899-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + VII.103. + Alexander M. Kaiser (1887-1971) alias A. M. Cay, Karikaturist. Nachlass + 1945 - 1967 + Bestand + + + + + + + + 12 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11476 + 1945-01-01 + 0 + 1967-12-31 + 0 + 1 + + + + diff --git a/tests/fixtures/test_searchretrieve_with_record_schema.xml b/tests/fixtures/test_searchretrieve_with_record_schema.xml new file mode 100644 index 0000000..e7c2509 --- /dev/null +++ b/tests/fixtures/test_searchretrieve_with_record_schema.xml @@ -0,0 +1,343 @@ + + + 1.2 + 12 + + + isad + xml + + + + VII.335.:2.34.8. + Podium "Frauen und Politik" beim Jubiläumsanlass "Frauenrechte-Menschenrechte" des Bundes Schweizerischer Frauenorganisationen BSF zu 150 Jahre Bundesstaat, 50 Jahre UNO-Menschenrechtserklärung und 27 Jahre politische Gleichberechtigung im Nationalratssaal in Bern vom 4. April 1998 + 1998 + Dossier + + + + + + + + 1 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=410130 + 1998-01-01 + 0 + 1998-12-31 + 0 + 0 + + + + isad + xml + + + + VII.424.:3.2.4.8. + Menschenrechte, Matinee der Schauspielunion, 18.04. (vor) 1964 + s. d. (sine dato) + Dossier + + + + + + + + 2 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=495785 + 0001-01-01 + 0 + 9999-12-31 + 0 + 0 + + + + isad + xml + + + + V.E.c.63. + Stadtpolizei, Kriminalkommissariat KK III. Staatsschutzakten Registratur 1 und 2 + 1920 - 1990 + Bestand + + + + + + + + 3 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=9514 + 1920-01-01 + 0 + 1990-12-31 + 0 + 1 + + + + isad + xml + + + + V.E.c.73. + Stadtpolizei, Bewilligungen. Akten + 1906 - 2014 + Bestand + + + + + + + + 4 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=207460 + 1906-01-01 + 0 + 2014-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.64. + Präsidialabteilung. Akten + 1955 - 1995 + Bestand + + + + + + + + 5 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8336 + 1955-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.900.:3.2. + Stadthaus. Drucksachen + 1951 - 2019 + Bestand + + + + + + + + 6 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8362 + 1951-01-01 + 0 + 2019-12-31 + 0 + 1 + + + + isad + xml + + + + VII.12. + Aktientheater, Stadttheater, Opernhaus Zürich AG. Theaterarchiv + 1830 - 1995 + Bestand + + + + + + + + 7 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11494 + 1830-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + VII.335. + Emilie Lieberherr (1924-2011), Stadträtin. Nachlass + approx. 1900 - 2004 + Bestand + + + + + + + + 8 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11736 + 1900-01-01 + 1 + 2004-12-31 + 0 + 1 + + + + isad + xml + + + + VII.424. + Dr. Peter Löffler (1926-2015), Dramaturg, Regisseur, künstlerischer Direktor am Schauspielhaus Zürich (1969/70). Nachlass + 1867 - 2012 + Bestand + + + + + + + + 9 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11835 + 1867-01-01 + 0 + 2012-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.42. + Ausstellungen. Dokumentation + from 1846 + Bestand + + + + + + + + 10 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11389 + 1846-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.105. + Kongresse und Tagungen. Dokumentation + from 1899 + Bestand + + + + + + + + 11 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11243 + 1899-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + VII.103. + Alexander M. Kaiser (1887-1971) alias A. M. Cay, Karikaturist. Nachlass + 1945 - 1967 + Bestand + + + + + + + + 12 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11476 + 1945-01-01 + 0 + 1967-12-31 + 0 + 1 + + + + diff --git a/tests/fixtures/test_searchretrieve_with_start_record.xml b/tests/fixtures/test_searchretrieve_with_start_record.xml new file mode 100644 index 0000000..e7c2509 --- /dev/null +++ b/tests/fixtures/test_searchretrieve_with_start_record.xml @@ -0,0 +1,343 @@ + + + 1.2 + 12 + + + isad + xml + + + + VII.335.:2.34.8. + Podium "Frauen und Politik" beim Jubiläumsanlass "Frauenrechte-Menschenrechte" des Bundes Schweizerischer Frauenorganisationen BSF zu 150 Jahre Bundesstaat, 50 Jahre UNO-Menschenrechtserklärung und 27 Jahre politische Gleichberechtigung im Nationalratssaal in Bern vom 4. April 1998 + 1998 + Dossier + + + + + + + + 1 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=410130 + 1998-01-01 + 0 + 1998-12-31 + 0 + 0 + + + + isad + xml + + + + VII.424.:3.2.4.8. + Menschenrechte, Matinee der Schauspielunion, 18.04. (vor) 1964 + s. d. (sine dato) + Dossier + + + + + + + + 2 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=495785 + 0001-01-01 + 0 + 9999-12-31 + 0 + 0 + + + + isad + xml + + + + V.E.c.63. + Stadtpolizei, Kriminalkommissariat KK III. Staatsschutzakten Registratur 1 und 2 + 1920 - 1990 + Bestand + + + + + + + + 3 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=9514 + 1920-01-01 + 0 + 1990-12-31 + 0 + 1 + + + + isad + xml + + + + V.E.c.73. + Stadtpolizei, Bewilligungen. Akten + 1906 - 2014 + Bestand + + + + + + + + 4 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=207460 + 1906-01-01 + 0 + 2014-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.64. + Präsidialabteilung. Akten + 1955 - 1995 + Bestand + + + + + + + + 5 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8336 + 1955-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.900.:3.2. + Stadthaus. Drucksachen + 1951 - 2019 + Bestand + + + + + + + + 6 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8362 + 1951-01-01 + 0 + 2019-12-31 + 0 + 1 + + + + isad + xml + + + + VII.12. + Aktientheater, Stadttheater, Opernhaus Zürich AG. Theaterarchiv + 1830 - 1995 + Bestand + + + + + + + + 7 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11494 + 1830-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + VII.335. + Emilie Lieberherr (1924-2011), Stadträtin. Nachlass + approx. 1900 - 2004 + Bestand + + + + + + + + 8 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11736 + 1900-01-01 + 1 + 2004-12-31 + 0 + 1 + + + + isad + xml + + + + VII.424. + Dr. Peter Löffler (1926-2015), Dramaturg, Regisseur, künstlerischer Direktor am Schauspielhaus Zürich (1969/70). Nachlass + 1867 - 2012 + Bestand + + + + + + + + 9 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11835 + 1867-01-01 + 0 + 2012-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.42. + Ausstellungen. Dokumentation + from 1846 + Bestand + + + + + + + + 10 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11389 + 1846-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.105. + Kongresse und Tagungen. Dokumentation + from 1899 + Bestand + + + + + + + + 11 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11243 + 1899-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + VII.103. + Alexander M. Kaiser (1887-1971) alias A. M. Cay, Karikaturist. Nachlass + 1945 - 1967 + Bestand + + + + + + + + 12 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11476 + 1945-01-01 + 0 + 1967-12-31 + 0 + 1 + + + + From 1553b512fdf3ca25a0b84275d6f81647eeb7f294 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Sat, 3 Oct 2020 23:35:30 +0200 Subject: [PATCH 08/14] Add possibility to pass kwargs to requests --- sruthi/client.py | 14 +- tests/client_test.py | 24 +- .../fixtures/test_passing_requests_kwargs.xml | 343 ++++++++++++++++++ 3 files changed, 372 insertions(+), 9 deletions(-) create mode 100644 tests/fixtures/test_passing_requests_kwargs.xml diff --git a/sruthi/client.py b/sruthi/client.py index 4149612..11e8078 100644 --- a/sruthi/client.py +++ b/sruthi/client.py @@ -13,7 +13,7 @@ def __init__(self, url=None, maximum_records=10, record_schema=None): self.sru_version = '1.2' self.record_schema = record_schema - def searchretrieve(self, query, start_record=1): + def searchretrieve(self, query, start_record=1, requests_kwargs=None): params = { 'operation': 'searchRetrieve', 'version': self.sru_version, @@ -25,25 +25,26 @@ def searchretrieve(self, query, start_record=1): if self.record_schema: params['recordSchema'] = self.record_schema - data_loader = DataLoader(self.url, params) + data_loader = DataLoader(self.url, params, requests_kwargs) return response.SearchRetrieveResponse(data_loader) - def explain(self): + def explain(self, requests_kwargs=None): params = { 'operation': 'explain', 'version': self.sru_version, } - data_loader = DataLoader(self.url, params) + data_loader = DataLoader(self.url, params, requests_kwargs) return response.ExplainResponse(data_loader) class DataLoader(object): - def __init__(self, url, params): + def __init__(self, url, params, requests_kwargs=None): self.session = requests.Session() self.url = url self.params = params self.response = None self.xmlparser = xmlparse.XMLParser() + self.requests_kwargs = requests_kwargs or {} def load(self, **kwargs): self.params.update(kwargs) @@ -55,7 +56,8 @@ def _get_content(self, url, params): try: res = self.session.get( url, - params=params + params=params, + **self.requests_kwargs ) res.raise_for_status() except requests.exceptions.HTTPError as e: diff --git a/tests/client_test.py b/tests/client_test.py index 6c51b2c..522502e 100644 --- a/tests/client_test.py +++ b/tests/client_test.py @@ -118,7 +118,7 @@ def test_passing_maximum_records(self): self.session_mock.return_value.get.assert_called_once_with( 'http://my-param.com/sru', params={ - 'operation': 'searchretrieve', + 'operation': 'searchRetrieve', 'version': '1.2', 'query': 'test-query', 'startRecord': 1, @@ -134,7 +134,7 @@ def test_passing_record_schema(self): self.session_mock.return_value.get.assert_called_once_with( 'http://my-param.com/sru', params={ - 'operation': 'searchretrieve', + 'operation': 'searchRetrieve', 'version': '1.2', 'query': 'test-query', 'startRecord': 1, @@ -143,6 +143,24 @@ def test_passing_record_schema(self): } ) + def test_passing_requests_kwargs(self): + client = Client('https://my-param.com/sru', record_schema='dc') + self.assertEqual(client.record_schema, 'dc') + + client.searchretrieve('test-query', requests_kwargs={'verify': False}) + self.session_mock.return_value.get.assert_called_once_with( + 'https://my-param.com/sru', + params={ + 'operation': 'searchRetrieve', + 'version': '1.2', + 'query': 'test-query', + 'startRecord': 1, + 'recordSchema': 'dc', + 'maximumRecords': 10, + }, + verify=False + ) + def test_passing_start_record(self): client = Client('http://my-param.com/sru') @@ -150,7 +168,7 @@ def test_passing_start_record(self): self.session_mock.return_value.get.assert_called_once_with( 'http://my-param.com/sru', params={ - 'operation': 'searchretrieve', + 'operation': 'searchRetrieve', 'version': '1.2', 'query': 'test-query', 'startRecord': 10, diff --git a/tests/fixtures/test_passing_requests_kwargs.xml b/tests/fixtures/test_passing_requests_kwargs.xml new file mode 100644 index 0000000..e7c2509 --- /dev/null +++ b/tests/fixtures/test_passing_requests_kwargs.xml @@ -0,0 +1,343 @@ + + + 1.2 + 12 + + + isad + xml + + + + VII.335.:2.34.8. + Podium "Frauen und Politik" beim Jubiläumsanlass "Frauenrechte-Menschenrechte" des Bundes Schweizerischer Frauenorganisationen BSF zu 150 Jahre Bundesstaat, 50 Jahre UNO-Menschenrechtserklärung und 27 Jahre politische Gleichberechtigung im Nationalratssaal in Bern vom 4. April 1998 + 1998 + Dossier + + + + + + + + 1 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=410130 + 1998-01-01 + 0 + 1998-12-31 + 0 + 0 + + + + isad + xml + + + + VII.424.:3.2.4.8. + Menschenrechte, Matinee der Schauspielunion, 18.04. (vor) 1964 + s. d. (sine dato) + Dossier + + + + + + + + 2 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=495785 + 0001-01-01 + 0 + 9999-12-31 + 0 + 0 + + + + isad + xml + + + + V.E.c.63. + Stadtpolizei, Kriminalkommissariat KK III. Staatsschutzakten Registratur 1 und 2 + 1920 - 1990 + Bestand + + + + + + + + 3 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=9514 + 1920-01-01 + 0 + 1990-12-31 + 0 + 1 + + + + isad + xml + + + + V.E.c.73. + Stadtpolizei, Bewilligungen. Akten + 1906 - 2014 + Bestand + + + + + + + + 4 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=207460 + 1906-01-01 + 0 + 2014-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.64. + Präsidialabteilung. Akten + 1955 - 1995 + Bestand + + + + + + + + 5 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8336 + 1955-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.900.:3.2. + Stadthaus. Drucksachen + 1951 - 2019 + Bestand + + + + + + + + 6 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8362 + 1951-01-01 + 0 + 2019-12-31 + 0 + 1 + + + + isad + xml + + + + VII.12. + Aktientheater, Stadttheater, Opernhaus Zürich AG. Theaterarchiv + 1830 - 1995 + Bestand + + + + + + + + 7 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11494 + 1830-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + VII.335. + Emilie Lieberherr (1924-2011), Stadträtin. Nachlass + approx. 1900 - 2004 + Bestand + + + + + + + + 8 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11736 + 1900-01-01 + 1 + 2004-12-31 + 0 + 1 + + + + isad + xml + + + + VII.424. + Dr. Peter Löffler (1926-2015), Dramaturg, Regisseur, künstlerischer Direktor am Schauspielhaus Zürich (1969/70). Nachlass + 1867 - 2012 + Bestand + + + + + + + + 9 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11835 + 1867-01-01 + 0 + 2012-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.42. + Ausstellungen. Dokumentation + from 1846 + Bestand + + + + + + + + 10 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11389 + 1846-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.105. + Kongresse und Tagungen. Dokumentation + from 1899 + Bestand + + + + + + + + 11 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11243 + 1899-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + VII.103. + Alexander M. Kaiser (1887-1971) alias A. M. Cay, Karikaturist. Nachlass + 1945 - 1967 + Bestand + + + + + + + + 12 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11476 + 1945-01-01 + 0 + 1967-12-31 + 0 + 1 + + + + From 96b87fcf3c827e6867b2c7231eb603cf56c832f3 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Sat, 3 Oct 2020 23:44:11 +0200 Subject: [PATCH 09/14] Add tests for requests_kwargs in explain() --- examples/isad.py | 4 -- examples/schemas.py | 3 - sruthi/sru.py | 4 +- tests/client_test.py | 13 ++++ .../test_explain_with_requests_kwargs.xml | 61 +++++++++++++++++++ 5 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 tests/fixtures/test_explain_with_requests_kwargs.xml diff --git a/examples/isad.py b/examples/isad.py index a86f316..729805a 100644 --- a/examples/isad.py +++ b/examples/isad.py @@ -1,6 +1,4 @@ import sruthi -import yaml -import sys from pprint import pprint # check supported schemas of server @@ -20,5 +18,3 @@ record_schema=schema ) pprint(records[0]) - - diff --git a/examples/schemas.py b/examples/schemas.py index 681753d..80a02fe 100644 --- a/examples/schemas.py +++ b/examples/schemas.py @@ -1,6 +1,4 @@ import sruthi -import yaml -import sys from pprint import pprint # check supported schemas of server @@ -21,6 +19,5 @@ record_schema=schema ) pprint(records[0]) - #print(yaml.dump(records[0], allow_unicode=True, default_flow_style=False)) print('') print('') diff --git a/sruthi/sru.py b/sruthi/sru.py index c22aaa1..0a22b84 100644 --- a/sruthi/sru.py +++ b/sruthi/sru.py @@ -5,11 +5,11 @@ def searchretrieve(url, query, **kwargs): search_params = ['query', 'start_record'] - search_kwargs = {k: v for k,v in kwargs.items() if k in search_params} + 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 = {k: v for k, v in kwargs.items() if k not in search_params} client_kwargs['url'] = url c = client.Client(**client_kwargs) diff --git a/tests/client_test.py b/tests/client_test.py index 522502e..18b5d07 100644 --- a/tests/client_test.py +++ b/tests/client_test.py @@ -110,6 +110,19 @@ def test_explain(self): self.assertEqual(config['my-test-config'], 'test123') self.assertEqual(config['defaults']['numberOfRecords'], 99) + def test_explain_with_requests_kwargs(self): + client = Client('https://test.com/sru') + client.explain(requests_kwargs={'verify': False}) + + self.session_mock.return_value.get.assert_called_once_with( + 'https://test.com/sru', + params={ + 'operation': 'explain', + 'version': '1.2', + }, + verify=False + ) + def test_passing_maximum_records(self): client = Client('http://my-param.com/sru', maximum_records=111) self.assertEqual(client.maximum_records, 111) diff --git a/tests/fixtures/test_explain_with_requests_kwargs.xml b/tests/fixtures/test_explain_with_requests_kwargs.xml new file mode 100644 index 0000000..ab7ceb9 --- /dev/null +++ b/tests/fixtures/test_explain_with_requests_kwargs.xml @@ -0,0 +1,61 @@ + + + 1.2 + + XML + http://explain.z3950.org/dtd/2.1/ + + + + + https://test.com/sru + 80 + sru + + + Testarchiv Online Search + Durchsuchen der Bestände des Testarchivs. + test@test.com + + + + + Title + + title + + + + Reference Code + + reference + + + + Date + + date + + + + Level + + descriptionlevel + + + + + + ISAD(G) + + + + 99 + 99 + test123 + + + + + + From 39ceb49d43edbb913d7c0e9736e4803f737e0f68 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Sun, 4 Oct 2020 00:12:37 +0200 Subject: [PATCH 10/14] Remove CQL attribute from README --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 942dfbe..c532b38 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,6 @@ import sruthi # note: records is an iterator records = sruthi.searchretrieve('https://suche.staatsarchiv.djiktzh.ch/SRU/', query='Human') -print(records.cql) print(records.sru_version) print(records.count) From e39a09ed722b555e28e37aa2b10c0af2c6aa1f90 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Sun, 4 Oct 2020 00:12:55 +0200 Subject: [PATCH 11/14] Add simple searchretrieve example --- examples/searchretrieve.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 examples/searchretrieve.py diff --git a/examples/searchretrieve.py b/examples/searchretrieve.py new file mode 100644 index 0000000..6d316a7 --- /dev/null +++ b/examples/searchretrieve.py @@ -0,0 +1,14 @@ +import sruthi + +records = sruthi.searchretrieve('https://suche.staatsarchiv.djiktzh.ch/SRU/', query='Zurich') +print("SRU version:", records.sru_version) +print("Count:", records.count) +print('') + +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 + print('') From 5026efd5209a41e619d943f8fb45f503206c61de Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Sun, 4 Oct 2020 00:39:29 +0200 Subject: [PATCH 12/14] Make sure requests_kwargs is supported by sru.py --- sruthi/sru.py | 2 +- ...st_searchretrieve_with_requests_kwargs.xml | 343 ++++++++++++++++++ tests/sru_test.py | 67 ++++ 3 files changed, 411 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/test_searchretrieve_with_requests_kwargs.xml diff --git a/sruthi/sru.py b/sruthi/sru.py index 0a22b84..583b482 100644 --- a/sruthi/sru.py +++ b/sruthi/sru.py @@ -4,7 +4,7 @@ def searchretrieve(url, query, **kwargs): - search_params = ['query', 'start_record'] + 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 diff --git a/tests/fixtures/test_searchretrieve_with_requests_kwargs.xml b/tests/fixtures/test_searchretrieve_with_requests_kwargs.xml new file mode 100644 index 0000000..e7c2509 --- /dev/null +++ b/tests/fixtures/test_searchretrieve_with_requests_kwargs.xml @@ -0,0 +1,343 @@ + + + 1.2 + 12 + + + isad + xml + + + + VII.335.:2.34.8. + Podium "Frauen und Politik" beim Jubiläumsanlass "Frauenrechte-Menschenrechte" des Bundes Schweizerischer Frauenorganisationen BSF zu 150 Jahre Bundesstaat, 50 Jahre UNO-Menschenrechtserklärung und 27 Jahre politische Gleichberechtigung im Nationalratssaal in Bern vom 4. April 1998 + 1998 + Dossier + + + + + + + + 1 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=410130 + 1998-01-01 + 0 + 1998-12-31 + 0 + 0 + + + + isad + xml + + + + VII.424.:3.2.4.8. + Menschenrechte, Matinee der Schauspielunion, 18.04. (vor) 1964 + s. d. (sine dato) + Dossier + + + + + + + + 2 + + 0.38 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=495785 + 0001-01-01 + 0 + 9999-12-31 + 0 + 0 + + + + isad + xml + + + + V.E.c.63. + Stadtpolizei, Kriminalkommissariat KK III. Staatsschutzakten Registratur 1 und 2 + 1920 - 1990 + Bestand + + + + + + + + 3 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=9514 + 1920-01-01 + 0 + 1990-12-31 + 0 + 1 + + + + isad + xml + + + + V.E.c.73. + Stadtpolizei, Bewilligungen. Akten + 1906 - 2014 + Bestand + + + + + + + + 4 + + 0.26 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=207460 + 1906-01-01 + 0 + 2014-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.64. + Präsidialabteilung. Akten + 1955 - 1995 + Bestand + + + + + + + + 5 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8336 + 1955-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + V.B.c.900.:3.2. + Stadthaus. Drucksachen + 1951 - 2019 + Bestand + + + + + + + + 6 + + 0.17 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=8362 + 1951-01-01 + 0 + 2019-12-31 + 0 + 1 + + + + isad + xml + + + + VII.12. + Aktientheater, Stadttheater, Opernhaus Zürich AG. Theaterarchiv + 1830 - 1995 + Bestand + + + + + + + + 7 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11494 + 1830-01-01 + 0 + 1995-12-31 + 0 + 1 + + + + isad + xml + + + + VII.335. + Emilie Lieberherr (1924-2011), Stadträtin. Nachlass + approx. 1900 - 2004 + Bestand + + + + + + + + 8 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11736 + 1900-01-01 + 1 + 2004-12-31 + 0 + 1 + + + + isad + xml + + + + VII.424. + Dr. Peter Löffler (1926-2015), Dramaturg, Regisseur, künstlerischer Direktor am Schauspielhaus Zürich (1969/70). Nachlass + 1867 - 2012 + Bestand + + + + + + + + 9 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11835 + 1867-01-01 + 0 + 2012-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.42. + Ausstellungen. Dokumentation + from 1846 + Bestand + + + + + + + + 10 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11389 + 1846-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + V.L.105. + Kongresse und Tagungen. Dokumentation + from 1899 + Bestand + + + + + + + + 11 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11243 + 1899-01-01 + 0 + 9999-12-31 + 0 + 1 + + + + isad + xml + + + + VII.103. + Alexander M. Kaiser (1887-1971) alias A. M. Cay, Karikaturist. Nachlass + 1945 - 1967 + Bestand + + + + + + + + 12 + + 0.09 + https://amsquery.stadt-zuerich.ch/detail.aspx?Id=11476 + 1945-01-01 + 0 + 1967-12-31 + 0 + 1 + + + + diff --git a/tests/sru_test.py b/tests/sru_test.py index a1d53da..44e9ca1 100644 --- a/tests/sru_test.py +++ b/tests/sru_test.py @@ -6,22 +6,89 @@ class TestSru(SruthiTestCase): def test_searchretrieve(self): r = sruthi.searchretrieve('http://test.com/sru/', 'Test-Query') self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + self.session_mock.return_value.get.assert_called_once_with( + 'http://test.com/sru/', + params={ + 'operation': 'searchRetrieve', + 'version': '1.2', + 'query': 'Test-Query', + 'startRecord': 1, + 'maximumRecords': 10, + } + ) def test_searchretrieve_with_maximum_records(self): r = sruthi.searchretrieve('http://test.com/sru/', 'Test-Query', maximum_records=100) self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + self.session_mock.return_value.get.assert_called_once_with( + 'http://test.com/sru/', + params={ + 'operation': 'searchRetrieve', + 'version': '1.2', + 'query': 'Test-Query', + 'startRecord': 1, + 'maximumRecords': 100, + } + ) def test_searchretrieve_with_record_schema(self): r = sruthi.searchretrieve('http://test.com/sru/', 'Test-Query', record_schema='isad') self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + self.session_mock.return_value.get.assert_called_once_with( + 'http://test.com/sru/', + params={ + 'operation': 'searchRetrieve', + 'version': '1.2', + 'query': 'Test-Query', + 'startRecord': 1, + 'maximumRecords': 10, + 'recordSchema': 'isad', + } + ) def test_searchretrieve_with_start_record(self): r = sruthi.searchretrieve('http://test.com/sru/', 'Test-Query', start_record=10) self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + self.session_mock.return_value.get.assert_called_once_with( + 'http://test.com/sru/', + params={ + 'operation': 'searchRetrieve', + 'version': '1.2', + 'query': 'Test-Query', + 'startRecord': 10, + 'maximumRecords': 10, + } + ) + + def test_searchretrieve_with_requests_kwargs(self): + r = sruthi.searchretrieve( + 'http://test.com/sru/', + 'Test-Query', + requests_kwargs={'verify': False} + ) + self.assertIsInstance(r, sruthi.response.SearchRetrieveResponse) + self.session_mock.return_value.get.assert_called_once_with( + 'http://test.com/sru/', + params={ + 'operation': 'searchRetrieve', + 'version': '1.2', + 'query': 'Test-Query', + 'startRecord': 1, + 'maximumRecords': 10, + }, + verify=False + ) def test_explain(self): info = sruthi.explain('http://test.com/sru/') self.assertIsInstance(info, sruthi.response.ExplainResponse) + self.session_mock.return_value.get.assert_called_once_with( + 'http://test.com/sru/', + params={ + 'operation': 'explain', + 'version': '1.2', + } + ) def test_client(self): client = sruthi.Client('http://test.com/sru') From 39cf68d142b39aa10ae6c91330b9a1d4d35d8270 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Sun, 4 Oct 2020 00:50:42 +0200 Subject: [PATCH 13/14] Release 0.1.0 --- CHANGELOG.md | 11 ++++++++++- sruthi/__init__.py | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24ba4a0..394fb48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [0.1.0] - 2020-10-04 +### Added +- Add `record_schema` parameter +- Add new dependencies to xmltodict and flatten-dict + +### Changed +- recordData is now returned as flattened dict (if possible) + ## [0.0.5] - 2020-06-10 ### Changed - Remove dependencies to convert md to rst @@ -45,7 +53,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - `Fixed` for any bug fixes. - `Security` to invite users to upgrade in case of vulnerabilities. -[Unreleased]: https://github.com/metaodi/sruthi/compare/v0.0.5...HEAD +[Unreleased]: https://github.com/metaodi/sruthi/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/metaodi/sruthi/compare/v0.0.5...v0.1.0 [0.0.5]: https://github.com/metaodi/sruthi/compare/v0.0.4...v0.0.5 [0.0.4]: https://github.com/metaodi/sruthi/compare/v0.0.3...v0.0.4 [0.0.3]: https://github.com/metaodi/sruthi/compare/v0.0.2...v0.0.3 diff --git a/sruthi/__init__.py b/sruthi/__init__.py index 126a60e..db700b5 100644 --- a/sruthi/__init__.py +++ b/sruthi/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.0.5' +__version__ = '0.1.0' __all__ = ['client', 'errors', 'response', 'sru', 'xmlparse'] from .errors import SruthiError, ServerIncompatibleError, SruError, NoMoreRecordsError # noqa From ea105270c033dd648fd3c6a5a1a1629f380c4ca2 Mon Sep 17 00:00:00 2001 From: Stefan Oderbolz Date: Sun, 4 Oct 2020 00:56:27 +0200 Subject: [PATCH 14/14] Add fix paragraph in 0.1.0 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 394fb48..b9a89dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Changed - recordData is now returned as flattened dict (if possible) +### Fixed +- Fix typo in `searchRetrieve` operation name + ## [0.0.5] - 2020-06-10 ### Changed - Remove dependencies to convert md to rst