diff --git a/api.ipynb b/api.ipynb index 959cf1d..74a9d3f 100644 --- a/api.ipynb +++ b/api.ipynb @@ -29,6 +29,7 @@ "import random\n", "import os\n", "from copy import deepcopy\n", + "import pytest\n", "%load_ext dotenv\n", "%dotenv" ] @@ -68,6 +69,22 @@ " def clear_cache():\n", " self.s.cache.clear()\n", " \n", + " def process_response(self, response):\n", + " '''\n", + " Handle Omeka responses, raising exceptions on errors.\n", + " '''\n", + " # Raise exception on HTTP error\n", + " response.raise_for_status()\n", + " # Try extracting JSON data\n", + " try:\n", + " data = response.json()\n", + " # If there's no JSON, display the raw response text and raise exception\n", + " except (json.decoder.JSONDecodeError, ValueError):\n", + " print(f'Bad JSON: {response.text}')\n", + " raise\n", + " else:\n", + " return data\n", + " \n", " def format_resource_id(self, resource_id, resource_type):\n", " '''\n", " Generate a formatted id for the resource with the specified Omeka id number and resource type.\n", @@ -100,8 +117,8 @@ " * `results` - a list of dicts, each containing a JSON-LD formatted representation of a resource\n", " '''\n", " response = self.s.get(f'{self.api_url}/{resource_type}/', params=kwargs)\n", - " results = response.json()\n", - " return {'total_results': int(response.headers['Omeka-S-Total-Results']), 'results': results}\n", + " data = self.process_response(response)\n", + " return {'total_results': int(response.headers['Omeka-S-Total-Results']), 'results': data}\n", " \n", " def get_resource(self, resource_type, **kwargs):\n", " '''\n", @@ -135,8 +152,8 @@ " * a dict containing a JSON-LD formatted representation of the resource\n", " '''\n", " response = self.s.get(f'{self.api_url}/{resource_type}/{resource_id}')\n", - " if response.status_code != 404:\n", - " return response.json()\n", + " data = self.process_response(response)\n", + " return data\n", "\n", " def get_template_by_label(self, label):\n", " '''\n", @@ -229,8 +246,8 @@ " }\n", " params = self.filter_items(params, **extra_filters)\n", " # print(params)\n", - " data = self.get_resources('items', **params)\n", - " return data\n", + " results = self.get_resources('items', **params)\n", + " return results\n", " \n", " def search_items(self, query, search_type='fulltext_search', page=1, **extra_filters):\n", " '''\n", @@ -257,7 +274,8 @@ " params = {'page': page}\n", " params[search_type] = query\n", " params = self.filter_items(params, **extra_filters)\n", - " return self.get_resources('items', **params)\n", + " results = self.get_resources('items', **params)\n", + " return results\n", "\n", " def get_template_properties(self, template_id):\n", " '''\n", @@ -279,7 +297,7 @@ " prop_url = prop['o:property']['@id']\n", " # The resource template doesn't include property terms, so we have to go to the property data\n", " response = self.s.get(prop_url)\n", - " data = response.json()\n", + " data = self.process_response(response)\n", " # Use default data types if they're not defined in the resource template\n", " data_type = ['literal', 'uri', 'resource:item'] if prop['o:data_type'] == [] else prop['o:data_type']\n", " properties[data['o:term']] = {'property_id': data['o:id'], 'type': data_type}\n", @@ -354,7 +372,8 @@ " else:\n", " response = self.s.post(f'{self.api_url}/items', json=payload, params=self.params)\n", " #print(response.text)\n", - " return response.json()\n", + " data = self.process_response(response)\n", + " return data\n", " \n", " def prepare_item_payload(self, terms):\n", " '''\n", @@ -472,7 +491,8 @@ " * dict with JSON-LD representation of the deleted resource\n", " '''\n", " response = self.s.delete(f'{self.api_url}/{resource_type}/{resource_id}', params=self.params)\n", - " return response.json()\n", + " data = self.process_response(response)\n", + " return data\n", " \n", " def update_resource(self, payload, resource_type='items'):\n", " '''\n", @@ -486,7 +506,8 @@ " make your desired changes to it, then submit the updated resource as your payload.\n", " '''\n", " response = self.s.put(f'{self.api_url}/{resource_type}/{payload[\"o:id\"]}', json=payload, params=self.params)\n", - " return response.json()\n", + " data = self.process_response(response)\n", + " return data\n", " \n", " def add_media_to_item(self, item_id, media_file, payload={}, template_id=None, class_id=None):\n", " '''\n", @@ -530,7 +551,8 @@ " files[f'file[0]'] = path.read_bytes()\n", " files['data'] = (None, json.dumps(payload), 'application/json')\n", " response = self.s.post(f'{self.api_url}/media', files=files, params=self.params)\n", - " return response.json()\n", + " data = self.process_response(response)\n", + " return data\n", " \n", " # MANAGING TEMPLATES\n", " \n", @@ -665,7 +687,8 @@ " '''\n", " # Upload the template payload\n", " response = self.s.post(f'{self.api_url}/resource_templates/', params=self.params, json=template_payload)\n", - " return response.json()\n", + " data = self.process_response(response)\n", + " return data\n", " \n", " # MODULE RELATED METHODS\n", "\n", @@ -707,7 +730,8 @@ " if media_id:\n", " marker_payload['o:media'] = {'o:id': media_id}\n", " response = self.s.post(f'{self.api_url}/mapping_markers/', json=marker_payload, params=self.params)\n", - " return response.json()\n" + " data = self.process_response(response)\n", + " return data\n" ] }, { @@ -763,7 +787,7 @@ { "data": { "text/markdown": [ - "
OmekaAPIClient.get_resources
[source]OmekaAPIClient.get_resources
[source]OmekaAPIClient.get_resources
(**`resource_type`**, **\\*\\*`kwargs`**)\n",
"\n",
@@ -799,7 +823,7 @@
{
"data": {
"text/plain": [
- "101"
+ "120"
]
},
"execution_count": null,
@@ -841,7 +865,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.get_resource_by_id
[source]OmekaAPIClient.get_resource_by_id
[source]OmekaAPIClient.get_resource_by_id
(**`resource_id`**, **`resource_type`**=*`'items'`*)\n",
"\n",
@@ -899,7 +923,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.get_template_by_label
[source]OmekaAPIClient.get_template_by_label
[source]OmekaAPIClient.get_template_by_label
(**`label`**)\n",
"\n",
@@ -960,7 +984,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.get_resource_by_term
[source]OmekaAPIClient.get_resource_by_term
[source]OmekaAPIClient.get_resource_by_term
(**`term`**, **`resource_type`**=*`'properties'`*)\n",
"\n",
@@ -1032,7 +1056,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.get_resource_from_vocab
[source]OmekaAPIClient.get_resource_from_vocab
[source]OmekaAPIClient.get_resource_from_vocab
(**`local_name`**, **`vocabulary_namespace_uri`**=*`'http://schema.org/'`*, **`resource_type`**=*`'properties'`*)\n",
"\n",
@@ -1111,7 +1135,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.get_property_id
[source]OmekaAPIClient.get_property_id
[source]OmekaAPIClient.get_property_id
(**`term`**)\n",
"\n",
@@ -1176,7 +1200,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.filter_items_by_property
[source]OmekaAPIClient.filter_items_by_property
[source]OmekaAPIClient.filter_items_by_property
(**`filter_property`**=*`'schema:name'`*, **`filter_value`**=*`''`*, **`filter_type`**=*`'eq'`*, **`page`**=*`1`*, **\\*\\*`extra_filters`**)\n",
"\n",
@@ -1231,7 +1255,7 @@
{
"data": {
"text/plain": [
- "'Clement Wragge at Home. - UPDATED!'"
+ "'Clement Wragge at Home. - UPDATED! - UPDATED!'"
]
},
"execution_count": null,
@@ -1251,7 +1275,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.search_items
[source]OmekaAPIClient.search_items
[source]OmekaAPIClient.search_items
(**`query`**, **`search_type`**=*`'fulltext_search'`*, **`page`**=*`1`*, **\\*\\*`extra_filters`**)\n",
"\n",
@@ -1295,7 +1319,7 @@
{
"data": {
"text/plain": [
- "21"
+ "23"
]
},
"execution_count": null,
@@ -1359,7 +1383,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.prepare_item_payload
[source]OmekaAPIClient.prepare_item_payload
[source]OmekaAPIClient.prepare_item_payload
(**`terms`**)\n",
"\n",
@@ -1456,7 +1480,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.prepare_item_payload_using_template
[source]OmekaAPIClient.prepare_item_payload_using_template
[source]OmekaAPIClient.prepare_item_payload_using_template
(**`terms`**, **`template_id`**)\n",
"\n",
@@ -1548,7 +1572,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.add_media_to_payload
[source]OmekaAPIClient.add_media_to_payload
[source]OmekaAPIClient.add_media_to_payload
(**`payload`**, **`media_files`**)\n",
"\n",
@@ -1612,7 +1636,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.add_item
[source]OmekaAPIClient.add_item
[source]OmekaAPIClient.add_item
(**`payload`**, **`media_files`**=*`None`*, **`template_id`**=*`None`*, **`class_id`**=*`None`*, **`item_set_id`**=*`None`*)\n",
"\n",
@@ -1656,9 +1680,9 @@
"data": {
"text/plain": [
"{'@context': 'https://timsherratt.org/collections/api-context',\n",
- " '@id': 'https://timsherratt.org/collections/api/items/992',\n",
+ " '@id': 'https://timsherratt.org/collections/api/items/1038',\n",
" '@type': 'o:Item',\n",
- " 'o:id': 992,\n",
+ " 'o:id': 1038,\n",
" 'o:is_public': True,\n",
" 'o:owner': {'@id': 'https://timsherratt.org/collections/api/users/1',\n",
" 'o:id': 1},\n",
@@ -1667,9 +1691,9 @@
" 'o:thumbnail': None,\n",
" 'o:title': 'My first resource!',\n",
" 'thumbnail_display_urls': {'large': None, 'medium': None, 'square': None},\n",
- " 'o:created': {'@value': '2022-04-03T06:43:24+00:00',\n",
+ " 'o:created': {'@value': '2022-04-04T00:47:02+00:00',\n",
" '@type': 'http://www.w3.org/2001/XMLSchema#dateTime'},\n",
- " 'o:modified': {'@value': '2022-04-03T06:43:24+00:00',\n",
+ " 'o:modified': {'@value': '2022-04-04T00:47:02+00:00',\n",
" '@type': 'http://www.w3.org/2001/XMLSchema#dateTime'},\n",
" 'o:media': [],\n",
" 'o:item_set': [],\n",
@@ -1740,7 +1764,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.delete_resource
[source]OmekaAPIClient.delete_resource
[source]OmekaAPIClient.delete_resource
(**`resource_id`**, **`resource_type`**)\n",
"\n",
@@ -1783,8 +1807,9 @@
"# The titles of the random and deleted items should be the same\n",
"assert deleted_resource['o:title'] == random_item['o:title']\n",
"\n",
- "# Trying to get the random item should now return None\n",
- "assert omeka_auth.get_resource_by_id(random_item['o:id'], 'items') is None"
+ "# Trying to get the random item should now raise an HTTP 404 error\n",
+ "with pytest.raises(requests.exceptions.HTTPError):\n",
+ " omeka_auth.get_resource_by_id(random_item['o:id'], 'items')"
]
},
{
@@ -1795,7 +1820,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.update_resource
[source]OmekaAPIClient.update_resource
[source]OmekaAPIClient.update_resource
(**`payload`**, **`resource_type`**=*`'items'`*)\n",
"\n",
@@ -1829,7 +1854,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "The Courier-Mail (Brisbane, Qld. : 1933 - 1954) - UPDATED!\n"
+ "Wellington Times (NSW : 1899 - 1954) - UPDATED! - UPDATED! - UPDATED!\n"
]
}
],
@@ -1866,7 +1891,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.add_media_to_item
[source]OmekaAPIClient.add_media_to_item
[source]OmekaAPIClient.add_media_to_item
(**`item_id`**, **`media_file`**, **`payload`**=*`{}`*, **`template_id`**=*`None`*, **`class_id`**=*`None`*)\n",
"\n",
@@ -2018,7 +2043,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.add_marker_to_item
[source]OmekaAPIClient.add_marker_to_item
[source]OmekaAPIClient.add_marker_to_item
(**`item_id`**, **`coords`**=*`None`*, **`terms`**=*`None`*, **`label`**=*`None`*, **`media_id`**=*`None`*)\n",
"\n",
@@ -2156,7 +2181,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.prepare_template_payload
[source]OmekaAPIClient.prepare_template_payload
[source]OmekaAPIClient.prepare_template_payload
(**`template_file`**)\n",
"\n",
@@ -2217,7 +2242,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.upload_template
[source]OmekaAPIClient.upload_template
[source]OmekaAPIClient.upload_template
(**`template_payload`**)\n",
"\n",
@@ -2277,7 +2302,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.localise_custom_vocabs
[source]OmekaAPIClient.localise_custom_vocabs
[source]OmekaAPIClient.localise_custom_vocabs
(**`data_types`**)\n",
"\n",
@@ -2339,7 +2364,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.get_template_class_id
[source]OmekaAPIClient.get_template_class_id
[source]OmekaAPIClient.get_template_class_id
(**`template`**)\n",
"\n",
@@ -2388,7 +2413,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.get_template_property_id
[source]OmekaAPIClient.get_template_property_id
[source]OmekaAPIClient.get_template_property_id
(**`template`**, **`term`**)\n",
"\n",
@@ -2447,7 +2472,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.format_resource_id
[source]OmekaAPIClient.format_resource_id
[source]OmekaAPIClient.format_resource_id
(**`resource_id`**, **`resource_type`**)\n",
"\n",
@@ -2494,7 +2519,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.prepare_property_value
[source]OmekaAPIClient.prepare_property_value
[source]OmekaAPIClient.prepare_property_value
(**`value`**, **`property_id`**)\n",
"\n",
@@ -2565,7 +2590,7 @@
{
"data": {
"text/markdown": [
- "OmekaAPIClient.get_template_properties
[source]OmekaAPIClient.get_template_properties
[source]OmekaAPIClient.get_template_properties
(**`template_id`**)\n",
"\n",
@@ -2859,9 +2884,9 @@
"data": {
"text/plain": [
"{'@context': 'http://timsherratt.org/collections/api-context',\n",
- " '@id': 'http://timsherratt.org/collections/api/items/999',\n",
+ " '@id': 'http://timsherratt.org/collections/api/items/1045',\n",
" '@type': ['o:Item', 'schema:Newspaper'],\n",
- " 'o:id': 999,\n",
+ " 'o:id': 1045,\n",
" 'o:is_public': True,\n",
" 'o:owner': {'@id': 'http://timsherratt.org/collections/api/users/1',\n",
" 'o:id': 1},\n",
@@ -2872,9 +2897,9 @@
" 'o:thumbnail': None,\n",
" 'o:title': 'The Bendigo Independent (Vic. : 1891 - 1918)',\n",
" 'thumbnail_display_urls': {'large': None, 'medium': None, 'square': None},\n",
- " 'o:created': {'@value': '2022-04-03T06:44:57+00:00',\n",
+ " 'o:created': {'@value': '2022-04-04T00:48:33+00:00',\n",
" '@type': 'http://www.w3.org/2001/XMLSchema#dateTime'},\n",
- " 'o:modified': {'@value': '2022-04-03T06:44:57+00:00',\n",
+ " 'o:modified': {'@value': '2022-04-04T00:48:33+00:00',\n",
" '@type': 'http://www.w3.org/2001/XMLSchema#dateTime'},\n",
" 'o:media': [],\n",
" 'o:item_set': [],\n",
@@ -3085,8 +3110,8 @@
" '@value': \"MR WRAGGE'S PREDICTION. RENEWAL OF CYCLONE FORETOLD.\"}],\n",
" 'schema:isPartOf': [{'property_id': 736,\n",
" 'type': 'resource:item',\n",
- " '@id': 'http://timsherratt.org/collections/api/items/999',\n",
- " 'value_resource_id': 999,\n",
+ " '@id': 'http://timsherratt.org/collections/api/items/1045',\n",
+ " 'value_resource_id': 1045,\n",
" 'value_resource_name': 'items'}],\n",
" 'schema:datePublished': [{'property_id': 928,\n",
" 'type': 'numeric:timestamp',\n",
@@ -3142,9 +3167,9 @@
"data": {
"text/plain": [
"{'@context': 'http://timsherratt.org/collections/api-context',\n",
- " '@id': 'http://timsherratt.org/collections/api/items/1000',\n",
+ " '@id': 'http://timsherratt.org/collections/api/items/1046',\n",
" '@type': ['o:Item', 'schema:NewsArticle'],\n",
- " 'o:id': 1000,\n",
+ " 'o:id': 1046,\n",
" 'o:is_public': True,\n",
" 'o:owner': {'@id': 'http://timsherratt.org/collections/api/users/1',\n",
" 'o:id': 1},\n",
@@ -3154,15 +3179,15 @@
" 'o:id': 4},\n",
" 'o:thumbnail': None,\n",
" 'o:title': \"MR WRAGGE'S PREDICTION. RENEWAL OF CYCLONE FORETOLD.\",\n",
- " 'thumbnail_display_urls': {'large': 'http://timsherratt.org/collections/files/large/4ad01b874e1d7f94c659638f681b93287b231263.jpg',\n",
- " 'medium': 'http://timsherratt.org/collections/files/medium/4ad01b874e1d7f94c659638f681b93287b231263.jpg',\n",
- " 'square': 'http://timsherratt.org/collections/files/square/4ad01b874e1d7f94c659638f681b93287b231263.jpg'},\n",
- " 'o:created': {'@value': '2022-04-03T06:45:04+00:00',\n",
+ " 'thumbnail_display_urls': {'large': 'http://timsherratt.org/collections/files/large/c60918ee88cb729ae8803742bbbb185460700903.jpg',\n",
+ " 'medium': 'http://timsherratt.org/collections/files/medium/c60918ee88cb729ae8803742bbbb185460700903.jpg',\n",
+ " 'square': 'http://timsherratt.org/collections/files/square/c60918ee88cb729ae8803742bbbb185460700903.jpg'},\n",
+ " 'o:created': {'@value': '2022-04-04T00:48:40+00:00',\n",
" '@type': 'http://www.w3.org/2001/XMLSchema#dateTime'},\n",
- " 'o:modified': {'@value': '2022-04-03T06:45:04+00:00',\n",
+ " 'o:modified': {'@value': '2022-04-04T00:48:40+00:00',\n",
" '@type': 'http://www.w3.org/2001/XMLSchema#dateTime'},\n",
- " 'o:media': [{'@id': 'http://timsherratt.org/collections/api/media/1001',\n",
- " 'o:id': 1001}],\n",
+ " 'o:media': [{'@id': 'http://timsherratt.org/collections/api/media/1047',\n",
+ " 'o:id': 1047}],\n",
" 'o:item_set': [],\n",
" 'o:site': [],\n",
" 'schema:name': [{'type': 'literal',\n",
@@ -3180,8 +3205,8 @@
" 'property_id': 736,\n",
" 'property_label': 'isPartOf',\n",
" 'is_public': True,\n",
- " '@id': 'http://timsherratt.org/collections/api/items/999',\n",
- " 'value_resource_id': 999,\n",
+ " '@id': 'http://timsherratt.org/collections/api/items/1045',\n",
+ " 'value_resource_id': 1045,\n",
" 'value_resource_name': 'items',\n",
" 'url': None,\n",
" 'display_title': 'The Bendigo Independent (Vic. : 1891 - 1918)'}],\n",
diff --git a/docs/api.html b/docs/api.html
index 0b5cefd..2bddd8c 100644
--- a/docs/api.html
+++ b/docs/api.html
@@ -119,7 +119,7 @@ OmekaAPIClient.get_resources
[source]+
OmekaAPIClient.get_resources
(resource_type
, **kwargs
)
OmekaAPIClient.get_resources
[source]
OmekaAPIClient.get_resources
(resource_type
, **kwargs
)Get a list of resources matching the supplied parameters. This will return the first page of matching results. To retrieve additional pages, @@ -168,7 +168,7 @@
OmekaAPIClient.ge
@@ -226,7 +226,7 @@
OmekaAPIClient.ge