diff --git a/docs/api_reference/eoproduct.rst b/docs/api_reference/eoproduct.rst index 48ec93abe1..8ec5e1727f 100644 --- a/docs/api_reference/eoproduct.rst +++ b/docs/api_reference/eoproduct.rst @@ -36,8 +36,10 @@ Conversion ---------- .. automethod:: EOProduct.as_dict +.. automethod:: EOProduct.as_pystac_object .. automethod:: EOProduct.from_dict .. automethod:: EOProduct.from_file +.. automethod:: EOProduct.from_pystac Interface --------- diff --git a/docs/api_reference/searchresult.rst b/docs/api_reference/searchresult.rst index 9f399c0efb..cd8c2c6e2a 100644 --- a/docs/api_reference/searchresult.rst +++ b/docs/api_reference/searchresult.rst @@ -47,7 +47,9 @@ Conversion .. autosummary:: SearchResult.from_dict + SearchResult.from_pystac SearchResult.as_dict + SearchResult.as_pystac_object SearchResult.as_shapely_geometry_object SearchResult.as_wkt_object @@ -60,5 +62,5 @@ Interface .. autoclass:: SearchResult :members: crunch, filter_date, filter_latest_intersect, filter_latest_by_name, filter_overlap, filter_property, - filter_online, from_dict, as_dict, as_shapely_geometry_object, as_wkt_object, next_page, - __geo_interface__ + filter_online, from_dict, from_pystac, as_dict, as_pystac_object, as_shapely_geometry_object, + as_wkt_object, next_page, __geo_interface__ diff --git a/docs/conf.py b/docs/conf.py index 64b1509d55..a7017675a1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -271,15 +271,16 @@ # configuration for intersphinx intersphinx_mapping = { "python": ("https://docs.python.org/3/", None), + "click": ("https://click.palletsprojects.com/en/stable/", None), + "fsspec": ("https://filesystem-spec.readthedocs.io/en/stable/", None), + "pydantic": ("https://docs.pydantic.dev/latest", None), + "pystac": ("https://pystac.readthedocs.io/en/stable/", None), "python-requests": ("https://requests.readthedocs.io/en/stable/", None), + "rasterio": ("https://rasterio.readthedocs.io/en/stable/", None), + "rioxarray": ("https://corteva.github.io/rioxarray/stable/", None), "shapely": ("https://shapely.readthedocs.io/en/stable/", None), - "click": ("https://click.palletsprojects.com/en/stable/", None), "urllib3": ("https://urllib3.readthedocs.io/en/stable/", None), "xarray": ("https://docs.xarray.dev/en/stable/", None), - "rasterio": ("https://rasterio.readthedocs.io/en/stable/", None), - "rioxarray": ("https://corteva.github.io/rioxarray/stable/", None), - "fsspec": ("https://filesystem-spec.readthedocs.io/en/stable/", None), - "pydantic": ("https://docs.pydantic.dev/latest", None), } suppress_warnings = ["misc.copy_overwrite"] diff --git a/docs/notebooks/api_user_guide/5_serialize_deserialize.ipynb b/docs/notebooks/api_user_guide/5_serialize_deserialize.ipynb index c3a60ac4d3..5b4b99b256 100644 --- a/docs/notebooks/api_user_guide/5_serialize_deserialize.ipynb +++ b/docs/notebooks/api_user_guide/5_serialize_deserialize.ipynb @@ -522,6 +522,7 @@ "metadata": {}, "outputs": [], "source": [ + "# basic JSON rendering\n", "import json\n", "from IPython.display import HTML\n", "from pathlib import Path\n", @@ -661,12 +662,12 @@ " }\n", " ],\n", " \"stac_extensions\": [\n", - " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/product/v1.0.0/schema.json\",\n", - " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/order/v1.1.0/schema.json\",\n", - " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\",\n", - " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\"\n", + " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\",\n", + " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\"\n", " ],\n", " \"stac_version\": \"1.1.0\",\n", " \"collection\": \"S2_MSI_L1C\"\n", @@ -790,12 +791,12 @@ " }\n", " ],\n", " \"stac_extensions\": [\n", - " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/product/v1.0.0/schema.json\",\n", - " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/order/v1.1.0/schema.json\",\n", - " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\",\n", - " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\"\n", + " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\",\n", + " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\"\n", " ],\n", " \"stac_version\": \"1.1.0\",\n", " \"collection\": \"S2_MSI_L1C\"\n", @@ -1110,12 +1111,12 @@ " }\n", " ],\n", " \"stac_extensions\": [\n", - " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/product/v1.0.0/schema.json\",\n", - " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/order/v1.1.0/schema.json\",\n", - " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\",\n", - " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\"\n", + " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\",\n", + " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\"\n", " ],\n", " \"stac_version\": \"1.1.0\",\n", " \"collection\": \"S2_MSI_L1C\"\n", @@ -1239,12 +1240,12 @@ " }\n", " ],\n", " \"stac_extensions\": [\n", - " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/product/v1.0.0/schema.json\",\n", - " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/order/v1.1.0/schema.json\",\n", - " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\",\n", - " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\"\n", + " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\",\n", + " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\"\n", " ],\n", " \"stac_version\": \"1.1.0\",\n", " \"collection\": \"S2_MSI_L1C\"\n", @@ -1370,6 +1371,2612 @@ "search_results.as_wkt_object()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `SearchResult.as_pystac_object`\n", + "\n", + "[SearchResult.as_pystac_object()](../../api_reference/searchresult.rst#eodag.api.search_result.SearchResult.as_pystac_object) will return a [pystac.ItemCollection](https://pystac.readthedocs.io/en/stable/api/item_collection.html#pystac-item-collection)." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "
\n", + "
\n", + " <pystac.item_collection.ItemCollection object at 0x706755bb1a90>\n", + "
\n", + "\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pystac_item_collection = search_results.as_pystac_object()\n", + "pystac_item_collection" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1381,7 +3988,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -1506,12 +4113,12 @@ " }\n", " ],\n", " \"stac_extensions\": [\n", - " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/product/v1.0.0/schema.json\",\n", - " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", " \"https://stac-extensions.github.io/order/v1.1.0/schema.json\",\n", - " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\",\n", - " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\"\n", + " \"https://stac-extensions.github.io/grid/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/sat/v1.1.0/schema.json\",\n", + " \"https://stac-extensions.github.io/eo/v2.0.0/schema.json\",\n", + " \"https://stac-extensions.github.io/processing/v1.2.0/schema.json\"\n", " ],\n", " \"stac_version\": \"1.1.0\",\n", " \"collection\": \"S2_MSI_L1C\"\n", @@ -1521,7 +4128,7 @@ "" ] }, - "execution_count": 13, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -1531,6 +4138,1153 @@ "collapsible_json(product_dict, \"product_dict\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `EOProduct.as_pystac_object`\n", + "\n", + "[EOProduct.as_pystac_object()](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct.as_pystac_object) allows to directly convert a single product to a [pystac.Item](https://pystac.readthedocs.io/en/stable/api/item.html#pystac-item)." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "
\n", + "
\n", + " <Item id=S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318>\n", + "
\n", + "\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pystac_item = search_results[0].as_pystac_object()\n", + "pystac_item" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1553,7 +5307,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -1920,7 +5674,7 @@ " EOProduct(id=S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137, provider=cop_dataspace)])" ] }, - "execution_count": 14, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -1932,7 +5686,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -1957,7 +5711,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -2324,7 +6078,7 @@ " EOProduct(id=S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137, provider=cop_dataspace)])" ] }, - "execution_count": 16, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -2336,13 +6090,13 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c1e4ded5c506498c8d86591db8490b6b", + "model_id": "ab8dda07667546088a42b2e2d05cbcae", "version_major": 2, "version_minor": 0 }, @@ -2376,7 +6130,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -2731,7 +6485,7 @@ " EOProduct(id=S2B_MSIL1C_20240710T103629_N0510_R008_T31TEJ_20240710T131044, provider=cop_dataspace)])" ] }, - "execution_count": 18, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -2757,7 +6511,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -5672,7 +9426,7 @@ " EOProduct(id=S2A_MSIL1C_20250510T084731_N0511_R107_T36TUR_20250510T094847, provider=generic_stac_provider)])" ] }, - "execution_count": 19, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -5698,7 +9452,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -6065,7 +9819,7 @@ " EOProduct(id=S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137, provider=cop_dataspace)])" ] }, - "execution_count": 20, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -6085,7 +9839,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -6452,7 +10206,7 @@ " EOProduct(id=S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137, provider=cop_dataspace)])" ] }, - "execution_count": 21, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -6465,21 +10219,29 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### `EOProduct.from_dict`\n", + "### `SearchResult.from_pystac`\n", "\n", - "[EOProduct.from_dict()](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct.from_dict) will build a [EOProduct](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct) from a given dictionary. If `dag` parameter is given, the method will use it to register the product downloader. If not\n", - "provided, the downloader and authenticator will not be registered." + "[SearchResult.from_pystac()](../../api_reference/searchresult.rst#eodag.api.search_result.SearchResult.from_pystac) will build a [SearchResult](../../api_reference/searchresult.rst#eodag.api.search_result.SearchResult) from a [pystac.ItemCollection](https://pystac.readthedocs.io/en/stable/api/item_collection.html#pystac-item-collection). If `dag` parameter is given, the method will use it to register products downloader. If not provided, the downloader and authenticator will not be registered." ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", + " \n", + " \n", + " \n", - " \n", - " \n", + " \n", + " \n", " \n", - "
\n", + " SearchResult (2)\n", + "
\n", + "
\n", + " 0 \n", + " EOProduct(id=S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318, provider=cop_dataspace)\n", + " \n", + " \n", " \n", @@ -6646,39 +10408,15 @@ " \n", " \n", " \n", - "
\n", " EOProduct\n", "
geometry
thumbnail
" - ], - "text/plain": [ - "EOProduct(id=S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318, provider=cop_dataspace)" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "EOProduct.from_dict(product_dict, dag=dag)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### `EOProduct.from_file`\n", - "\n", - "[EOProduct.from_file()](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct.from_file) will build a [EOProduct](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct) from a serialized Feature / STAC item file. If `dag` parameter is given, the method will use it to register the product downloader. If not provided, the downloader and authenticator will not be registered." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", + "
\n", + "
\n", + "
\n", + "
\n", + " 1 \n", + " EOProduct(id=S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137, provider=cop_dataspace)\n", + " \n", + " \n", " \n", @@ -6695,15 +10433,15 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", "
\n", " EOProduct\n", "
properties["id"]:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318','S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137',
properties["start_datetime"]:'2024-07-03T10:46:29.024000Z','2024-07-05T10:40:21.025000Z',
properties["end_datetime"]:'2024-07-03T10:46:29.024000Z','2024-07-05T10:40:21.025000Z',
\n", "
properties: (30){\n", @@ -6712,15 +10450,15 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -6729,7 +10467,7 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -6749,47 +10487,47 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -6801,7 +10539,7 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -6817,11 +10555,11 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -6829,54 +10567,649 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", "
datetime:'2024-07-03T10:46:29.024000Z','2024-07-05T10:40:21.025000Z',
end_datetime:'2024-07-03T10:46:29.024000Z','2024-07-05T10:40:21.025000Z',
id:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318','S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137',
instruments:
platform:'S2B','S2A',
providers:
published:'2024-07-03T12:42:14.249198Z','2024-07-05T16:44:47.318744Z',
start_datetime:'2024-07-03T10:46:29.024000Z','2024-07-05T10:40:21.025000Z',
title:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318','S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137',
uid:'c010825a-c3a6-46a0-948e-005521edf124','5193fc1e-6e68-40ab-8e0f-fc1c55cb01da',
updated:'2024-11-09T03:15:32.907273Z','2024-11-08T21:39:34.502029Z',
cop_dataspace:sourceProduct:'S2B_OPER_MSI_L1C_TL_2BPS_20240703T114318_A038258_T31TEJ_N05.10,S2B_OPER_MSI_L1C_DS_2BPS_20240703T114318_S20240703T104623_N05.10,S2B_OPER_MSI_L1C_TC_2BPS_20240703T114318_A038258_T31TEJ_N05.10.jp2','S2A_OPER_MSI_L1C_TL_2APS_20240705T142137_A047195_T31TEJ_N05.10,S2A_OPER_MSI_L1C_DS_2APS_20240705T142137_S20240705T104024_N05.10,S2A_OPER_MSI_L1C_TC_2APS_20240705T142137_A047195_T31TEJ_N05.10.jp2',
cop_dataspace:sourceProductOriginDate:'2024-07-03T12:35:09Z,2024-07-03T12:23:12Z,2024-07-03T12:35:09Z','2024-07-05T16:33:16Z,2024-07-05T16:32:39Z,2024-07-05T16:33:18Z',
eo:cloud_cover:14.423965639102,59.366657708501,
eodag:download_link:'https://catalogue.dataspace.copernicus.eu/odata/v1/Products(c010825a-c3a6-46a0-948e-005521edf124)/$value','https://catalogue.dataspace.copernicus.eu/odata/v1/Products(5193fc1e-6e68-40ab-8e0f-fc1c55cb01da)/$value',
eodag:quicklook:'https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(396a9522-3f07-4645-9196-a65c349ad8e9)/$value','https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(afbc766b-b6cd-448c-a01a-872cff8fce36)/$value',
eodag:thumbnail:'https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(396a9522-3f07-4645-9196-a65c349ad8e9)/$value','https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(afbc766b-b6cd-448c-a01a-872cff8fce36)/$value',
grid:code:
processing:datetime:'2024-07-03T11:43:18.000000Z','2024-07-05T14:21:37.000000Z',
processing:level:
s2:datastrip_id:'S2B_OPER_MSI_L1C_DS_2BPS_20240703T114318_S20240703T104623_N05.10','S2A_OPER_MSI_L1C_DS_2APS_20240705T142137_S20240705T104024_N05.10',
s2:datatake_id:'GS2B_20240703T104629_038258_N05.10','GS2A_20240705T104021_047195_N05.10',
s2:datatake_type:
s2:tile_id:'S2B_OPER_MSI_L1C_TL_2BPS_20240703T114318_A038258_T31TEJ_N05.10','S2A_OPER_MSI_L1C_TL_2APS_20240705T142137_A047195_T31TEJ_N05.10',
sat:absolute_orbit:38258,47195,
sat:relative_orbit:51,8,
}
\n", "
assets: (0)
\n", "
geometry
thumbnailgeometry
thumbnail
" + " \n", + " \n", + " \n", + " " ], "text/plain": [ - "EOProduct(id=S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318, provider=cop_dataspace)" + "SearchResult([EOProduct(id=S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318, provider=cop_dataspace),\n", + " EOProduct(id=S2A_MSIL1C_20240705T104021_N0510_R008_T31TEJ_20240705T142137, provider=cop_dataspace)])" ] }, - "execution_count": 23, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# save serialized to file\n", - "product_filepath = Path(workspace) / \"product.json\"\n", - "with open(product_filepath, \"w\") as f:\n", - " json.dump(product_dict, f)\n", + "SearchResult.from_pystac(pystac_item_collection, dag=dag)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `EOProduct.from_dict`\n", "\n", - "# build EOProduct from file\n", - "EOProduct.from_file(product_filepath, dag=dag)" + "[EOProduct.from_dict()](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct.from_dict) will build a [EOProduct](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct) from a given dictionary. If `dag` parameter is given, the method will use it to register the product downloader. If not\n", + "provided, the downloader and authenticator will not be registered." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " EOProduct\n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
provider:'cop_dataspace',
collection:'S2_MSI_L1C',
properties["id"]:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
properties["start_datetime"]:'2024-07-03T10:46:29.024000Z',
properties["end_datetime"]:'2024-07-03T10:46:29.024000Z',
\n", + "
properties: (30){\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
constellation:'SENTINEL-2',
datetime:'2024-07-03T10:46:29.024000Z',
end_datetime:'2024-07-03T10:46:29.024000Z',
id:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
instruments:['MSI'\n", + " ],
platform:'S2B',
providers:[{\n", + " 'name': 'ESA'\n", + " , \n", + " 'roles': ['producer'\n", + " ]\n", + " }\n", + " ,
{\n", + " 'name': 'cop_dataspace'\n", + " , \n", + " 'roles': ['host'\n", + " ]\n", + " }\n", + " ],
published:'2024-07-03T12:42:14.249198Z',
start_datetime:'2024-07-03T10:46:29.024000Z',
title:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
uid:'c010825a-c3a6-46a0-948e-005521edf124',
updated:'2024-11-09T03:15:32.907273Z',
cop_dataspace:sourceProduct:'S2B_OPER_MSI_L1C_TL_2BPS_20240703T114318_A038258_T31TEJ_N05.10,S2B_OPER_MSI_L1C_DS_2BPS_20240703T114318_S20240703T104623_N05.10,S2B_OPER_MSI_L1C_TC_2BPS_20240703T114318_A038258_T31TEJ_N05.10.jp2',
cop_dataspace:sourceProductOriginDate:'2024-07-03T12:35:09Z,2024-07-03T12:23:12Z,2024-07-03T12:35:09Z',
eo:cloud_cover:14.423965639102,
eodag:download_link:'https://catalogue.dataspace.copernicus.eu/odata/v1/Products(c010825a-c3a6-46a0-948e-005521edf124)/$value',
eodag:quicklook:'https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(396a9522-3f07-4645-9196-a65c349ad8e9)/$value',
eodag:thumbnail:'https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(396a9522-3f07-4645-9196-a65c349ad8e9)/$value',
grid:code:'MGRS-31TEJ',
order:status:'succeeded',
processing:datetime:'2024-07-03T11:43:18.000000Z',
processing:level:'S2MSI1C',
processing:version:'05.10',
product:type:'S2MSI1C',
s2:datastrip_id:'S2B_OPER_MSI_L1C_DS_2BPS_20240703T114318_S20240703T104623_N05.10',
s2:datatake_id:'GS2B_20240703T104629_038258_N05.10',
s2:datatake_type:'INS-NOBS',
s2:tile_id:'S2B_OPER_MSI_L1C_TL_2BPS_20240703T114318_A038258_T31TEJ_N05.10',
sat:absolute_orbit:38258,
sat:relative_orbit:51,
}
\n", + "
assets: (0)
\n", + "
geometry
thumbnail
" + ], + "text/plain": [ + "EOProduct(id=S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318, provider=cop_dataspace)" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "EOProduct.from_dict(product_dict, dag=dag)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `EOProduct.from_file`\n", + "\n", + "[EOProduct.from_file()](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct.from_file) will build a [EOProduct](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct) from a serialized Feature / STAC item file. If `dag` parameter is given, the method will use it to register the product downloader. If not provided, the downloader and authenticator will not be registered." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " EOProduct\n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
provider:'cop_dataspace',
collection:'S2_MSI_L1C',
properties["id"]:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
properties["start_datetime"]:'2024-07-03T10:46:29.024000Z',
properties["end_datetime"]:'2024-07-03T10:46:29.024000Z',
\n", + "
properties: (30){\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
constellation:'SENTINEL-2',
datetime:'2024-07-03T10:46:29.024000Z',
end_datetime:'2024-07-03T10:46:29.024000Z',
id:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
instruments:['MSI'\n", + " ],
platform:'S2B',
providers:[{\n", + " 'name': 'ESA'\n", + " , \n", + " 'roles': ['producer'\n", + " ]\n", + " }\n", + " ,
{\n", + " 'name': 'cop_dataspace'\n", + " , \n", + " 'roles': ['host'\n", + " ]\n", + " }\n", + " ],
published:'2024-07-03T12:42:14.249198Z',
start_datetime:'2024-07-03T10:46:29.024000Z',
title:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
uid:'c010825a-c3a6-46a0-948e-005521edf124',
updated:'2024-11-09T03:15:32.907273Z',
cop_dataspace:sourceProduct:'S2B_OPER_MSI_L1C_TL_2BPS_20240703T114318_A038258_T31TEJ_N05.10,S2B_OPER_MSI_L1C_DS_2BPS_20240703T114318_S20240703T104623_N05.10,S2B_OPER_MSI_L1C_TC_2BPS_20240703T114318_A038258_T31TEJ_N05.10.jp2',
cop_dataspace:sourceProductOriginDate:'2024-07-03T12:35:09Z,2024-07-03T12:23:12Z,2024-07-03T12:35:09Z',
eo:cloud_cover:14.423965639102,
eodag:download_link:'https://catalogue.dataspace.copernicus.eu/odata/v1/Products(c010825a-c3a6-46a0-948e-005521edf124)/$value',
eodag:quicklook:'https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(396a9522-3f07-4645-9196-a65c349ad8e9)/$value',
eodag:thumbnail:'https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(396a9522-3f07-4645-9196-a65c349ad8e9)/$value',
grid:code:'MGRS-31TEJ',
order:status:'succeeded',
processing:datetime:'2024-07-03T11:43:18.000000Z',
processing:level:'S2MSI1C',
processing:version:'05.10',
product:type:'S2MSI1C',
s2:datastrip_id:'S2B_OPER_MSI_L1C_DS_2BPS_20240703T114318_S20240703T104623_N05.10',
s2:datatake_id:'GS2B_20240703T104629_038258_N05.10',
s2:datatake_type:'INS-NOBS',
s2:tile_id:'S2B_OPER_MSI_L1C_TL_2BPS_20240703T114318_A038258_T31TEJ_N05.10',
sat:absolute_orbit:38258,
sat:relative_orbit:51,
}
\n", + "
assets: (0)
\n", + "
geometry
thumbnail
" + ], + "text/plain": [ + "EOProduct(id=S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318, provider=cop_dataspace)" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# save serialized to file\n", + "product_filepath = Path(workspace) / \"product.json\"\n", + "with open(product_filepath, \"w\") as f:\n", + " json.dump(product_dict, f)\n", + "\n", + "# build EOProduct from file\n", + "EOProduct.from_file(product_filepath, dag=dag)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `EOProduct.from_pystac`\n", + "\n", + "[EOProduct.from_pystac()](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct.from_pystac) will build a [EOProduct](../../api_reference/eoproduct.rst#eodag.api.product._product.EOProduct) from a [pystac.Item](https://pystac.readthedocs.io/en/stable/api/item.html#pystac-item). If `dag` parameter is given, the method will use it to register the product downloader. If not provided, the downloader and authenticator will not be registered." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " EOProduct\n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
provider:'cop_dataspace',
collection:'S2_MSI_L1C',
properties["id"]:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
properties["start_datetime"]:'2024-07-03T10:46:29.024000Z',
properties["end_datetime"]:'2024-07-03T10:46:29.024000Z',
\n", + "
properties: (30){\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
constellation:'SENTINEL-2',
datetime:'2024-07-03T10:46:29.024000Z',
end_datetime:'2024-07-03T10:46:29.024000Z',
id:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
instruments:['MSI'\n", + " ],
platform:'S2B',
providers:[{\n", + " 'name': 'ESA'\n", + " , \n", + " 'roles': ['producer'\n", + " ]\n", + " }\n", + " ,
{\n", + " 'name': 'cop_dataspace'\n", + " , \n", + " 'roles': ['host'\n", + " ]\n", + " }\n", + " ],
published:'2024-07-03T12:42:14.249198Z',
start_datetime:'2024-07-03T10:46:29.024000Z',
title:'S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318',
uid:'c010825a-c3a6-46a0-948e-005521edf124',
updated:'2024-11-09T03:15:32.907273Z',
cop_dataspace:sourceProduct:'S2B_OPER_MSI_L1C_TL_2BPS_20240703T114318_A038258_T31TEJ_N05.10,S2B_OPER_MSI_L1C_DS_2BPS_20240703T114318_S20240703T104623_N05.10,S2B_OPER_MSI_L1C_TC_2BPS_20240703T114318_A038258_T31TEJ_N05.10.jp2',
cop_dataspace:sourceProductOriginDate:'2024-07-03T12:35:09Z,2024-07-03T12:23:12Z,2024-07-03T12:35:09Z',
eo:cloud_cover:14.423965639102,
eodag:download_link:'https://catalogue.dataspace.copernicus.eu/odata/v1/Products(c010825a-c3a6-46a0-948e-005521edf124)/$value',
eodag:quicklook:'https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(396a9522-3f07-4645-9196-a65c349ad8e9)/$value',
eodag:thumbnail:'https://catalogue.dataspace.copernicus.eu/odata/v1/Assets(396a9522-3f07-4645-9196-a65c349ad8e9)/$value',
grid:code:'MGRS-31TEJ',
order:status:'succeeded',
processing:datetime:'2024-07-03T11:43:18.000000Z',
processing:level:'S2MSI1C',
processing:version:'05.10',
product:type:'S2MSI1C',
s2:datastrip_id:'S2B_OPER_MSI_L1C_DS_2BPS_20240703T114318_S20240703T104623_N05.10',
s2:datatake_id:'GS2B_20240703T104629_038258_N05.10',
s2:datatake_type:'INS-NOBS',
s2:tile_id:'S2B_OPER_MSI_L1C_TL_2BPS_20240703T114318_A038258_T31TEJ_N05.10',
sat:absolute_orbit:38258,
sat:relative_orbit:51,
}
\n", + "
assets: (0)
\n", + "
geometry
thumbnail
" + ], + "text/plain": [ + "EOProduct(id=S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318, provider=cop_dataspace)" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "EOProduct.from_pystac(pystac_item, dag=dag)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -6895,7 +11228,13 @@ "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { - "2747b2b5af8343c289851da9b0a309db": { + "2ff09d229b9f4b5b93d4598a17734eff": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "35485bd4633542f28371fb15cd7392d8": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -6905,19 +11244,7 @@ "width": "100%" } }, - "39a610f85fd14f189c68f0de842e0621": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "2.0.0", - "model_name": "FloatProgressModel", - "state": { - "bar_style": "success", - "layout": "IPY_MODEL_aafea1095e924d3b9ae8752fa7f980e9", - "max": 66, - "style": "IPY_MODEL_86577094c9e740358b0dde7b2923d21b", - "value": 66 - } - }, - "585786b05d854294a98e433eb4958852": { + "50dffc8f53f94308b166efa05d622404": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", @@ -6927,13 +11254,17 @@ "text_color": null } }, - "5971b535b78845edb6cdc300729151f7": { - "model_module": "@jupyter-widgets/base", + "56971c898d4846ea862baec6cde585f6": { + "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": {} + "model_name": "HTMLModel", + "state": { + "layout": "IPY_MODEL_95aa05c7fbe24a6fa2d6f6f5f7a7d248", + "style": "IPY_MODEL_50dffc8f53f94308b166efa05d622404", + "value": "Extracting files from S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318.zip: 100%" + } }, - "86577094c9e740358b0dde7b2923d21b": { + "7f791d380f6a4ec7bbbe2f5a6716dae3": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", @@ -6941,61 +11272,63 @@ "description_width": "" } }, - "923f007a09694a2389613ea6c8460039": { + "7fc000303b3043439f9bd107624043e3": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", - "model_name": "HTMLStyleModel", + "model_name": "HTMLModel", "state": { - "description_width": "", - "font_size": null, - "text_color": null + "layout": "IPY_MODEL_2ff09d229b9f4b5b93d4598a17734eff", + "style": "IPY_MODEL_96b8942ba0c44aa491862fbf51b724fb", + "value": " 66/66 [00:00<00:00, 2357.01file/s]" } }, - "a40e99eacde04f12bf2dcb21cbc3e816": { + "95aa05c7fbe24a6fa2d6f6f5f7a7d248": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {} }, - "aafea1095e924d3b9ae8752fa7f980e9": { - "model_module": "@jupyter-widgets/base", + "96b8942ba0c44aa491862fbf51b724fb": { + "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", - "model_name": "LayoutModel", + "model_name": "HTMLStyleModel", "state": { - "flex": "2" + "description_width": "", + "font_size": null, + "text_color": null } }, - "c1e4ded5c506498c8d86591db8490b6b": { + "ab8dda07667546088a42b2e2d05cbcae": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": { "children": [ - "IPY_MODEL_d497feaf86ee4761b32422155f1cf761", - "IPY_MODEL_39a610f85fd14f189c68f0de842e0621", - "IPY_MODEL_da93b50aae2248ae831092f1e55f5d0a" + "IPY_MODEL_56971c898d4846ea862baec6cde585f6", + "IPY_MODEL_b0dfa81fa51d4738ab4b1ed6676e1d9c", + "IPY_MODEL_7fc000303b3043439f9bd107624043e3" ], - "layout": "IPY_MODEL_2747b2b5af8343c289851da9b0a309db" + "layout": "IPY_MODEL_35485bd4633542f28371fb15cd7392d8" } }, - "d497feaf86ee4761b32422155f1cf761": { + "b0dfa81fa51d4738ab4b1ed6676e1d9c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", - "model_name": "HTMLModel", + "model_name": "FloatProgressModel", "state": { - "layout": "IPY_MODEL_5971b535b78845edb6cdc300729151f7", - "style": "IPY_MODEL_585786b05d854294a98e433eb4958852", - "value": "Extracting files from S2B_MSIL1C_20240703T104629_N0510_R051_T31TEJ_20240703T114318.zip: 100%" + "bar_style": "success", + "layout": "IPY_MODEL_f94358d23dae46379a7f74b3701220b6", + "max": 66, + "style": "IPY_MODEL_7f791d380f6a4ec7bbbe2f5a6716dae3", + "value": 66 } }, - "da93b50aae2248ae831092f1e55f5d0a": { - "model_module": "@jupyter-widgets/controls", + "f94358d23dae46379a7f74b3701220b6": { + "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", - "model_name": "HTMLModel", + "model_name": "LayoutModel", "state": { - "layout": "IPY_MODEL_a40e99eacde04f12bf2dcb21cbc3e816", - "style": "IPY_MODEL_923f007a09694a2389613ea6c8460039", - "value": " 66/66 [00:00<00:00, 2119.81file/s]" + "flex": "2" } } }, diff --git a/eodag/api/product/_product.py b/eodag/api/product/_product.py index e6f94e0eb3..da7c63308f 100644 --- a/eodag/api/product/_product.py +++ b/eodag/api/product/_product.py @@ -28,6 +28,7 @@ import geojson import orjson import requests +from pystac import Item from requests import RequestException from requests.auth import AuthBase from shapely import geometry @@ -302,6 +303,15 @@ def as_dict(self, skip_invalid: bool = True) -> dict[str, Any]: } return geojson_repr + def as_pystac_object(self, skip_invalid: bool = True) -> Item: + """Builds a representation of EOProduct as a pystac Item to enable its manipulation with pystac methods + + :param skip_invalid: Whether to skip properties whose values are not valid according to the STAC specification. + :returns: The representation of a :class:`~eodag.api.product._product.EOProduct` as a :class:`pystac.Item` + """ + prod_dict = self.as_dict(skip_invalid=skip_invalid) + return Item.from_dict(prod_dict) + @classmethod def from_dict( cls, @@ -362,6 +372,27 @@ def from_file( return cls.from_dict(feature, dag=dag, raise_errors=raise_errors) + @classmethod + def from_pystac( + cls, + item: Item, + dag: Optional[EODataAccessGateway] = None, + raise_errors: bool = False, + ) -> EOProduct: + """Builds an :class:`~eodag.api.product._product.EOProduct` object from a pystac Item. + + :param item: The :class:`pystac.Item` containing the metadata of the product + :param dag: (optional) The EODataAccessGateway instance to use for registering the product downloader. If not + provided, the downloader and authenticator will not be registered. + :param raise_errors: (optional) Whether to raise exceptions in case of errors during the deserialize process. + If False, several import methods will be tried: from serialized, from eodag-server, from + known provider, from unknown provider. + :returns: An instance of :class:`~eodag.api.product._product.EOProduct` + :raises: :class:`~eodag.utils.exceptions.ValidationError` + """ + feature = item.to_dict() + return cls.from_dict(feature, dag=dag, raise_errors=raise_errors) + @classmethod @_deprecated( reason="Please use 'EOProduct.from_dict' instead", diff --git a/eodag/api/search_result.py b/eodag/api/search_result.py index 9d8a5640eb..5b7b69f9f0 100644 --- a/eodag/api/search_result.py +++ b/eodag/api/search_result.py @@ -22,6 +22,7 @@ from typing import TYPE_CHECKING, Annotated, Any, Iterable, Iterator, Optional, Union import geojson +from pystac import ItemCollection from shapely.geometry import GeometryCollection from shapely.geometry import mapping as shapely_mapping from shapely.geometry import shape @@ -235,6 +236,22 @@ def from_file( return cls.from_dict(feature, dag=dag) + @classmethod + def from_pystac( + cls, + item_collection: ItemCollection, + dag: Optional[EODataAccessGateway] = None, + ) -> SearchResult: + """Builds an :class:`~eodag.api.search_result.SearchResult` object from a pystac ItemCollection + + :param item_collection: The :class:`pystac.ItemCollection` containing the metadata of the products. + :param dag: (optional) The EODataAccessGateway instance to use for registering the products. + :returns: An eodag representation of a search result + """ + features_collection = item_collection.to_dict() + + return cls.from_dict(features_collection, dag=dag) + @staticmethod @_deprecated( reason="Please use 'SearchResult.from_dict' instead", @@ -315,6 +332,16 @@ def as_wkt_object(self, skip_invalid: bool = True) -> str: """ return self.as_shapely_geometry_object(skip_invalid=skip_invalid).wkt + def as_pystac_object(self, skip_invalid: bool = True) -> ItemCollection: + """Pystac ItemCollection representation of SearchResult + + :param skip_invalid: Whether to skip properties whose values are not valid according to the STAC specification. + :returns: The representation of a :class:`~eodag.api.search_result.SearchResult` as a + :class:`pystac.ItemCollection` + """ + results_dict = self.as_dict(skip_invalid=skip_invalid) + return ItemCollection.from_dict(results_dict) + @property def __geo_interface__(self) -> dict[str, Any]: """Implements the geo-interface protocol. diff --git a/tests/units/test_eoproduct.py b/tests/units/test_eoproduct.py index 3a9f8aa106..ffa8bbd5c0 100644 --- a/tests/units/test_eoproduct.py +++ b/tests/units/test_eoproduct.py @@ -29,6 +29,7 @@ import geojson import responses from lxml import html +from pystac import Item from shapely import geometry from eodag.config import PluginConfig @@ -784,3 +785,21 @@ def test_eoproduct_serialize(self): self.assertFalse( any("mgrs" in ext for ext in prod_dict.get("stac_extensions", [])) ) + + def test_eoproduct_as_pystac_object(self): + """eoproduct.as_pystac_object must return a pystac.Item""" + product = self._dummy_product( + properties={"id": "dummy_id", "datetime": "2021-01-01T00:00:00Z"} + ) + pystac_item = product.as_pystac_object() + self.assertIsInstance(pystac_item, Item) + pystac_item.validate() + + def test_eoproduct_from_pystac(self): + """eoproduct.from_pystac must return an EOProduct instance from a pystac.Item""" + product = self._dummy_product( + properties={"id": "dummy_id", "datetime": "2021-01-01T00:00:00Z"} + ) + pystac_item = Item.from_dict(product.as_dict()) + product_from_pystac = EOProduct.from_pystac(pystac_item) + self.assertIsInstance(product_from_pystac, EOProduct) diff --git a/tests/units/test_search_result.py b/tests/units/test_search_result.py index 8cc44a3e70..6ab4131a98 100644 --- a/tests/units/test_search_result.py +++ b/tests/units/test_search_result.py @@ -21,6 +21,7 @@ import geojson from lxml import html +from pystac import ItemCollection from shapely.geometry.collection import GeometryCollection from tests.context import EOProduct, SearchResult @@ -73,6 +74,10 @@ def test_search_result_as_wkt_object(self): self.assertIsInstance(wkt_object, str) self.assertTrue(wkt_object.startswith("GEOMETRYCOLLECTION")) + def test_search_result_as_pystac_object(self): + pystac_object = self.search_result.as_pystac_object() + self.assertIsInstance(pystac_object, ItemCollection) + def test_search_result_is_list_like(self): """SearchResult must provide a list interface""" self.assertIsInstance(self.search_result, UserList) @@ -84,6 +89,13 @@ def test_search_result_from_feature_collection(self): ) self.assertEqual(len(same_search_result), len(self.search_result)) + def test_search_result_from_pystac(self): + """SearchResult instances must be build-able from feature collection geojson""" + same_search_result = SearchResult.from_pystac( + ItemCollection.from_dict(self.search_result.as_dict()) + ) + self.assertEqual(len(same_search_result), len(self.search_result)) + def test_search_result_repr_html(self): """SearchResult html repr must be correctly formatted""" sr_repr = html.fromstring(self.search_result._repr_html_())