{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# ibmpairs SDK" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Overview\n", "\n", "The ibmpairs SDK is a python module that can be used to interact with the Geospatial APIs component of the IBM Environmental Intelligence (EI). \n", "\n", "The wrapper is available to download from [PyPI](https://pypi.org/project/ibmpairs/).\n", "\n", "### Layout and Versions\n", "\n", "There are two versions of ibmpairs implemented across the various sub-modules that make up this SDK.\n", "\n", "The legacy sub-modules called `paw` and `utils` only support query operations. These sub-modules are retained to maintain backward compatibility for those still using it. \n", "\n", "
\n", "The `paw` and `utils` sub-modules will be deprecated at some point in the future, \n", "so if you are new to Geospatial APIs use the new sub-modules instead. \n", "
\n", "\n", "Version 3.0.0 is embodied in all of the other sub-modules. The query function of the legacy sub-modules was improved and separated into a sub-module called `query` and various other modules were added to give more complete coverage of the Geospatial APIs. \n", "\n", "| Sub-module | PAW Version | Description |\n", "| :----- | :--------------- | :---------- |\n", "| paw | 0.1.x | version 0.1.x of the library |\n", "| utils | 0.1.x | a utility package for paw |\n", "|authentication | 3.0.0 + |sign in |\n", "| catalog | 3.0.0 + |allow an authorized Geospatial APIs user to perform get, create, update, delete operations on Geospatial APIs Data Sets, Data Layers, Data Layer Dimensions & Properties |\n", "| client | 3.0.0 + |a common HTTP client for Geospatial APIs which understands authentication from the module above |\n", "| query | 3.0.0 + |creation, submission, monitoring and download of Geospatial APIs queries and subsequent query data files. In addition, this module contains helper functions that allow for the retrieval of recent and favourite flagged queries and more |\n", "| external/ibm | 3.0.0 + |interact with IBM COS (used by upload) |\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Model\n", "\n", "The ibmpairs SDK wraps the Geospatial APIs server side HTTP API. The wrapper has been designed using a small number of patterns. \n", "\n", "At a very high level this is how it works:\n", "\n", "```bash\n", "Client Side Object <-------> Server Side Geospatial APIs\n", "|\n", "|-> Data Objects\n", "```\n", "\n", "i.e. Each client side object, such as Query or Catalog, wraps the server side Query and Catalog APIs. Data objects on the client side allow the data and parameters of the API calls to be provided without having to worry about the technical implementation of the API, for example, URL encoding. \n", "\n", "## Data Objects\n", "\n", "Generally the client side objects are configured using data objects. Data objects can be expressed using JSON (or a Python dictionary), and inserted into the Geospatial APIs objects with helper functions. e.g.:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "query_dict = {\n", " \"layers\": [\n", " {\n", " \"id\": \"49464\",\n", " \"type\": \"raster\"\n", " }\n", " ],\n", " \"name\": \"Area Query Test\",\n", " \"spatial\": {\n", " \"coordinates\": [\n", " 48.437249,\n", " 2.5735152,\n", " 48.488131,\n", " 2.6838934\n", " ],\n", " \"type\": \"square\"\n", " },\n", " \"temporal\": {\n", " \"intervals\": [\n", " {\n", " \"end\": \"2016-11-08\",\n", " \"start\": \"2016-11-06\"\n", " }\n", " ]\n", " }\n", "}\n", "\n", "q = query.query_from_dict(query_dict)\n", "\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively a data object can be created directly and you can set its attributes individually in the init. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "l = [{\"id\": \"49464\", \"type\": \"raster\"}]\n", "\n", "q = query.Query(name = \"Area Query Test\",\n", " layers = l)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The JSON responses from the Geospatial APIs will be converted to data objects and returned to you automatically.\n", "\n", "If you want to change the data in a data object you can set the object's attributes:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "l = [{\"id\": \"49464\", \"type\": \"raster\"}, {\"id\": \"12345\", \"type\": \"raster\"}]\n", "q.name = \"New Name\"\n", "q.layers = l\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reading from the API\n", "\n", "The wrapper supports a number of different ways of reading data and meta-data from the Geospatial APIs. To read data or meta-data you need to provide its id.\n", "\n", "### Approach 1 - Provide data id as an attribute to get()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "id = '1234'\n", "data_layer = catalog.DataLayer()\n", "data_layer.get(id = id)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Approach 2 - Provide data id by constructing a client side object before calling get()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "id = '1234'\n", "data_layer = catalog.DataLayer(id = id)\n", "data_layer.get()\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Approach 3 - Helper Functions that hide get()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "id = '1234'\n", "data_layer = catalog.get_data_layer(id)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Writing to the API\n", "\n", "The method used to \"write\" data to the Geospatial APIs varies depending on the data object in question. \n", "A data layer is created using a `create` operation and a query is run using a `submit` operation for example.\n", "The wrapper supports a number of different patterns for writing client side objects to the server side:\n", "\n", "### Approach 1 - Provide data by constructing a client side object before calling create()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "data_layer = catalog.DataLayer(crs = \"EPSG:4326\",\n", " datatype = \"bt\",\n", " level = 21,\n", " name = \"a_data_layer_name\"\n", " )\n", "data_layer.create(data_set_id = 1234, \n", " data_layer_type = \"Raster\"\n", " )\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The data_layer object will contact the Geospatial API and have it create the data layer assuming\n", "you are authorized to do that. \n", "\n", "As an alternative to specifying separate fields the data_layer object can be created from JSON or a Python dictionary using the following pattern:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "data_layer = catalog.DataLayer.from_dict()\n", "data_layer = catalog.DataLayer.from_json()\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Approach 2 - Helper Function hides create()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "layer_dictionary = {\n", " \"data_layers\": [\n", " {\n", " \"color_table\": {\n", " \"id\": 58\n", " },\n", " \"crs\": \"EPSG:4326\",\n", " \"datatype\": \"bt\",\n", " \"level\": 13,\n", " \"name\": \"a_data_layer_name\"\n", " }\n", " ],\n", " \"layer_type\": \"Raster\"\n", "}\n", " \n", "data_layers = catalog.data_layers_from_dict(layer_dictionary)\n", " \n", "catalog.create_data_layers(data_layers = data_layers\n", " data_set_id = 490, \n", " data_layer_type = \"Raster\",\n", " )\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using a DataLayers object rather than DataLayer is useful if you want to create many datalayers are the same time. \n", "This is usually the case when creating a dataset to represent a multi-band input data. \n", "\n", "## Using Client Objects\n", "\n", "Once a client side object has been created it can be used for further processing. For example,\n", "\n", "### Pass one Object to Another\n", "\n", "An object within the library can sometimes be passed to another:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "credentials = authentication.OAuth2()\n", "\n", "#...\n", "\n", "eis_client = client.Client(authentication = credentials)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we create a credentials object and use it as part of the construction of a client object.\n", "\n", "### Pass an Object to the API\n", "\n", "An object can sometimes be passed to a server side call:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "query = Query()\n", " \n", "#...\n", "\n", "dashboard.add_dashboard_layer(query)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this example we want to display a query on the dashboard so we pass the query object to a helper method on the dashboard object which in turn forwards the query information on to the dashboard part of the Geospatial API.\n", "\n", "### Use an Object Returned by the API\n", "\n", "A returned result from a request is an object or list of objects and can be acted on:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "query_list = query.get_latest_queries()\n", "query = query_list[0]\n", "query.submit()\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we get the latest queries that have been run and re-run the first one in the list. We might re-run a query if, for example, it uses as data layer that has been updated since we last ran the query." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.0" } }, "nbformat": 4, "nbformat_minor": 2 }