cap-tools


Namecap-tools JSON
Version 3.1.1 PyPI version JSON
download
home_pagehttps://github.com/bjoern-reetz/cap-tools
SummaryPython data bindings for the Common Alerting Protocol Version.
upload_time2024-08-04 11:26:29
maintainerNone
docs_urlNone
authorBjörn Reetz
requires_python<4.0,>=3.10
licenseMIT
keywords cap common alerting protocol read write tool util
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # CAP-Tools

[![pipeline status](https://github.com/bjoern-reetz/cap-tools/actions/workflows/publish.yml/badge.svg?main)](https://github.com/bjoern-reetz/cap-tools/actions/workflows/publish.yml)
[![latest package version](https://img.shields.io/pypi/v/cap-tools)](https://pypi.org/project/cap-tools/)
[![supported python versions](https://img.shields.io/pypi/pyversions/cap-tools)](https://www.python.org/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/cap-tools)](https://pypistats.org/packages/cap-tools)
[![license](./images/license.svg)](./LICENSE)
[![source files coverage](./images/coverage.svg)](https://coverage.readthedocs.io/)
[![pyright](./images/pyright.svg)](https://microsoft.github.io/pyright)
[![ruff](./images/ruff.svg)](https://docs.astral.sh/ruff)
[![pre-commit](./images/pre-commit.svg)](https://pre-commit.com/)

Python data bindings for the [Common Alerting Protocol Version 1.2](https://docs.oasis-open.org/emergency/cap/v1.2/CAP-v1.2.html).

## Getting started

This package contains a Python model for CAP XML documents that was generated using using [xsData](https://xsdata.readthedocs.io/) along with some convenience utilities.

To parse a CAP XML from a file into an instance of `cap_tools.models.Alert`, do as follows:

```python
from cap_tools.models import Alert
from xsdata.formats.dataclass.parsers import XmlParser

parser = XmlParser()
alert = parser.parse("path/to/my/cap.xml", Alert)
```

For advanced usage, just take a look at the [xsData](https://xsdata.readthedocs.io/en/latest/data_binding/basics/) docs.

### Convenience utilities

In addition to the code that was generated using xsData, this library adds some convenience utilities on top.

#### Transforming the system-specific key-value-pairs to mappings

The `Info.parameters`, `Info.event_codes` and `Area.geocode` fields generated by xsData are implemented as a list of (containers of) key-value-pairs.

```python
>>> import cap_tools
>>> from xsdata.formats.dataclass.parsers import XmlParser
>>> parser = XmlParser()
>>> alert = parser.parse("data/oasis/example2.xml")
>>> area = alert.infos[0].areas[0]
>>> area.geocodes
[Geocode(value_name=ValueName(value='SAME'), value=Value(value='006109')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='006009')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='006003'))]
```

This can more ergonomically be represented using a mapping. Use the `Info.parameters_to_dict`, `Info.event_codes_to_dict` and `Area.geocode_to_dict` methods to create instances of [MultiDict](https://multidict.aio-libs.org/en/stable/) from the data.

```python
>>> geocodes_multidict = area.geocodes_to_dict()
>>> geocodes_multidict
<MultiDict('SAME': '006109', 'SAME': '006009', 'SAME': '006003')>
>>> geocodes_multidict["SAME"]
'006109'
>>> geocodes_multidict.getall("SAME")
['006109', '006009', '006003']
```

Remember that `MultiDict.__getitem__()` uses the *first* occurence of the key while a `dict` would have used the *last* because of its overwrite rules.

You can also write any mapping to the instance fields using the `Info.parameters_from_dict`, `Info.event_codes_from_dict` and `Area.geocode_from_dict` methods.

Use the `MultiDict`:

```python
>>> geocodes_multidict.add("SAME", "123456")
>>> area.geocodes_from_dict(geocodes_multidict)
>>> area.geocodes
[Geocode(value_name=ValueName(value='SAME'), value=Value(value='006109')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='006009')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='006003')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='123456'))]
```

Or use a `dict`:

```python
>>> area.geocodes_from_dict({"foo": "bar", "lorem": "ipsum"})
>>> area.geocodes
[Geocode(value_name=ValueName(value='foo'), value=Value(value='bar')), Geocode(value_name=ValueName(value='lorem'), value=Value(value='ipsum'))]
```

The MultiDicts do not retain any connection to the model. In all cases, the internal state is always represented by the list of containers of key-value-pairs.

#### Splitting group listings

The attributes `addresses`, `references` and `incidents` of `Alert` store multiple values as "group listings", i.e. multiple values are space-delimited. You can split these attributes by using `Alert.addresses_to_list()`, `Alert.references_to_list()` and `Alert.incidents_to_list()` and write back to them with corresponding `Alert.*_from_list()` methods respectively.

#### Awareness of "en-US" as the default language

When no language is explicitly defined on an Info element, "en-US" is assumed per CAP spec. This library implements this behavior neither by using default values nor by using descriptor fields.

```python
>>> alert.infos[0].language = "en-US"
>>> alert.infos[0].language
'en-US'
>>> alert.infos[0].language = None
>>> alert.infos[0].language is None
True
>>> alert.infos[0].language == "en-US"
False
```

To still have this "absence means en-US" logic implemented, two convenience methods are added to Info.

```python
>>> alert.infos[0].set_language("de-DE")
>>> alert.infos[0].language
'de-DE'
>>> alert.infos[0].set_language("en-US")
>>> alert.infos[0].language is None
True
>>> alert.infos[0].get_language()
'en-US'
```

Using `Info.get_language()` returns `"en-US"` when `Info.language` is `None` and `Info.set_language("en-US")` sets `Info.language` to `None` (implicitly "en-US") instead of `"en-US"` (explicitly).

## Limitations

While this library is fully typed to enable Python type safety, it currently does neither implement the pattern restrictions from the [CAP v1.2 XSD specification](./CAP-v1.2.xsd) (i.e. the pattern restriction for the XmlDateTime fields) nor the additional restrictions imposed by the [normative alert message structure](https://docs.oasis-open.org/emergency/cap/v1.2/CAP-v1.2.html#_Toc454352650) (e.g. Alert.identifier must not include spaces, commas or the characters "<" and "&").

This does not matter much when using this library for reading CAP messages - but when you are using this library to create CAP messages, **you are responsible** for respecting those additional restrictions yourself!


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/bjoern-reetz/cap-tools",
    "name": "cap-tools",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.10",
    "maintainer_email": null,
    "keywords": "cap, common alerting protocol, read, write, tool, util",
    "author": "Bj\u00f6rn Reetz",
    "author_email": "git@bjoern-reetz.de",
    "download_url": "https://files.pythonhosted.org/packages/a5/36/5bc4752ff211b9ff5cc3af9434017fc729fac295c8fb98e1a0b851b82b66/cap_tools-3.1.1.tar.gz",
    "platform": null,
    "description": "# CAP-Tools\n\n[![pipeline status](https://github.com/bjoern-reetz/cap-tools/actions/workflows/publish.yml/badge.svg?main)](https://github.com/bjoern-reetz/cap-tools/actions/workflows/publish.yml)\n[![latest package version](https://img.shields.io/pypi/v/cap-tools)](https://pypi.org/project/cap-tools/)\n[![supported python versions](https://img.shields.io/pypi/pyversions/cap-tools)](https://www.python.org/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/cap-tools)](https://pypistats.org/packages/cap-tools)\n[![license](./images/license.svg)](./LICENSE)\n[![source files coverage](./images/coverage.svg)](https://coverage.readthedocs.io/)\n[![pyright](./images/pyright.svg)](https://microsoft.github.io/pyright)\n[![ruff](./images/ruff.svg)](https://docs.astral.sh/ruff)\n[![pre-commit](./images/pre-commit.svg)](https://pre-commit.com/)\n\nPython data bindings for the [Common Alerting Protocol Version 1.2](https://docs.oasis-open.org/emergency/cap/v1.2/CAP-v1.2.html).\n\n## Getting started\n\nThis package contains a Python model for CAP XML documents that was generated using using [xsData](https://xsdata.readthedocs.io/) along with some convenience utilities.\n\nTo parse a CAP XML from a file into an instance of `cap_tools.models.Alert`, do as follows:\n\n```python\nfrom cap_tools.models import Alert\nfrom xsdata.formats.dataclass.parsers import XmlParser\n\nparser = XmlParser()\nalert = parser.parse(\"path/to/my/cap.xml\", Alert)\n```\n\nFor advanced usage, just take a look at the [xsData](https://xsdata.readthedocs.io/en/latest/data_binding/basics/) docs.\n\n### Convenience utilities\n\nIn addition to the code that was generated using xsData, this library adds some convenience utilities on top.\n\n#### Transforming the system-specific key-value-pairs to mappings\n\nThe `Info.parameters`, `Info.event_codes` and `Area.geocode` fields generated by xsData are implemented as a list of (containers of) key-value-pairs.\n\n```python\n>>> import cap_tools\n>>> from xsdata.formats.dataclass.parsers import XmlParser\n>>> parser = XmlParser()\n>>> alert = parser.parse(\"data/oasis/example2.xml\")\n>>> area = alert.infos[0].areas[0]\n>>> area.geocodes\n[Geocode(value_name=ValueName(value='SAME'), value=Value(value='006109')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='006009')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='006003'))]\n```\n\nThis can more ergonomically be represented using a mapping. Use the `Info.parameters_to_dict`, `Info.event_codes_to_dict` and `Area.geocode_to_dict` methods to create instances of [MultiDict](https://multidict.aio-libs.org/en/stable/) from the data.\n\n```python\n>>> geocodes_multidict = area.geocodes_to_dict()\n>>> geocodes_multidict\n<MultiDict('SAME': '006109', 'SAME': '006009', 'SAME': '006003')>\n>>> geocodes_multidict[\"SAME\"]\n'006109'\n>>> geocodes_multidict.getall(\"SAME\")\n['006109', '006009', '006003']\n```\n\nRemember that `MultiDict.__getitem__()` uses the *first* occurence of the key while a `dict` would have used the *last* because of its overwrite rules.\n\nYou can also write any mapping to the instance fields using the `Info.parameters_from_dict`, `Info.event_codes_from_dict` and `Area.geocode_from_dict` methods.\n\nUse the `MultiDict`:\n\n```python\n>>> geocodes_multidict.add(\"SAME\", \"123456\")\n>>> area.geocodes_from_dict(geocodes_multidict)\n>>> area.geocodes\n[Geocode(value_name=ValueName(value='SAME'), value=Value(value='006109')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='006009')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='006003')), Geocode(value_name=ValueName(value='SAME'), value=Value(value='123456'))]\n```\n\nOr use a `dict`:\n\n```python\n>>> area.geocodes_from_dict({\"foo\": \"bar\", \"lorem\": \"ipsum\"})\n>>> area.geocodes\n[Geocode(value_name=ValueName(value='foo'), value=Value(value='bar')), Geocode(value_name=ValueName(value='lorem'), value=Value(value='ipsum'))]\n```\n\nThe MultiDicts do not retain any connection to the model. In all cases, the internal state is always represented by the list of containers of key-value-pairs.\n\n#### Splitting group listings\n\nThe attributes `addresses`, `references` and `incidents` of `Alert` store multiple values as \"group listings\", i.e. multiple values are space-delimited. You can split these attributes by using `Alert.addresses_to_list()`, `Alert.references_to_list()` and `Alert.incidents_to_list()` and write back to them with corresponding `Alert.*_from_list()` methods respectively.\n\n#### Awareness of \"en-US\" as the default language\n\nWhen no language is explicitly defined on an Info element, \"en-US\" is assumed per CAP spec. This library implements this behavior neither by using default values nor by using descriptor fields.\n\n```python\n>>> alert.infos[0].language = \"en-US\"\n>>> alert.infos[0].language\n'en-US'\n>>> alert.infos[0].language = None\n>>> alert.infos[0].language is None\nTrue\n>>> alert.infos[0].language == \"en-US\"\nFalse\n```\n\nTo still have this \"absence means en-US\" logic implemented, two convenience methods are added to Info.\n\n```python\n>>> alert.infos[0].set_language(\"de-DE\")\n>>> alert.infos[0].language\n'de-DE'\n>>> alert.infos[0].set_language(\"en-US\")\n>>> alert.infos[0].language is None\nTrue\n>>> alert.infos[0].get_language()\n'en-US'\n```\n\nUsing `Info.get_language()` returns `\"en-US\"` when `Info.language` is `None` and `Info.set_language(\"en-US\")` sets `Info.language` to `None` (implicitly \"en-US\") instead of `\"en-US\"` (explicitly).\n\n## Limitations\n\nWhile this library is fully typed to enable Python type safety, it currently does neither implement the pattern restrictions from the [CAP v1.2 XSD specification](./CAP-v1.2.xsd) (i.e. the pattern restriction for the XmlDateTime fields) nor the additional restrictions imposed by the [normative alert message structure](https://docs.oasis-open.org/emergency/cap/v1.2/CAP-v1.2.html#_Toc454352650) (e.g. Alert.identifier must not include spaces, commas or the characters \"<\" and \"&\").\n\nThis does not matter much when using this library for reading CAP messages - but when you are using this library to create CAP messages, **you are responsible** for respecting those additional restrictions yourself!\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python data bindings for the Common Alerting Protocol Version.",
    "version": "3.1.1",
    "project_urls": {
        "Documentation": "https://github.com/bjoern-reetz/cap-tools",
        "Homepage": "https://github.com/bjoern-reetz/cap-tools",
        "Repository": "https://github.com/bjoern-reetz/cap-tools"
    },
    "split_keywords": [
        "cap",
        " common alerting protocol",
        " read",
        " write",
        " tool",
        " util"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1c8284f7d0fdec52ce7f0206bae76b3b05d5910629a73a17ea630b335dd6c1d8",
                "md5": "fa7235b83fe08c64355439d852b60003",
                "sha256": "6dc93d6b38408862ab901a7b67d038e1688cfef603ba9cc0d78db26c3b590dae"
            },
            "downloads": -1,
            "filename": "cap_tools-3.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "fa7235b83fe08c64355439d852b60003",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.10",
            "size": 8149,
            "upload_time": "2024-08-04T11:26:27",
            "upload_time_iso_8601": "2024-08-04T11:26:27.966109Z",
            "url": "https://files.pythonhosted.org/packages/1c/82/84f7d0fdec52ce7f0206bae76b3b05d5910629a73a17ea630b335dd6c1d8/cap_tools-3.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a5365bc4752ff211b9ff5cc3af9434017fc729fac295c8fb98e1a0b851b82b66",
                "md5": "ec4f55e3cd8ca232f1ddb2a402cb07c2",
                "sha256": "315e6edd80637f4e817783c900def7a44fd2aa4bda23e438742a64d18016d1f5"
            },
            "downloads": -1,
            "filename": "cap_tools-3.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "ec4f55e3cd8ca232f1ddb2a402cb07c2",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.10",
            "size": 9965,
            "upload_time": "2024-08-04T11:26:29",
            "upload_time_iso_8601": "2024-08-04T11:26:29.456535Z",
            "url": "https://files.pythonhosted.org/packages/a5/36/5bc4752ff211b9ff5cc3af9434017fc729fac295c8fb98e1a0b851b82b66/cap_tools-3.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-04 11:26:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "bjoern-reetz",
    "github_project": "cap-tools",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "cap-tools"
}
        
Elapsed time: 0.29524s