-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
- Loading branch information
1 parent
3d10607
commit 661909f
Showing
16 changed files
with
10,349 additions
and
10,349 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,187 +1,187 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "edcc1fd6-2474-4d15-8355-084ef85bc748", | ||
"metadata": {}, | ||
"source": [ | ||
"# Operations development" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "e191786a-786a-418e-886a-a4da0c2d741e", | ||
"metadata": {}, | ||
"source": [ | ||
"SimPhoNy operations are actions (written in Python) that can be executed on\n", | ||
"demand on any ontology individual belonging to the ontology class they\n", | ||
"are defined for." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "7ea449f9-bc08-4ddc-a8a8-13c6d3ade2ef", | ||
"metadata": {}, | ||
"source": [ | ||
"<div class=\"admonition important\">\n", | ||
"<div class=\"admonition-title\" style=\"font-weight: bold\"><div style=\"display: inline-block\">Tip</div></div>\n", | ||
" \n", | ||
"File uploads and downloads in SimPhoNy are an example of SimPhoNy operations.\n", | ||
"Head to the [assertional knowledge](../usage/assertional_knowledge.html#Operations) section to see them in action.\n", | ||
" \n", | ||
"</div>" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "ee275d73-f2ef-4418-bc94-cec8458c803c", | ||
"metadata": {}, | ||
"source": [ | ||
"\n", | ||
"SimPhoNy operations are distributed as (or as part of) Python packages. \n", | ||
"Developing operations for an ontology class is fairly simple. To do so, import the [Operations abstract class](../api_reference.md#simphony_osp.development.Operations) from the `simphony_osp.development` module, and create an implementation by subclassing it.\n", | ||
"\n", | ||
"Then, define an `iri` attribute having as value the IRI of the ontology class that the\n", | ||
"operation should be associated to. Every public method ([not starting with\n", | ||
"an underscore](https://peps.python.org/pep-0008/#method-names-and-instance-variables)) defined on the implementation is automatically detected and\n", | ||
"assigned as an operation to said ontology class. The\n", | ||
"[ontology individual object](../usage/assertional_knowledge.ipynb#Ontology-individual-objects)\n", | ||
"on which the operation is called is available as the private attribute\n", | ||
"`_individual` on every instance of the implementation. For a specific \n", | ||
"ontology individual, the implementation gets instantiated the first time that \n", | ||
"any operation defined on it is called by the user.\n", | ||
"\n", | ||
"Finally, define an\n", | ||
"[entry point](https://packaging.python.org/en/latest/specifications/entry-points/#entry-points-specification)\n", | ||
"(or many if implementing operations for several ontology classes) under the\n", | ||
"`simphony_osp.ontology.operations`\n", | ||
"[group](https://packaging.python.org/en/latest/specifications/entry-points/#data-model)\n", | ||
"that points to your\n", | ||
"implementation of the `Operations` abstract class.\n", | ||
"\n", | ||
"An example implementation of an operation that takes advantage of\n", | ||
"[geopy](https://pypi.org/project/geopy/) to compute the distance between \n", | ||
"two points on Earth defined using the \n", | ||
"[WGS84 Geo Positioning vocabulary](https://www.w3.org/2003/01/geo/wgs84_pos)\n", | ||
"is shown below." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "0fffa052-186a-46b7-9076-8acfed6b1ee0", | ||
"metadata": {}, | ||
"source": [ | ||
"```python\n", | ||
"\"\"\"Operations for classes from the WGS84 Geo Positioning vocabulary.\"\"\"\n", | ||
"\n", | ||
"from geopy import distance\n", | ||
"from simphony_osp.namespaces import wgs84_pos\n", | ||
"from simphony_osp.ontology import OntologyIndividual\n", | ||
"from simphony_osp.ontology.operations import Operations\n", | ||
"\n", | ||
"\n", | ||
"class Wgs84Pos(Operations):\n", | ||
" \"\"\"Operations for the Point ontology class.\"\"\"\n", | ||
"\n", | ||
" iri = wgs84_pos.Point.iri\n", | ||
"\n", | ||
" def distance(self, other: OntologyIndividual) -> float:\n", | ||
" \"\"\"Compute the distance between two points on Earth.\n", | ||
" \n", | ||
" Args:\n", | ||
" other: Another point with respect to which the distance will be computed. \n", | ||
" \n", | ||
" Returns:\n", | ||
" The distance between this point and the given one in km.\n", | ||
" \"\"\"\n", | ||
" lat_self = float(self._individual[wgs84_pos.latitude].one())\n", | ||
" long_self = float(self._individual[wgs84_pos.longitude].one())\n", | ||
" lat_other = float(other[wgs84_pos.latitude].one())\n", | ||
" long_other = float(other[wgs84_pos.longitude].one())\n", | ||
" return distance.geodesic(\n", | ||
" (lat_self, long_self),\n", | ||
" (lat_other, long_other),\n", | ||
" ellipsoid=\"WGS-84\"\n", | ||
" ).km\n", | ||
"\n", | ||
"```" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "744e037f-aabe-4bdf-a994-8787f3f039b1", | ||
"metadata": {}, | ||
"source": [ | ||
"<div class=\"admonition note\">\n", | ||
"<div class=\"admonition-title\" style=\"font-weight: bold\"><div style=\"display: inline-block\">Note</div></div>\n", | ||
" \n", | ||
"Remember that the implementation above is still not enough for the operation to\n", | ||
"work: the corresponding \n", | ||
"[entry point](https://packaging.python.org/en/latest/specifications/entry-points/#entry-points-specification)\n", | ||
"for `Wgs84Pos` must have been defined and the `wgs84_pos` vocabulary needs to be installed using [pico](../usage/ontologies/pico.html).\n", | ||
" \n", | ||
"</div>" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "d3db93d6-e26f-4831-b9a2-d9223cc4a51f", | ||
"metadata": {}, | ||
"source": [ | ||
"The operation can be used as follows." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"id": "40a97048-80ea-4d99-8711-3ecd6ab5598b", | ||
"metadata": {}, | ||
"outputs": [ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "edcc1fd6-2474-4d15-8355-084ef85bc748", | ||
"metadata": {}, | ||
"source": [ | ||
"# Operations development" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "e191786a-786a-418e-886a-a4da0c2d741e", | ||
"metadata": {}, | ||
"source": [ | ||
"SimPhoNy operations are actions (written in Python) that can be executed on\n", | ||
"demand on any ontology individual belonging to the ontology class they\n", | ||
"are defined for." | ||
] | ||
}, | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"417.4695920611045" | ||
"cell_type": "markdown", | ||
"id": "7ea449f9-bc08-4ddc-a8a8-13c6d3ade2ef", | ||
"metadata": {}, | ||
"source": [ | ||
"<div class=\"admonition important\">\n", | ||
"<div class=\"admonition-title\" style=\"font-weight: bold\"><div style=\"display: inline-block\">Tip</div></div>\n", | ||
" \n", | ||
"File uploads and downloads in SimPhoNy are an example of SimPhoNy operations.\n", | ||
"Head to the [assertional knowledge](../usage/assertional_knowledge.html#Operations) section to see them in action.\n", | ||
" \n", | ||
"</div>" | ||
] | ||
}, | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "ee275d73-f2ef-4418-bc94-cec8458c803c", | ||
"metadata": {}, | ||
"source": [ | ||
"\n", | ||
"SimPhoNy operations are distributed as (or as part of) Python packages. \n", | ||
"Developing operations for an ontology class is fairly simple. To do so, import the [Operations abstract class](../api_reference.md#simphony_osp.development.Operations) from the `simphony_osp.development` module, and create an implementation by subclassing it.\n", | ||
"\n", | ||
"Then, define an `iri` attribute having as value the IRI of the ontology class that the\n", | ||
"operation should be associated to. Every public method ([not starting with\n", | ||
"an underscore](https://peps.python.org/pep-0008/#method-names-and-instance-variables)) defined on the implementation is automatically detected and\n", | ||
"assigned as an operation to said ontology class. The\n", | ||
"[ontology individual object](../usage/assertional_knowledge.ipynb#Ontology-individual-objects)\n", | ||
"on which the operation is called is available as the private attribute\n", | ||
"`_individual` on every instance of the implementation. For a specific \n", | ||
"ontology individual, the implementation gets instantiated the first time that \n", | ||
"any operation defined on it is called by the user.\n", | ||
"\n", | ||
"Finally, define an\n", | ||
"[entry point](https://packaging.python.org/en/latest/specifications/entry-points/#entry-points-specification)\n", | ||
"(or many if implementing operations for several ontology classes) under the\n", | ||
"`simphony_osp.ontology.operations`\n", | ||
"[group](https://packaging.python.org/en/latest/specifications/entry-points/#data-model)\n", | ||
"that points to your\n", | ||
"implementation of the `Operations` abstract class.\n", | ||
"\n", | ||
"An example implementation of an operation that takes advantage of\n", | ||
"[geopy](https://pypi.org/project/geopy/) to compute the distance between \n", | ||
"two points on Earth defined using the \n", | ||
"[WGS84 Geo Positioning vocabulary](https://www.w3.org/2003/01/geo/wgs84_pos)\n", | ||
"is shown below." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "0fffa052-186a-46b7-9076-8acfed6b1ee0", | ||
"metadata": {}, | ||
"source": [ | ||
"```python\n", | ||
"\"\"\"Operations for classes from the WGS84 Geo Positioning vocabulary.\"\"\"\n", | ||
"\n", | ||
"from geopy import distance\n", | ||
"from simphony_osp.namespaces import wgs84_pos\n", | ||
"from simphony_osp.ontology import OntologyIndividual\n", | ||
"from simphony_osp.ontology.operations import Operations\n", | ||
"\n", | ||
"\n", | ||
"class Wgs84Pos(Operations):\n", | ||
" \"\"\"Operations for the Point ontology class.\"\"\"\n", | ||
"\n", | ||
" iri = wgs84_pos.Point.iri\n", | ||
"\n", | ||
" def distance(self, other: OntologyIndividual) -> float:\n", | ||
" \"\"\"Compute the distance between two points on Earth.\n", | ||
" \n", | ||
" Args:\n", | ||
" other: Another point with respect to which the distance will be computed. \n", | ||
" \n", | ||
" Returns:\n", | ||
" The distance between this point and the given one in km.\n", | ||
" \"\"\"\n", | ||
" lat_self = float(self._individual[wgs84_pos.latitude].one())\n", | ||
" long_self = float(self._individual[wgs84_pos.longitude].one())\n", | ||
" lat_other = float(other[wgs84_pos.latitude].one())\n", | ||
" long_other = float(other[wgs84_pos.longitude].one())\n", | ||
" return distance.geodesic(\n", | ||
" (lat_self, long_self),\n", | ||
" (lat_other, long_other),\n", | ||
" ellipsoid=\"WGS-84\"\n", | ||
" ).km\n", | ||
"\n", | ||
"```" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "744e037f-aabe-4bdf-a994-8787f3f039b1", | ||
"metadata": {}, | ||
"source": [ | ||
"<div class=\"admonition note\">\n", | ||
"<div class=\"admonition-title\" style=\"font-weight: bold\"><div style=\"display: inline-block\">Note</div></div>\n", | ||
" \n", | ||
"Remember that the implementation above is still not enough for the operation to\n", | ||
"work: the corresponding \n", | ||
"[entry point](https://packaging.python.org/en/latest/specifications/entry-points/#entry-points-specification)\n", | ||
"for `Wgs84Pos` must have been defined and the `wgs84_pos` vocabulary needs to be installed using [pico](../usage/ontologies/pico.html).\n", | ||
" \n", | ||
"</div>" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "d3db93d6-e26f-4831-b9a2-d9223cc4a51f", | ||
"metadata": {}, | ||
"source": [ | ||
"The operation can be used as follows." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"id": "40a97048-80ea-4d99-8711-3ecd6ab5598b", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"data": { | ||
"text/plain": [ | ||
"417.4695920611045" | ||
] | ||
}, | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"output_type": "execute_result" | ||
} | ||
], | ||
"source": [ | ||
"from simphony_osp.namespaces import wgs84_pos\n", | ||
"\n", | ||
"location_freiburg = wgs84_pos.Point()\n", | ||
"location_freiburg[wgs84_pos.latitude] = 47.997791\n", | ||
"location_freiburg[wgs84_pos.longitude] = 7.842609\n", | ||
"\n", | ||
"location_paris = wgs84_pos.Point()\n", | ||
"location_paris[wgs84_pos.latitude] = 48.85333\n", | ||
"location_paris[wgs84_pos.longitude] = 2.34885\n", | ||
"\n", | ||
"location_freiburg.operations.distance(location_paris)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.8.12" | ||
} | ||
], | ||
"source": [ | ||
"from simphony_osp.namespaces import wgs84_pos\n", | ||
"\n", | ||
"location_freiburg = wgs84_pos.Point()\n", | ||
"location_freiburg[wgs84_pos.latitude] = 47.997791\n", | ||
"location_freiburg[wgs84_pos.longitude] = 7.842609\n", | ||
"\n", | ||
"location_paris = wgs84_pos.Point()\n", | ||
"location_paris[wgs84_pos.latitude] = 48.85333\n", | ||
"location_paris[wgs84_pos.longitude] = 2.34885\n", | ||
"\n", | ||
"location_freiburg.operations.distance(location_paris)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.8.12" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
Oops, something went wrong.