# museumpy
**museum**py is a client for python to get data from [Zetcom MuseumPlus](https://www.zetcom.com/en/museumplus-en/) instances.
## Table of Contents
* [Installation](#installation)
* [Usage](#usage)
* [`search`](#search)
* [`fulltext_search`](#fulltext_search)
* [Advanced Usage](#advanced-usage)
* [`module_item`](#module_item)
* [`download_attachement`](#download_attachement)
* [Custom mapping of fields](#custom-mapping-of-fields)
* [Release](#release)
## Installation
[museumpy is available on PyPI](https://pypi.org/project/museumpy/), so to install it simply use:
```
$ pip install museumpy
```
## Usage
See the [`examples` directory](/examples) for more scripts.
### `search`
```python
import museumpy
records = museumpy.search(
base_url='https://mpzurichrietberg.zetcom.com/MpWeb-mpZurichRietberg',
field='ObjObjectNumberTxt',
value='2019.184',
)
for record in records:
print(record)
```
The return value of `search` 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 element, or `records[-1]` to get the last one.
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]:
print(record)
```
### `fulltext_search`
```python
import museumpy
records = museumpy.fulltext_search(
base_url='https://test.zetcom.com/MpWeb-mpTest',
query='Patolu',
)
for record in records:
print(record)
```
## Advanced usage
For more advanced usage of this library, it is recommened to first create a client instance and then use this to request data:
```python
import museumpy
import requests
s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'Accept-Language': 'de'})
client = museumpy.MuseumPlusClient(
base_url='https://test.zetcom.com/MpWeb-mpTest',
session=s
)
```
### `module_item`
```python
import museumpy
id = '98977'
module = 'Multimedia'
item = client.module_item(id, module)
```
### `download_attachement`
```python
import museumpy
id = '98977'
module = 'Multimedia'
# download attachment to a directory called `files`
attachment_path = client.download_attachment(id, module, 'files')
print(attachment_path)
```
### Custom mapping of fields
There are most likely custom fields on the MuseumPlus Instance you want to query.
The returned XML is converted to a python `dict` using the [`xmltodict` library](https://pypi.org/project/xmltodict/).
The raw dict is returned on the `raw` key of the result:
```python
import museumpy
records = museumpy.search(
base_url='https://test.zetcom.com/MpWeb-mpTest',
query='Patolu',
)
for record in records:
print(record['raw'])
```
For convenience a default mapping is provided to access some fields more easily:
```python
for record in records:
print(record['hasAttachments'])
print(record['ObjObjectNumberTxt'])
```
If you want to customize this mapping, you can pass a `map_function` to the client, which is then used on all subsequent calls to `search` and `fulltext_search`:
```python
import museumpy
def my_custom_map(record, xml_rec):
NS = "http://www.zetcom.com/ria/ws/module"
ID_XPATH = f".//{{{NS}}}dataField[@name='ObjObjectNumberTxt']/{{{NS}}}value"
TITLE_XPATH = f".//{{{NS}}}repeatableGroup[@name='ObjObjectTitleGrp']//{{{NS}}}dataField[@name='TitleTxt']//{{{NS}}}value"
xml_parser = museumpy.xmlparse.XMLParser()
my_new_record = {
'my_id': xml_parser.find(xml_rec, ID_XPATH).text,
'my_title': xml_parser.find(xml_rec, TITLE_XPATH).text
}
return my_new_record
client = museumpy.MuseumPlusClient(
base_url='https://test.zetcom.com/MpWeb-mpTest',
map_function=my_custom_map,
)
records = client.search(
base_url='https://test.zetcom.com/MpWeb-mpTest',
query='Patolu',
)
for record in records:
print(record['my_id'])
print(record['my_title'])
```
## Release
To create a new release, follow these steps (please respect [Semantic Versioning](http://semver.org/)):
1. Adapt the version number in `museumpy/__init__.py`
1. Update the CHANGELOG with the version
1. Create a [pull request to merge `develop` into `main`](https://github.com/metaodi/museumpy/compare/main...develop?expand=1) (make sure the tests pass!)
1. Create a [new release/tag on GitHub](https://github.com/metaodi/museumpy/releases) (on the main branch)
1. The [publication on PyPI](https://pypi.python.org/pypi/museumpy) happens via [GitHub Actions](https://github.com/metaodi/museumpy/actions?query=workflow%3A%22Upload+Python+Package%22) on every tagged commit
Raw data
{
"_id": null,
"home_page": "https://github.com/metaodi/museumpy",
"name": "museumpy",
"maintainer": "Stefan Oderbolz",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "odi@metaodi.ch",
"keywords": "museumplus,glam,museum,zetcom",
"author": "Stefan Oderbolz",
"author_email": "odi@metaodi.ch",
"download_url": "https://files.pythonhosted.org/packages/b7/a5/78f2b173f4feb4eaa0ea143f9c624e0fdce2262d8c73fb1547618b1dba9b/museumpy-0.4.1.tar.gz",
"platform": null,
"description": "# museumpy\n\n**museum**py is a client for python to get data from [Zetcom MuseumPlus](https://www.zetcom.com/en/museumplus-en/) instances.\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Usage](#usage)\n * [`search`](#search)\n * [`fulltext_search`](#fulltext_search)\n* [Advanced Usage](#advanced-usage)\n * [`module_item`](#module_item)\n * [`download_attachement`](#download_attachement)\n * [Custom mapping of fields](#custom-mapping-of-fields)\n* [Release](#release)\n\n## Installation\n\n[museumpy is available on PyPI](https://pypi.org/project/museumpy/), so to install it simply use:\n\n```\n$ pip install museumpy\n```\n\n## Usage\n\nSee the [`examples` directory](/examples) for more scripts.\n\n### `search`\n\n```python\nimport museumpy\n\nrecords = museumpy.search(\n base_url='https://mpzurichrietberg.zetcom.com/MpWeb-mpZurichRietberg',\n field='ObjObjectNumberTxt',\n value='2019.184',\n)\n\n\nfor record in records:\n print(record)\n```\n\n\nThe return value of `search` 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 element, or `records[-1]` to get the last one.\n\nEven [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\n\n```python\nfor records in records[:5]:\n print(record)\n```\n\n### `fulltext_search`\n```python\nimport museumpy\n\nrecords = museumpy.fulltext_search(\n base_url='https://test.zetcom.com/MpWeb-mpTest',\n query='Patolu',\n)\n\n\nfor record in records:\n print(record)\n```\n\n## Advanced usage\n\nFor more advanced usage of this library, it is recommened to first create a client instance and then use this to request data:\n\n```python\nimport museumpy\nimport requests\n\ns = requests.Session()\ns.auth = ('user', 'pass')\ns.headers.update({'Accept-Language': 'de'})\n\nclient = museumpy.MuseumPlusClient(\n base_url='https://test.zetcom.com/MpWeb-mpTest',\n session=s\n)\n\n```\n\n\n### `module_item`\n```python\nimport museumpy\n\nid = '98977'\nmodule = 'Multimedia'\nitem = client.module_item(id, module)\n```\n\n### `download_attachement`\n```python\nimport museumpy\n\nid = '98977'\nmodule = 'Multimedia'\n# download attachment to a directory called `files`\nattachment_path = client.download_attachment(id, module, 'files')\nprint(attachment_path)\n```\n\n### Custom mapping of fields\n\nThere are most likely custom fields on the MuseumPlus Instance you want to query.\nThe returned XML is converted to a python `dict` using the [`xmltodict` library](https://pypi.org/project/xmltodict/).\nThe raw dict is returned on the `raw` key of the result:\n\n```python\nimport museumpy\n\nrecords = museumpy.search(\n base_url='https://test.zetcom.com/MpWeb-mpTest',\n query='Patolu',\n)\nfor record in records:\n print(record['raw'])\n```\n\nFor convenience a default mapping is provided to access some fields more easily:\n\n\n```python\nfor record in records:\n print(record['hasAttachments'])\n print(record['ObjObjectNumberTxt'])\n```\n\nIf you want to customize this mapping, you can pass a `map_function` to the client, which is then used on all subsequent calls to `search` and `fulltext_search`:\n\n\n```python\nimport museumpy\n\ndef my_custom_map(record, xml_rec):\n NS = \"http://www.zetcom.com/ria/ws/module\"\n ID_XPATH = f\".//{{{NS}}}dataField[@name='ObjObjectNumberTxt']/{{{NS}}}value\"\n TITLE_XPATH = f\".//{{{NS}}}repeatableGroup[@name='ObjObjectTitleGrp']//{{{NS}}}dataField[@name='TitleTxt']//{{{NS}}}value\"\n\n xml_parser = museumpy.xmlparse.XMLParser()\n my_new_record = {\n 'my_id': xml_parser.find(xml_rec, ID_XPATH).text,\n 'my_title': xml_parser.find(xml_rec, TITLE_XPATH).text \n }\n return my_new_record\n\n\nclient = museumpy.MuseumPlusClient(\n base_url='https://test.zetcom.com/MpWeb-mpTest',\n map_function=my_custom_map,\n)\n\nrecords = client.search(\n base_url='https://test.zetcom.com/MpWeb-mpTest',\n query='Patolu',\n)\nfor record in records:\n print(record['my_id'])\n print(record['my_title'])\n\n```\n\n## Release\n\nTo create a new release, follow these steps (please respect [Semantic Versioning](http://semver.org/)):\n\n1. Adapt the version number in `museumpy/__init__.py`\n1. Update the CHANGELOG with the version\n1. Create a [pull request to merge `develop` into `main`](https://github.com/metaodi/museumpy/compare/main...develop?expand=1) (make sure the tests pass!)\n1. Create a [new release/tag on GitHub](https://github.com/metaodi/museumpy/releases) (on the main branch)\n1. The [publication on PyPI](https://pypi.python.org/pypi/museumpy) happens via [GitHub Actions](https://github.com/metaodi/museumpy/actions?query=workflow%3A%22Upload+Python+Package%22) on every tagged commit\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Client for MuseumPlus",
"version": "0.4.1",
"project_urls": {
"Download": "https://github.com/metaodi/museumpy/archive/v0.4.1.zip",
"Homepage": "https://github.com/metaodi/museumpy"
},
"split_keywords": [
"museumplus",
"glam",
"museum",
"zetcom"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6351158f9c77042de22b026647fc330f30916ea0dd488dda9832c4b83d0b18d8",
"md5": "3dcbbc477f002d02daa212964a8feb67",
"sha256": "fd3765ce46dc168916efcb1207105c1026592092fa995457cb8c1883c5ed116f"
},
"downloads": -1,
"filename": "museumpy-0.4.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3dcbbc477f002d02daa212964a8feb67",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 9151,
"upload_time": "2023-06-07T13:27:59",
"upload_time_iso_8601": "2023-06-07T13:27:59.597351Z",
"url": "https://files.pythonhosted.org/packages/63/51/158f9c77042de22b026647fc330f30916ea0dd488dda9832c4b83d0b18d8/museumpy-0.4.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b7a578f2b173f4feb4eaa0ea143f9c624e0fdce2262d8c73fb1547618b1dba9b",
"md5": "c7a3b3eacb0126dbc03c826ed367d6c3",
"sha256": "fd83cc2c1cec1604ff894d204ba7d57eceed303890a66d9f5224f53f20b380b4"
},
"downloads": -1,
"filename": "museumpy-0.4.1.tar.gz",
"has_sig": false,
"md5_digest": "c7a3b3eacb0126dbc03c826ed367d6c3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 10439,
"upload_time": "2023-06-07T13:28:01",
"upload_time_iso_8601": "2023-06-07T13:28:01.548183Z",
"url": "https://files.pythonhosted.org/packages/b7/a5/78f2b173f4feb4eaa0ea143f9c624e0fdce2262d8c73fb1547618b1dba9b/museumpy-0.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-06-07 13:28:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "metaodi",
"github_project": "museumpy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "requests",
"specs": []
},
{
"name": "defusedxml",
"specs": []
},
{
"name": "xmltodict",
"specs": []
},
{
"name": "python-dotenv",
"specs": []
}
],
"lcname": "museumpy"
}