{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "215b81b2-7b82-4477-a9e7-8759b46662f0",
   "metadata": {},
   "source": [
    "# Setup - Load an API Key and Libraries"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38e894e3",
   "metadata": {},
   "source": [
    "## Storing and Loading Your API Key Securely\n",
    "\n",
    "To securely store and use your API key in this notebook, follow these steps:\n",
    "\n",
    "1. **What is a `.env` File?**  \n",
    "   A `.env` file is a simple text file used to store sensitive information, such as API keys, in a secure and organized way. It allows you to keep sensitive data out of your code, making it easier to share or version-control your scripts without exposing private information. See our [guide](https://eodatahub.org.uk/docs/documentation/notebooks/sensitive-data/) for more information.\n",
    "\n",
    "2. **Generate an API key**  \n",
    "   Follow instructions in the [Getting Started documentation](https://eodatahub.org.uk/docs/documentation/apis/getting-started/) for Hub APIs to generate a Hub API Key.\n",
    "\n",
    "3. **Create a `.env` File**\n",
    "   - In the same directory as this notebook, create a plain text file named `.env`. You don't need any special tools or scripts - just create a regular file and name it .env.\n",
    "   - Add the following line to the file, replacing `<your_api_key>` with your actual API key:\n",
    "     ```plaintext\n",
    "     API_KEY=<your_api_key>\n",
    "     ```\n",
    "   - Save the file.\n",
    "\n",
    "4. **Load the Key in the Notebook**  \n",
    "   The following code snippet is already included in this notebook to load the key securely:\n",
    "   ```python\n",
    "   import os\n",
    "   from dotenv import load_dotenv\n",
    "   \n",
    "   load_dotenv(\".env\")  # Ensure the path matches your `.env` file location\n",
    "   key = os.getenv(\"API_KEY\")\n",
    "   ```\n",
    "   This will load the `API_KEY` from your `.env` file into the `key` variable.\n",
    "\n",
    "5. **Keep the `.env` File Secure**\n",
    "   - Do not share your `.env` file or API key.\n",
    "   - If you do accidentally share your key, delete it in the workspaces UI and request a new one.\n",
    "\n",
    "By following these steps, you can securely store and use your API key without exposing it in the notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5063414",
   "metadata": {},
   "source": [
    "## Setting Up the Workspace and Environment\n",
    "\n",
    "To ensure the notebook works correctly, you need to configure the `workspace` and `environment` variables. Follow these steps:\n",
    "1. **Ensure your workspace is configured for commercial orders**\n",
    "   - Follow the [Commercial Data](https://staging.eodatahub.org.uk/data/commercial/link-accounts/) guide to link your commercial account to your workspace.\n",
    "2. **Set the `workspace` Variable**:\n",
    "   - In the following cell, the `workspace` variable should be set to the name of the workspace you wish to order data for.\n",
    "   - Check the [Workspaces page](https://eodatahub.org.uk/workspaces/) to view names of workspaces available to you.\n",
    "\n",
    "> **Note for Developers**:  \n",
    "> Most users do not need to change the `platform_domain` variable, as it is already set to the correct value for the production environment. However, developers with access to other platforms (e.g., staging, test, or dev environments) may need to update the `platform_domain` to match the appropriate environment. For example:  \n",
    "> - Staging: `https://staging.eodatahub.org.uk`  \n",
    "> - Test: `https://test.eodatahub.org.uk`  \n",
    "> - Dev: `https://dev.eodatahub.org.uk`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9555e138-05ad-40c6-b5f6-07ab94156748",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "workspace = \"my-workspace\"\n",
    "\n",
    "load_dotenv(\".env\")\n",
    "api_key = os.getenv(\"API_KEY\")\n",
    "\n",
    "platform_domain = \"https://eodatahub.org.uk\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c6f2117c-8b93-4834-8391-a727c67e70cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install pystac-client xarray rasterio matplotlib"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "765f67ed-a48d-4bbd-89a6-08cd52f905d3",
   "metadata": {},
   "source": [
    "# Create a pystac-client Client for the EODH Catalogue\n",
    "\n",
    "The EODH catalogue can be viewed through a UI on the Hub under the `Catalogue` tab.\n",
    "\n",
    "Our STAC catalogue can also be browsed programatically using tools such as pystac-client, using your api_key for authorisation. In the following example, our client is scoped to the Planet catalogue to refine a search for some Planet commercial data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97883a1a-0845-41f5-be29-7ee19e1e0fc6",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pystac_client import Client\n",
    "\n",
    "# Limit scope of the top-level catalogue to Planet\n",
    "rc_url = f\"{platform_domain}/api/catalogue/stac/catalogs/commercial/catalogs/planet\"\n",
    "\n",
    "# Create STAC client\n",
    "stac_client = Client.open(rc_url, headers={\"Authorization\": f\"Bearer {api_key}\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df109ec1-82de-41ae-8b63-f525828c7f6d",
   "metadata": {},
   "source": [
    "# Search for Planet Data\n",
    "\n",
    "To demonstrate search capabilities, the following cell searches our catalogue for PSScene items that intersect a given polygon. If you have already selected the imagery you would like to order, you can skip this step. Further examples of search capabilities are available in our [API tutorials](https://eodatahub.org.uk/docs/documentation/apis/example-tutorials/).\n",
    "\n",
    "Coordinates are to be provided in longitude/latitude WGS84, and the polygon must be closed. Coordinates follow OGC GeoJSON specification. If you don’t have coordinates to hand, you can generate them using tools like [Google Earth](https://earth.google.com/) or any GIS software. Coordinates can define a polygon with more than 5 points inside the array, allowing for more complex shapes.\n",
    "\n",
    "You can adjust the `max_items` variable to control the number of image results returned."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4b9fe535-a186-44ed-8370-1c8f99078965",
   "metadata": {},
   "outputs": [],
   "source": [
    "geom = {\n",
    "    \"type\": \"Polygon\",\n",
    "    \"coordinates\": [\n",
    "        [\n",
    "            [9.6, 57.1],\n",
    "            [9.6, 57.0],\n",
    "            [9.8, 56.9],\n",
    "            [9.8, 57.0],\n",
    "            [9.6, 57.1],\n",
    "        ]\n",
    "    ],\n",
    "}\n",
    "search = stac_client.search(\n",
    "    max_items=10,\n",
    "    collections=['PSScene'],\n",
    "    intersects=geom,\n",
    ")\n",
    "for item in search.items():\n",
    "    print(item.get_self_href())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d282d3c8-fe56-4550-955b-f2edd17912fa",
   "metadata": {},
   "source": [
    "# Obtain a Quote for Planet Data\n",
    "\n",
    "Once an item of interest is found, you may obtain a quote for the item via a POST request to `/quote` following the `item_href`.\n",
    "\n",
    "### How to Obtain the `item_href`\n",
    "- The `item_href` can be obtained from the output of a search, such as the cell above, where the `get_self_href()` method returns the link.\n",
    "- Alternatively, you can find the `item_href` in the Map user interface under the \"Additional Resources\" section for an item, labeled as the \"self\" link.\n",
    "\n",
    "### Understanding the `coordinates` Field\n",
    "\n",
    "The `coordinates` field is optional and can be included to specify an Area of Interest (AOI). If provided, the item will be clipped to the specified AOI, and the quote (and later purchase) will reflect only the intersection of the original item and your AOI. This can help reduce the area and cost of the data you are requesting.\n",
    "\n",
    "If the `coordinates` field is omitted, the quote (and purchase) will be for the entire item.\n",
    "\n",
    "Coordinates must follow the OGC GeoJSON specification and be provided in longitude/latitude WGS84. The polygon must be closed, meaning the first and last points in the array should be the same. For example:\n",
    "\n",
    "```json\n",
    "\"coordinates\": [\n",
    "    [\n",
    "        [9.6, 57.1],\n",
    "        [9.6, 57.0],\n",
    "        [9.8, 56.9],\n",
    "        [9.8, 57.0],\n",
    "        [9.6, 57.1]\n",
    "    ]\n",
    "]\n",
    "```\n",
    "You can generate these coordinates using tools like [Google Earth](https://earth.google.com/) or any GIS software.\n",
    "\n",
    "### Understanding the Response\n",
    "- The `response` from the POST request is a JSON output containing the amount and unit of the quote. For Planet data, the unit is typically in square kilometers (km²).\n",
    "- The quote is provided in square kilometers (km²) and represents an approximation of the area of data contained in the purchase.\n",
    "- This area will count against your quota in the Planet system, which you can view on your [Planet account](https://docs.planet.com/platform/get-started/access-data/).\n",
    "\n",
    "### Status Codes and Their Meaning\n",
    "- **200 (OK)**: The request was successful, and the quote is returned in the response.\n",
    "- **400 (Bad Request)**: The request is malformed. Check the input data `coordinates` field is valid if included.\n",
    "- **401 (Unauthorized)**: The API key is missing or invalid. Ensure your `.env` file contains the correct API key.\n",
    "- **404 (Not Found)**: The `item_href` is incorrect or invalid. Verify that the link is valid and corresponds to an existing item.\n",
    "- **405 (Method Not Allowed)**: The HTTP method used is not supported for the endpoint. Ensure you are using a POST request.\n",
    "- **500 (Internal Server Error)**: An issue occurred on the server. Retry the request later or contact support if the issue persists.\n",
    "\n",
    "### Important Note\n",
    "- You will **not** be charged for the quote itself. Charges will only apply if you proceed to place an order in a later cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf7d3fbf",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "item_href = \"https://staging.eodatahub.org.uk/api/catalogue/stac/catalogs/commercial/catalogs/planet/collections/PSScene/items/20250217_101155_07_24c7\"\n",
    "url = f\"{item_href}/quote\"\n",
    "headers = {\n",
    "    'accept': 'application/json', \n",
    "    'Content-Type': 'application/json', \n",
    "    'Authorization': f'Bearer {api_key}'\n",
    "}\n",
    "data =  {\n",
    "    \"coordinates\": [\n",
    "        [\n",
    "            [9.6, 57.1],\n",
    "            [9.6, 57.0],\n",
    "            [9.8, 56.9],\n",
    "            [9.8, 57.0],\n",
    "            [9.6, 57.1]\n",
    "        ]\n",
    "    ]\n",
    "}\n",
    "\n",
    "response = requests.post(url, headers=headers, json=data)\n",
    "\n",
    "print(\"Status Code\", response.status_code)\n",
    "print(\"Response \", response.json())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "992e4742",
   "metadata": {},
   "source": [
    "# Order Planet Data\n",
    "\n",
    "Once you are satisfied with the item and pricing, you may proceed with ordering the item via a POST request to `/order` following the `item_href`.\n",
    "\n",
    "- Change the `item_href` to any valid link to a STAC item in our Planet commercial catalogue to order it.  \n",
    "- The `coordinates` argument is optional. If included, the ordered image will be clipped to the specified AOI. If omitted, the entire image will be purchased.  \n",
    "- The `productBundle` field may also be changed to adjust the processing done on the image. For details, please see our [guide on placing orders](https://eodatahub.org.uk/data/commercial/ordering-commercial-data/).\n",
    "\n",
    "Once an order is placed, the API response includes a `Location` header that links to the item in your workspace catalogue. This item will be updated with the order status and assets when they are ready.\n",
    "\n",
    "> **Warning**: The lines of code that place the order and process the response are commented out by default. If you uncomment and run them with the correct setup, it will charge quota to your account. Ensure you review all parameters carefully before proceeding.\n",
    "\n",
    "An order cannot be changed once it is placed, so please ensure the correct product and parameters are chosen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e5349a0f-3747-4349-9dfd-30f12d512847",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "item_href = \"https://staging.eodatahub.org.uk/api/catalogue/stac/catalogs/commercial/catalogs/planet/collections/PSScene/items/20250217_101155_07_24c7\"\n",
    "url = f\"{item_href}/order\"\n",
    "headers = {\n",
    "    'accept': 'application/json', \n",
    "    'Content-Type': 'application/json', \n",
    "    'Authorization': f'Bearer {api_key}'\n",
    "}\n",
    "data =  {\n",
    "    \"productBundle\": \"General Use\",\n",
    "    \"coordinates\": [\n",
    "        [\n",
    "            [9.6, 57.1],\n",
    "            [9.6, 57.0],\n",
    "            [9.8, 56.9],\n",
    "            [9.8, 57.0],\n",
    "            [9.6, 57.1]\n",
    "        ]\n",
    "    ]\n",
    "}\n",
    "\n",
    "# Uncomment the following lines to place an order\n",
    "\n",
    "# response = requests.post(url, headers=headers, json=data)\n",
    "\n",
    "# print(\"Status Code:\", response.status_code)\n",
    "# print(\"Response:\", response.json())\n",
    "\n",
    "# location_header = response.headers.get('Location')\n",
    "# print(\"Item will shortly be available at:\", location_header)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00e81bb7-5e24-4de9-baaa-9ad688e86b84",
   "metadata": {},
   "source": [
    "# Read STAC for Ordered Planet Data\n",
    "\n",
    "The STAC item can also be obtained through browsing your workspace catalogue. The following example demonstrates a search for a specific asset for an item."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "057d2a52-62c0-44c7-99b9-bcedb559c7e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pystac import Item\n",
    "from pystac_client import CollectionClient\n",
    "\n",
    "data_i_ordered_earlier = f\"{platform_domain}/api/catalogue/stac/catalogs/user/catalogs/{workspace}/catalogs/commercial-data/catalogs/planet\"\n",
    "stac_client = Client.open(data_i_ordered_earlier, headers={\"Authorization\": f\"Bearer {api_key}\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "adedb354-a229-454f-bd54-c5434322d87f",
   "metadata": {},
   "outputs": [],
   "source": [
    "ordered_item = next(stac_client.get_items(\"20250217_101155_07_24c7\"))\n",
    "ordered_item"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5df62617-e8be-476e-8b5f-d684c0d0ee1c",
   "metadata": {},
   "outputs": [],
   "source": [
    "asset = ordered_item.get_assets()[\"20250217_101155_07_24c7_3B_AnalyticMS_clip.tif\"]\n",
    "asset"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87eff8df-4daf-4d81-95b7-8f2665e2f5ec",
   "metadata": {},
   "source": [
    "# Fetch Ordered Planet Data\n",
    "\n",
    "Any asset link from a commercial data purchase can be downloaded via an authorised GET request to the asset href."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a8354c1e-fe58-4fdb-8c03-5f872c2f2c22",
   "metadata": {},
   "outputs": [],
   "source": [
    "import urllib3\n",
    "from io import BytesIO\n",
    "\n",
    "resp = urllib3.request(\"GET\", asset.href, headers={\"Authorization\": f\"Bearer {api_key}\"})\n",
    "resp.data[0:100]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8b59094-cf51-469d-b925-5036c473f4f7",
   "metadata": {},
   "source": [
    "# Plot Planet Data\n",
    "\n",
    "Visual assets can be viewed programmatically:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25cdfe5c-7175-40d4-beba-3543526fd8c9",
   "metadata": {},
   "outputs": [],
   "source": [
    "from rasterio.plot import show\n",
    "import rasterio\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "with rasterio.open(BytesIO(resp.data)) as src:\n",
    "    f = src.read()\n",
    "    fig, ax = plt.subplots(figsize=(10, 10))\n",
    "    show(f / 10000, ax=ax, title=\"PlanetScope Image\")\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21c2472d",
   "metadata": {},
   "source": [
    "# Further Visualisation of Planet Data\n",
    "\n",
    "Our TiTiler instance can also be used to visualise the data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a610d2d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "from IPython.display import Image, display\n",
    "\n",
    "TITILER_PREVIEW_URL = f'{platform_domain}/titiler/core/cog/preview'\n",
    "TITILER_PREVIEW_PARAMS = {\n",
    "    'url': asset.href,\n",
    "    'bidx': 1,\n",
    "    'rescale': '2229,12331',\n",
    "    'colormap_name': 'rain_r'\n",
    "}\n",
    "\n",
    "response = requests.get(TITILER_PREVIEW_URL, params=TITILER_PREVIEW_PARAMS, headers={'Authorization': f'Bearer {api_key}'})\n",
    "\n",
    "# Display the image\n",
    "image = Image(response.content)\n",
    "display(image)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10e37827",
   "metadata": {},
   "source": [
    "# Obtain a Quote for Airbus SAR Data\n",
    "\n",
    "Search and ordering capabilities are also in place for Airbus SAR items. Once an item of interest is found, you may obtain a quote for the item via a POST request to `/quote` following the `item_href`.\n",
    "\n",
    "Note: Airbus SAR does not support clipping an item with an AOI.\n",
    "\n",
    "### How to Obtain the `item_href`\n",
    "- The `item_href` can be obtained from the output of a search, demonstrated earlier in this notebook for Planet items.\n",
    "- Alternatively, you can find the `item_href` in the Map user interface under the \"Additional Resources\" section for an item, labeled as the \"self\" link.\n",
    "\n",
    "### Understanding the `licence` field\n",
    "\n",
    "The `licence` field must be populated for Airbus SAR quotes. It should be changed depending on how you intend to use the data. For more information see the [Airbus guide](https://space-solutions.airbus.com/legal/licences/). Supported licences are:\n",
    "- `Single User Licence`\n",
    "- `Multi User (2 - 5) Licence`\n",
    "- `Multi User (6 - 30) Licence`.\n",
    "\n",
    "### Understanding the Response\n",
    "- The `response` from the POST request is a JSON output containing the amount and unit of the quote. For Airbus data, the unit is typically in Euros (EUR).\n",
    "- The quote represents a monetary value that will be charged to your Airbus account upon placing the order.\n",
    "\n",
    "### Status Codes and Their Meaning\n",
    "- **200 (OK)**: The request was successful, and the quote is returned in the response.\n",
    "- **400 (Bad Request)**: The request is malformed. Check the input data includes only a valid `licence`.\n",
    "- **401 (Unauthorized)**: The API key is missing or invalid. Ensure your `.env` file contains the correct API key.\n",
    "- **404 (Not Found)**: The `item_href` is incorrect or invalid. Verify that the link is valid and corresponds to an existing item.\n",
    "- **405 (Method Not Allowed)**: The HTTP method used is not supported for the endpoint. Ensure you are using a POST request.\n",
    "- **500 (Internal Server Error)**: An issue occurred on the server. Retry the request later or contact support if the issue persists.\n",
    "\n",
    "### Important Note\n",
    "- You will **not** be charged for the quote itself. Charges will only apply if you proceed to place an order in a later cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eb69a573",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "item_href = \"https://staging.eodatahub.org.uk/api/catalogue/stac/catalogs/commercial/catalogs/airbus/collections/airbus_sar_data/items/TSX-1_WS_S_wide_001R_97985_D33003943_29000\"\n",
    "url = f\"{item_href}/quote\"\n",
    "headers = {\n",
    "    'accept': 'application/json', \n",
    "    'Content-Type': 'application/json', \n",
    "    'Authorization': f'Bearer {api_key}'\n",
    "}\n",
    "data =  {\n",
    "    \"licence\": \"Single User Licence\",\n",
    "}\n",
    "\n",
    "response = requests.post(url, headers=headers, json=data)\n",
    "\n",
    "print(\"Status Code:\", response.status_code)\n",
    "print(\"Response:\", response.json())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81d0c97c-62c2-47c0-8941-3bcbb8a2710a",
   "metadata": {},
   "source": [
    "# Order Airbus SAR Data\n",
    "\n",
    "Once you are satisfied with the item and pricing, you may proceed with ordering the item via a POST request to `/order` following the `item_href`.\n",
    "\n",
    "- Change the `item_href` to any valid link to a STAC item in our Airbus commercial catalogue to order it.\n",
    "- `licence` must be set depending on the intended usage of the data. For more information see the [Airbus guide](https://space-solutions.airbus.com/legal/licences/). Supported licences are:\n",
    "  - `Single User Licence`\n",
    "  - `Multi User (2 - 5) Licence`\n",
    "  - `Multi User (6 - 30) Licence`\n",
    "- The `productBundle` and `radarOptions` fields may also be changed to adjust the processing done on the image. Valid product bundles for SAR are `SSC`, `MGD`, `GEC`, and `EEC`. `radarOptions` include:\n",
    "  - `orbit` of `rapid` or `science`.\n",
    "  - `resolutionVariant` of `RE` or `SE`.\n",
    "  - `projection` of `Auto`, `UTM`, or `UPS`.\n",
    "  \n",
    "For further details please see our [guide on placing orders](https://eodatahub.org.uk/data/commercial/ordering-commercial-data/).\n",
    "\n",
    "Once an order is placed, the API response includes a `Location` header that links to the item in your workspace catalogue. This item will be updated with the order status and assets when they are ready.\n",
    "\n",
    "> **Warning**: The lines of code that place the order and process the response are commented out by default. If you uncomment and run them with the correct setup, it will charge quota to your account. Ensure you review all parameters carefully before proceeding.\n",
    "\n",
    "An order cannot be changed once it is placed, so please ensure the correct product and parameters are chosen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "042cfc54-6acb-41bb-9e55-7d7de8b2efbc",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "item_href = \"https://staging.eodatahub.org.uk/api/catalogue/stac/catalogs/commercial/catalogs/airbus/collections/airbus_sar_data/items/TSX-1_WS_S_wide_001R_97985_D33003943_29000\"\n",
    "url = f\"{item_href}/order\"\n",
    "headers = {\n",
    "    \"accept\": \"application/json\", \n",
    "    \"Content-Type\": \"application/json\", \n",
    "    \"Authorization\": f\"Bearer {api_key}\"\n",
    "}\n",
    "data =  {\n",
    "    \"licence\": \"Single User Licence\",\n",
    "    \"productBundle\": \"SSC\",\n",
    "    \"radarOptions\": {\n",
    "        \"orbit\": \"rapid\"\n",
    "    }\n",
    "}\n",
    "\n",
    "# Uncomment the following lines to place an order\n",
    "\n",
    "# response = requests.post(url, headers=headers, json=data)\n",
    "\n",
    "# print(\"Status Code\", response.status_code)\n",
    "# print(\"Response \", response.json())\n",
    "\n",
    "# location_header = response.headers.get('Location')\n",
    "# print(\"Item will shortly be available at:\", location_header)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e9c5009",
   "metadata": {},
   "source": [
    "# Obtain a Quote for Airbus Optical Data\n",
    "\n",
    "Search and ordering capabilities are also in place for Airbus Optical items. Once an item of interest is found, you may obtain a quote for the item via a POST request to `/quote` following the `item_href`.\n",
    "\n",
    "### How to Obtain the `item_href`\n",
    "- The `item_href` can be obtained from the output of a search, such as the cell above, where the `get_self_href()` method returns the link.\n",
    "- Alternatively, you can find the `item_href` in the Map user interface under the \"Additional Resources\" section for an item, labeled as the \"self\" link.\n",
    "\n",
    "### Understanding the `licence` field\n",
    "\n",
    "The `licence` field must be populated for Airbus Optical quotes. It should be changed depending on how you intend to use the data. For more information see the [Airbus guide](https://space-solutions.airbus.com/legal/licences/). Supported licences are:\n",
    "- `Standard`\n",
    "- `Background Layer`\n",
    "- `Standard + Background Layer`\n",
    "- `Academic`\n",
    "- `Media Licence`\n",
    "- `Standard Multi End-Users (2-5)`\n",
    "- `Standard Multi End-Users (6-10)`\n",
    "- `Standard Multi End-Users (11-30)`\n",
    "- `Standard Multi End-Users (>30)`\n",
    "\n",
    "### Understanding the `coordinates` Field\n",
    "\n",
    "The `coordinates` field is optional and can be included to specify an AOI. If provided, the item will be clipped to the specified AOI, and the quote (and later purchase) will reflect only the intersection of the original item and your AOI. This can help reduce the area and cost of the data you are requesting.\n",
    "\n",
    "If the `coordinates` field is omitted, the quote (and purchase) will be for the entire item.\n",
    "\n",
    "Coordinates must follow the OGC GeoJSON specification and be provided in longitude/latitude WGS84. The polygon must be closed, meaning the first and last points in the array should be the same. For example:\n",
    "\n",
    "```json\n",
    "\"coordinates\": [\n",
    "    [\n",
    "        [9.6, 57.1],\n",
    "        [9.6, 57.0],\n",
    "        [9.8, 56.9],\n",
    "        [9.8, 57.0],\n",
    "        [9.6, 57.1]\n",
    "    ]\n",
    "]\n",
    "```\n",
    "You can generate these coordinates using tools like [Google Earth](https://earth.google.com/) or any GIS software.\n",
    "\n",
    "### Understanding the Response\n",
    "- The `response` from the POST request is a JSON output containing the amount and unit of the quote. For Airbus data, the unit is typically in Euros (EUR).\n",
    "- The quote represents a monetary value that will be charged to your Airbus account upon placing the order.\n",
    "\n",
    "### Status Codes and Their Meaning\n",
    "- **200 (OK)**: The request was successful, and the quote is returned in the response.\n",
    "- **400 (Bad Request)**: The request is malformed. Check the input data includes a valid `licence` and the `coordinates` field is valid if included.\n",
    "- **401 (Unauthorized)**: The API key is missing or invalid. Ensure your `.env` file contains the correct API key.\n",
    "- **404 (Not Found)**: The `item_href` is incorrect or invalid. Verify that the link is valid and corresponds to an existing item.\n",
    "- **405 (Method Not Allowed)**: The HTTP method used is not supported for the endpoint. Ensure you are using a POST request.\n",
    "- **500 (Internal Server Error)**: An issue occurred on the server. Retry the request later or contact support if the issue persists.\n",
    "\n",
    "### Important Note\n",
    "- You will **not** be charged for the quote itself. Charges will only apply if you proceed to place an order in a later cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "260e779e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "item_href = \"https://staging.eodatahub.org.uk/api/catalogue/stac/catalogs/commercial/catalogs/airbus/collections/airbus_phr_data/items/DS_PHR1A_201203021558128_FR1_PX_W080S03_0221_01728\"\n",
    "url = f\"{item_href}/quote\"\n",
    "headers = {\n",
    "    'accept': 'application/json', \n",
    "    'Content-Type': 'application/json', \n",
    "    'Authorization': f'Bearer {api_key}'\n",
    "}\n",
    "data =  {\n",
    "    \"licence\": \"Standard\",\n",
    "    \"coordinates\": [\n",
    "        [\n",
    "            [-79.8,-2.1], \n",
    "            [-79.8,-2.2], \n",
    "            [-79.95,-2.2], \n",
    "            [-79.95,-2.1], \n",
    "            [-79.8,-2.1]\n",
    "        ]\n",
    "    ]\n",
    "}\n",
    "\n",
    "response = requests.post(url, headers=headers, json=data)\n",
    "\n",
    "print(\"Status Code\", response.status_code)\n",
    "print(\"Response \", response.json())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2c3288d-e47f-4cf9-bd82-e22158d7bcb0",
   "metadata": {},
   "source": [
    "# Order Airbus Optical Data\n",
    "\n",
    "Once you are satisfied with the item and pricing, you may proceed with ordering the item via a POST request to `/order` following the `item_href`.\n",
    "\n",
    "- Change the `item_href` to any valid link to a STAC item in our Airbus commercial catalogue to order it. \n",
    "- `coordinates` can optionally clip an item to an AOI.\n",
    "- `licence` must be set depending on the intended usage of the data. For more information see the [Airbus guide](https://space-solutions.airbus.com/legal/licences/). Supported licences are:\n",
    "  - `Standard`\n",
    "  - `Background Layer`\n",
    "  - `Standard + Background Layer`\n",
    "  - `Academic`\n",
    "  - `Media Licence`\n",
    "  - `Standard Multi End-Users (2-5)`\n",
    "  - `Standard Multi End-Users (6-10)`\n",
    "  - `Standard Multi End-Users (11-30)`\n",
    "  - `Standard Multi End-Users (>30)`\n",
    "- Set the `productBundle` field to adjust the processing done on the image. For details please see our [guide on placing orders](https://eodatahub.org.uk/data/commercial/ordering-commercial-data/).\n",
    "- `endUserCountry` must match an Airbus country code corresponding to the user making the purchase.\n",
    "\n",
    "Once an order is placed, the API response includes a Location header that links to the item in your workspace catalogue. This item will be updated with the order status and assets when they are ready.\n",
    "\n",
    "> **Warning**: The lines of code that place the order and process the response are commented out by default. If you uncomment and run them with the correct setup, it will charge quota to your account. Ensure you review all parameters carefully before proceeding.\n",
    "\n",
    "An order cannot be changed once it is placed, so please ensure the correct product and parameters are chosen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "38e0ae71-2271-4842-be9f-4e38720dc385",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "item_href = \"https://staging.eodatahub.org.uk/api/catalogue/stac/catalogs/commercial/catalogs/airbus/collections/airbus_phr_data/items/DS_PHR1A_201203021558128_FR1_PX_W080S03_0221_01728\"\n",
    "url = f\"{item_href}/order\"\n",
    "headers = {\n",
    "    'accept': 'application/json', \n",
    "    'Content-Type': 'application/json', \n",
    "    'Authorization': f'Bearer {api_key}'\n",
    "}\n",
    "data =  {\n",
    "    \"licence\": \"Standard\",\n",
    "    \"endUserCountry\": \"GB\",\n",
    "    \"productBundle\": \"General Use\", \n",
    "    \"coordinates\": [\n",
    "        [\n",
    "            [-79.8,-2.1], \n",
    "            [-79.8,-2.2], \n",
    "            [-79.95,-2.2], \n",
    "            [-79.95,-2.1], \n",
    "            [-79.8,-2.1]\n",
    "        ]\n",
    "    ]\n",
    "}\n",
    "\n",
    "response = requests.post(url, headers=headers, json=data)\n",
    "\n",
    "print(\"Status Code:\", response.status_code)\n",
    "print(\"Response:\", response.json())\n",
    "\n",
    "location_header = response.headers.get('Location')\n",
    "print(\"Item will shortly be available at:\", location_header)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "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.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
