SmartCane/python_app/Chemba_download.ipynb
Martin Folkerts 2c84747ff0 wip
2024-01-22 09:54:15 +01:00

630 lines
51 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "b7ca7102-5fd9-481f-90cd-3ba60e288649",
"metadata": {},
"outputs": [],
"source": [
"# $ pip install sentinelhub\n",
"# pip install gdal\n",
"\n",
"import os\n",
"import datetime\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from pathlib import Path\n",
"from osgeo import gdal\n",
"\n",
"from sentinelhub import MimeType, CRS, BBox, SentinelHubRequest, SentinelHubDownloadClient, \\\n",
" DataCollection, bbox_to_dimensions, DownloadRequest, SHConfig, BBoxSplitter, read_data\n",
"\n",
"config = SHConfig()\n",
"\n",
"import time"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "330c967c-2742-4a7a-9a61-28bfdaf8eeca",
"metadata": {},
"outputs": [],
"source": [
"#pip install pipreqs"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "49f8496a-a267-4b74-9500-a168e031ed68",
"metadata": {},
"outputs": [],
"source": [
"#import pipreqs\n",
"#pipreqs Resilience BV/4002 CMD App - General/4002 CMD Team/4002 TechnicalData/04 WP2 technical/python/Chemba_download.ipynb"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "5491a840-779c-4f0c-8164-c3de738b3298",
"metadata": {},
"outputs": [],
"source": [
"config.sh_client_id = '1a72d811-4f0e-4447-8282-df09608cff44'\n",
"config.sh_client_secret = 'FcBlRL29i9ZmTzhmKTv1etSMFs5PxSos'"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "eb1fb662-0e25-4ca9-8317-c6953290842b",
"metadata": {},
"outputs": [],
"source": [
"collection_id = 'c691479f-358c-46b1-b0f0-e12b70a9856c'\n",
"byoc = DataCollection.define_byoc(\n",
" collection_id,\n",
" name='planet_data2',\n",
" is_timeless=True)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "244b5752-4f02-4347-9278-f6a0a46b88f4",
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'Path' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[13], line 101\u001b[0m\n\u001b[1;32m 41\u001b[0m evalscript_true_color \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\"\"\u001b[39m\n\u001b[1;32m 42\u001b[0m \u001b[38;5;124m //VERSION=3\u001b[39m\n\u001b[1;32m 43\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 79\u001b[0m \u001b[38;5;124m }\u001b[39m\n\u001b[1;32m 80\u001b[0m \u001b[38;5;124m\"\"\"\u001b[39m\n\u001b[1;32m 82\u001b[0m \u001b[38;5;66;03m#def get_true_color_request(time_interval):\u001b[39;00m\n\u001b[1;32m 83\u001b[0m \u001b[38;5;66;03m# return SentinelHubRequest(\u001b[39;00m\n\u001b[1;32m 84\u001b[0m \u001b[38;5;66;03m# evalscript=evalscript_true_color,\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 98\u001b[0m \u001b[38;5;66;03m#\u001b[39;00m\n\u001b[1;32m 99\u001b[0m \u001b[38;5;66;03m# )\u001b[39;00m\n\u001b[0;32m--> 101\u001b[0m BASE_PATH_SINGLE \u001b[38;5;241m=\u001b[39m Path(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m../laravel_app/storage/app/chemba/\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 102\u001b[0m BASE_PATH_SINGLE_IMAGES \u001b[38;5;241m=\u001b[39m Path(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m../laravel_app/storage/app/chemba/single_images\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 103\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_true_color_request_day_east\u001b[39m(time_interval):\n\u001b[1;32m 104\u001b[0m \u001b[38;5;66;03m#base_path = '../laravel_app/storage/app/chemba/single_images/'\u001b[39;00m\n",
"\u001b[0;31mNameError\u001b[0m: name 'Path' is not defined"
]
}
],
"source": [
"\"\"\"\n",
"Utilities used by example notebooks\n",
"\"\"\"\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"\n",
"#def plot_image(image, factor=1.0, clip_range=None, **kwargs):\n",
"# \"\"\"\n",
"# Utility function for plotting RGB images.\n",
"# \"\"\"\n",
"# fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15, 15))\n",
"# if clip_range is not None:\n",
"# ax.imshow(np.clip(image * factor, *clip_range), **kwargs)\n",
"# else:\n",
"## ax.imshow(image * factor, **kwargs)\n",
" # ax.set_xticks([])\n",
" # ax.set_yticks([]) \n",
"\n",
"\n",
"#evalscript_true_color = \"\"\"\n",
"# //VERSION=3\n",
"#\n",
"# function setup() {\n",
"# return {\n",
"# input: [{\n",
"# bands: [\"B1\", \"B2\", \"B3\", \"B4\", \"UDM\"]\n",
"# }],\n",
"# output: {\n",
"# bands: 5,\n",
"# nodataValue: NA\n",
"# }\n",
"# };\n",
"# }\n",
"#\n",
"# function evaluatePixel(sample) {\n",
"# return [2.5 * sample.B1 / 10000, 2.5 * sample.B2 / 10000, 2.5 * sample.B3 / 10000, 2.5 * sample.B4 / 10000, sample.UDM];\n",
"# }\n",
"#\"\"\"\n",
"\n",
"evalscript_true_color = \"\"\"\n",
" //VERSION=3\n",
"\n",
" function setup() {\n",
" return {\n",
" input: [{\n",
" bands: [\"Red\", \"Green\", \"Blue\", \"NIR\", \"UDM\"]\n",
" }],\n",
" output: {\n",
" bands: 2 \n",
" //sampleType: \"FLOAT32\"\n",
" }\n",
" };\n",
" }\n",
"\n",
" function evaluatePixel(sample) {\n",
" // Scale the bands\n",
" //var scaledBlue = [2.5 * sample.Blue / 10000];\n",
" var scaledGreen = [2.5 * sample.Green / 10000];\n",
" //var scaledRed = [2.5 * sample.Red / 10000];\n",
" var scaledNIR = [2.5 * sample.NIR / 10000];\n",
" \n",
" // Calculate the CI (Chlorophyll Index) using the scaled values\n",
" // var CI = [scaledNIR / scaledGreen - 1] ;\n",
"\n",
"// Output the scaled bands and CI\n",
" if (sample.UDM == 0) { \n",
" return [\n",
" //scaledRed,\n",
" scaledGreen,\n",
" // scaledBlue,\n",
" scaledNIR\n",
" // sample.UDM,\n",
" // CI,\n",
" ]\n",
" } else {\n",
" return [NaN, NaN]}\n",
" \n",
" }\n",
"\"\"\"\n",
"\n",
"#def get_true_color_request(time_interval):\n",
"# return SentinelHubRequest(\n",
"# evalscript=evalscript_true_color,\n",
"# input_data=[\n",
"# SentinelHubRequest.input_data(\n",
" # data_collection=DataCollection.planet_data2,\n",
"# time_interval=time_interval\n",
"# )\n",
"# ],\n",
"# responses=[\n",
"# SentinelHubRequest.output_response('default', MimeType.TIFF)\n",
"# ],\n",
"# bbox=chemba_bbox,\n",
"# size=chemba_size,\n",
"# config=config,\n",
"# data_folder='chemba_single_images/'+date,\n",
"#\n",
"# )\n",
"\n",
"BASE_PATH = Path('../laravel_app/storage/app') / os.getenv('PROJECT_DIR','chemba') \n",
"BASE_PATH_SINGLE_IMAGES = Path(BASE_PATH / 'single_images')\n",
"def get_true_color_request_day_east(time_interval):\n",
" return SentinelHubRequest(\n",
" evalscript=evalscript_true_color,\n",
" input_data=[\n",
" SentinelHubRequest.input_data(\n",
" data_collection=DataCollection.planet_data2,\n",
" time_interval=(time_interval, time_interval)\n",
" )\n",
" ],\n",
" responses=[\n",
" SentinelHubRequest.output_response('default', MimeType.TIFF)\n",
" ],\n",
" bbox=chemba_bbox_east,\n",
" size=chemba_size_east,\n",
" config=config,\n",
" data_folder=str(BASE_PATH_SINGLE_IMAGES / time_interval),\n",
"\n",
" )\n",
"\n",
"def get_true_color_request_day_west(time_interval):\n",
" return SentinelHubRequest(\n",
" evalscript=evalscript_true_color,\n",
" input_data=[\n",
" SentinelHubRequest.input_data(\n",
" data_collection=DataCollection.planet_data2,\n",
" time_interval=(time_interval, time_interval)\n",
" )\n",
" ],\n",
" responses=[\n",
" SentinelHubRequest.output_response('default', MimeType.TIFF)\n",
" ],\n",
" bbox=chemba_bbox_west,\n",
" size=chemba_size_west,\n",
" config=config,\n",
" data_folder=str(BASE_PATH_SINGLE_IMAGES / time_interval),\n",
"\n",
" )\n",
"\n",
"#def get_true_color_request_week(time_interval):\n",
"# return SentinelHubRequest(\n",
"# evalscript=evalscript_true_color,\n",
"# input_data=[\n",
"# SentinelHubRequest.input_data(\n",
"# data_collection=DataCollection.planet_data2,\n",
"# time_interval=time_interval\n",
"# )\n",
"# ],\n",
"# responses=[\n",
"# SentinelHubRequest.output_response('default', MimeType.TIFF)\n",
"# ],\n",
"# bbox=chemba_bbox,\n",
"# size=chemba_size,\n",
"# config=config,\n",
"# data_folder='chemba_weekly_img/'+date,\n",
"#\n",
" # )"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "5abb2cc0-5e2f-46cd-9676-3093d07b0624",
"metadata": {},
"outputs": [],
"source": [
"\n",
"#end = datetime.date.today() - datetime.timedelta(days=1)\n",
"#start = end - datetime.timedelta(days=6)\n",
"\n",
"#end = datetime.date(2022, 7, 1)\n",
"#start = datetime.date(2022, 7, 21)\n",
"\n",
"#n_chunks = start - end\n",
"#n_chunks.days\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "a4937240-27f9-44c3-ad9c-cec6f2ffe4c8",
"metadata": {},
"outputs": [],
"source": [
"#end = datetime.date(2022, 8, 4) \n",
"#start = datetime.date(2023, 3, 1)\n",
"#days_needed = 6#\n",
"\n",
"#end = datetime.date.today() - datetime.timedelta(days=days_needed - 1)\n",
"#start = end - datetime.timedelta(days=1)\n",
"\n",
"\n",
"#n_chunks = days_needed + 1\n",
"#tdelta = datetime.timedelta(days=1)\n",
"#edges = [(start + i*tdelta).isoformat() for i in range(n_chunks)]\n",
"#slots = [(edges[i], edges[i]) for i in range(len(edges))]\n",
"#slots = [(edges[i]) for i in range(len(edges))]\n",
"\n",
"#date = start.strftime(\"%Y-%m-%d\")\n",
"\n",
"#print('Monthly time windows:\\n')\n",
"#for slot in slots:\n",
"# print(slot)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "848dc773-70d6-4ae6-b05c-d6ebfb41624d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Monthly time windows:\n",
"\n",
"2023-11-11\n",
"2023-11-12\n",
"2023-11-13\n",
"2023-11-14\n",
"2023-11-15\n",
"2023-11-16\n",
"2023-11-17\n",
"2023-11-18\n",
"2023-11-19\n",
"2023-11-20\n",
"2023-11-21\n",
"2023-11-22\n",
"2023-11-23\n",
"2023-11-24\n",
"2023-11-25\n",
"2023-11-26\n",
"2023-11-27\n",
"2023-11-28\n",
"2023-11-29\n",
"2023-11-30\n",
"2023-12-01\n",
"2023-12-02\n",
"2023-12-03\n",
"2023-12-04\n",
"2023-12-05\n",
"2023-12-06\n",
"2023-12-07\n",
"2023-12-08\n"
]
}
],
"source": [
"import datetime\n",
"\n",
"days_needed = int(os.environ.get(\"DAYS\", 28))\n",
" # Adjust the number of days needed\n",
" \n",
"date_str = os.environ.get(\"DATE\")\n",
"if date_str:\n",
" # Parse de datumstring naar een datetime.date object\n",
" end = datetime.datetime.strptime(date_str, \"%Y-%m-%d\").date()\n",
"else:\n",
" # Gebruik de huidige datum als fallback\n",
" end = datetime.date.today() \n",
"\n",
"\n",
"#end = datetime.datetime(2023, 11, 10)\n",
"#start = datetime.datetime(2023, 10, 19)\n",
"start = end - datetime.timedelta(days=days_needed - 1)\n",
"\n",
"slots = [(start + datetime.timedelta(days=i)).strftime('%Y-%m-%d') for i in range(days_needed)]\n",
"\n",
"print('Monthly time windows:\\n')\n",
"for slot in slots:\n",
" print(slot)\n"
]
},
{
"cell_type": "markdown",
"id": "0c18e312-8421-47d7-84f9-ed7d5e47e7ee",
"metadata": {},
"source": [
"### Download images\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "2335139b-dfb1-4371-ae2c-c2b9c8cbf10c",
"metadata": {},
"outputs": [],
"source": [
"chemba_east = [34.8830, -17.3516, 34.9380, -17.2917]\n",
"resolution = 3\n",
"chemba_bbox_east = BBox(bbox=chemba_east, crs=CRS.WGS84)\n",
"chemba_size_east = bbox_to_dimensions(chemba_bbox_east, resolution=resolution)\n",
"\n",
"chemba_west = [34.9460, -17.3500, 34.9839, -17.3110]\n",
"chemba_bbox_west = BBox(bbox=chemba_west, crs=CRS.WGS84)\n",
"chemba_size_west = bbox_to_dimensions(chemba_bbox_west, resolution=resolution)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "77513576-2fed-4d17-a665-d11267b42390",
"metadata": {},
"outputs": [],
"source": [
"def download_function(slot):\n",
" ### Chemba east side\n",
" # create a list of requests \n",
" list_of_requests = [get_true_color_request_day_east(slot)]\n",
" list_of_requests = [request.download_list[0] for request in list_of_requests]\n",
"\n",
" # download data chemba east with multiple threads\n",
" data = SentinelHubDownloadClient(config=config).download(list_of_requests, max_threads=15)\n",
" print(f' East downloaded ' +slot)\n",
"\n",
" ### Chemba west side\n",
" # create a list of requests\n",
" list_of_requests = [get_true_color_request_day_west(slot)]\n",
" list_of_requests = [request.download_list[0] for request in list_of_requests]\n",
"\n",
" # download data chemba west with multiple threads\n",
" data = SentinelHubDownloadClient(config=config).download(list_of_requests, max_threads=15)\n",
" print(f' West downloaded ' +slot)\n",
" \n",
" time.sleep(.5)\n",
"\n",
"def merge_files(slot):\n",
" \n",
" # List the downloaded Tiffs in the different subfolders with pathlib (native library)\n",
" file_list = [f\"{x}/response.tiff\" for x in Path(BASE_PATH_SINGLE_IMAGES / slot).iterdir()]\n",
" print(file_list)\n",
"\n",
" folder_for_merged_tifs = str(BASE_PATH / 'merged_tif' / f\"{slot}.tif\")\n",
" folder_for_virtual_raster = str(BASE_PATH / 'merged_virtual' / f\"merged{slot}.vrt\")\n",
"\n",
" # Create a virtual raster\n",
" vrt_all = gdal.BuildVRT(folder_for_virtual_raster, file_list)\n",
" vrt_all = gdal.BuildVRT(folder_for_virtual_raster, file_list)\n",
"\n",
" # Convert to JPEG\n",
" gdal.Translate(folder_for_merged_tifs,folder_for_virtual_raster)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "d5830b6e-da0a-416f-867e-cbca4bd434f5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" East downloaded 2023-11-11\n",
" West downloaded 2023-11-11\n",
" East downloaded 2023-11-12\n",
" West downloaded 2023-11-12\n",
" East downloaded 2023-11-13\n",
" West downloaded 2023-11-13\n",
" East downloaded 2023-11-14\n",
" West downloaded 2023-11-14\n",
" East downloaded 2023-11-15\n",
" West downloaded 2023-11-15\n",
" East downloaded 2023-11-16\n",
" West downloaded 2023-11-16\n",
" East downloaded 2023-11-17\n",
" West downloaded 2023-11-17\n",
" East downloaded 2023-11-18\n",
" West downloaded 2023-11-18\n",
" East downloaded 2023-11-19\n",
" West downloaded 2023-11-19\n",
" East downloaded 2023-11-20\n",
" West downloaded 2023-11-20\n",
" East downloaded 2023-11-21\n",
" West downloaded 2023-11-21\n",
" East downloaded 2023-11-22\n",
" West downloaded 2023-11-22\n",
" East downloaded 2023-11-23\n",
" West downloaded 2023-11-23\n",
" East downloaded 2023-11-24\n",
" West downloaded 2023-11-24\n",
" East downloaded 2023-11-25\n",
" West downloaded 2023-11-25\n",
" East downloaded 2023-11-26\n",
" West downloaded 2023-11-26\n",
" East downloaded 2023-11-27\n",
" West downloaded 2023-11-27\n",
" East downloaded 2023-11-28\n",
" West downloaded 2023-11-28\n",
" East downloaded 2023-11-29\n",
" West downloaded 2023-11-29\n",
" East downloaded 2023-11-30\n",
" West downloaded 2023-11-30\n",
" East downloaded 2023-12-01\n",
" West downloaded 2023-12-01\n",
" East downloaded 2023-12-02\n",
" West downloaded 2023-12-02\n",
" East downloaded 2023-12-03\n",
" West downloaded 2023-12-03\n",
" East downloaded 2023-12-04\n",
" West downloaded 2023-12-04\n",
" East downloaded 2023-12-05\n",
" West downloaded 2023-12-05\n"
]
},
{
"ename": "UnauthorizedClientError",
"evalue": "(unauthorized_client) Unexpected error when authenticating client",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mUnauthorizedClientError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[12], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m slot \u001b[38;5;129;01min\u001b[39;00m slots:\n\u001b[0;32m----> 2\u001b[0m download_function(slot)\n",
"Cell \u001b[0;32mIn[11], line 8\u001b[0m, in \u001b[0;36mdownload_function\u001b[0;34m(slot)\u001b[0m\n\u001b[1;32m 5\u001b[0m list_of_requests \u001b[38;5;241m=\u001b[39m [request\u001b[38;5;241m.\u001b[39mdownload_list[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;28;01mfor\u001b[39;00m request \u001b[38;5;129;01min\u001b[39;00m list_of_requests]\n\u001b[1;32m 7\u001b[0m \u001b[38;5;66;03m# download data chemba east with multiple threads\u001b[39;00m\n\u001b[0;32m----> 8\u001b[0m data \u001b[38;5;241m=\u001b[39m SentinelHubDownloadClient(config\u001b[38;5;241m=\u001b[39mconfig)\u001b[38;5;241m.\u001b[39mdownload(list_of_requests, max_threads\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m15\u001b[39m)\n\u001b[1;32m 9\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m East downloaded \u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m+\u001b[39mslot)\n\u001b[1;32m 11\u001b[0m \u001b[38;5;66;03m### Chemba west side\u001b[39;00m\n\u001b[1;32m 12\u001b[0m \u001b[38;5;66;03m# create a list of requests\u001b[39;00m\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/sentinelhub_client.py:62\u001b[0m, in \u001b[0;36mSentinelHubDownloadClient.download\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 60\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlock \u001b[38;5;241m=\u001b[39m Lock()\n\u001b[1;32m 61\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 62\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mdownload(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 63\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 64\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlock \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/client.py:101\u001b[0m, in \u001b[0;36mDownloadClient.download\u001b[0;34m(self, download_requests, max_threads, decode_data, show_progress)\u001b[0m\n\u001b[1;32m 99\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m future \u001b[38;5;129;01min\u001b[39;00m as_completed(download_list):\n\u001b[1;32m 100\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 101\u001b[0m results[future_order[future]] \u001b[38;5;241m=\u001b[39m future\u001b[38;5;241m.\u001b[39mresult()\n\u001b[1;32m 102\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m DownloadFailedException \u001b[38;5;28;01mas\u001b[39;00m download_exception:\n\u001b[1;32m 103\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mraise_download_errors:\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/concurrent/futures/_base.py:449\u001b[0m, in \u001b[0;36mFuture.result\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 447\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m CancelledError()\n\u001b[1;32m 448\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_state \u001b[38;5;241m==\u001b[39m FINISHED:\n\u001b[0;32m--> 449\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__get_result()\n\u001b[1;32m 451\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_condition\u001b[38;5;241m.\u001b[39mwait(timeout)\n\u001b[1;32m 453\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_state \u001b[38;5;129;01min\u001b[39;00m [CANCELLED, CANCELLED_AND_NOTIFIED]:\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/concurrent/futures/_base.py:401\u001b[0m, in \u001b[0;36mFuture.__get_result\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 399\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_exception:\n\u001b[1;32m 400\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 401\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_exception\n\u001b[1;32m 402\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 403\u001b[0m \u001b[38;5;66;03m# Break a reference cycle with the exception in self._exception\u001b[39;00m\n\u001b[1;32m 404\u001b[0m \u001b[38;5;28mself\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/concurrent/futures/thread.py:58\u001b[0m, in \u001b[0;36m_WorkItem.run\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[1;32m 57\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 58\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfn(\u001b[38;5;241m*\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkwargs)\n\u001b[1;32m 59\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[1;32m 60\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfuture\u001b[38;5;241m.\u001b[39mset_exception(exc)\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/client.py:117\u001b[0m, in \u001b[0;36mDownloadClient._single_download_decoded\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 115\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_single_download_decoded\u001b[39m(\u001b[38;5;28mself\u001b[39m, request: DownloadRequest) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Any:\n\u001b[1;32m 116\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Downloads a response and decodes it into data. By decoding a single response\"\"\"\u001b[39;00m\n\u001b[0;32m--> 117\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_single_download(request)\n\u001b[1;32m 118\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01mif\u001b[39;00m response \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m response\u001b[38;5;241m.\u001b[39mdecode()\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/client.py:130\u001b[0m, in \u001b[0;36mDownloadClient._single_download\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 128\u001b[0m no_local_data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mredownload \u001b[38;5;129;01mor\u001b[39;00m response_path \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mexists(response_path)\n\u001b[1;32m 129\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m no_local_data:\n\u001b[0;32m--> 130\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_execute_download(request)\n\u001b[1;32m 131\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 132\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m request\u001b[38;5;241m.\u001b[39mreturn_data \u001b[38;5;129;01mor\u001b[39;00m response_path \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/handlers.py:64\u001b[0m, in \u001b[0;36mretry_temporary_errors.<locals>.new_download_func\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 62\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m attempt_idx \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(download_attempts):\n\u001b[1;32m 63\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 64\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m download_func(\u001b[38;5;28mself\u001b[39m, request)\n\u001b[1;32m 66\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m requests\u001b[38;5;241m.\u001b[39mRequestException \u001b[38;5;28;01mas\u001b[39;00m exception:\n\u001b[1;32m 67\u001b[0m attempts_left \u001b[38;5;241m=\u001b[39m download_attempts \u001b[38;5;241m-\u001b[39m (attempt_idx \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m1\u001b[39m)\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/handlers.py:37\u001b[0m, in \u001b[0;36mfail_user_errors.<locals>.new_download_func\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[38;5;129m@functools\u001b[39m\u001b[38;5;241m.\u001b[39mwraps(download_func)\n\u001b[1;32m 35\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mnew_download_func\u001b[39m(\u001b[38;5;28mself\u001b[39m: Self, request: DownloadRequest) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m T:\n\u001b[1;32m 36\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 37\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m download_func(\u001b[38;5;28mself\u001b[39m, request)\n\u001b[1;32m 38\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m requests\u001b[38;5;241m.\u001b[39mHTTPError \u001b[38;5;28;01mas\u001b[39;00m exception:\n\u001b[1;32m 39\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[1;32m 40\u001b[0m exception\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mstatus_code \u001b[38;5;241m<\u001b[39m requests\u001b[38;5;241m.\u001b[39mstatus_codes\u001b[38;5;241m.\u001b[39mcodes\u001b[38;5;241m.\u001b[39mINTERNAL_SERVER_ERROR\n\u001b[1;32m 41\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m exception\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mstatus_code \u001b[38;5;241m!=\u001b[39m requests\u001b[38;5;241m.\u001b[39mstatus_codes\u001b[38;5;241m.\u001b[39mcodes\u001b[38;5;241m.\u001b[39mTOO_MANY_REQUESTS\n\u001b[1;32m 42\u001b[0m ):\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/sentinelhub_client.py:82\u001b[0m, in \u001b[0;36mSentinelHubDownloadClient._execute_download\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 75\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m sleep_time \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m 76\u001b[0m LOGGER\u001b[38;5;241m.\u001b[39mdebug(\n\u001b[1;32m 77\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSending \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m request to \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m. Hash of sent request is \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 78\u001b[0m request\u001b[38;5;241m.\u001b[39mrequest_type\u001b[38;5;241m.\u001b[39mvalue,\n\u001b[1;32m 79\u001b[0m request\u001b[38;5;241m.\u001b[39murl,\n\u001b[1;32m 80\u001b[0m request\u001b[38;5;241m.\u001b[39mget_hashed_name(),\n\u001b[1;32m 81\u001b[0m )\n\u001b[0;32m---> 82\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_do_download(request)\n\u001b[1;32m 84\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_execute_thread_safe(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrate_limit\u001b[38;5;241m.\u001b[39mupdate, response\u001b[38;5;241m.\u001b[39mheaders)\n\u001b[1;32m 86\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m response\u001b[38;5;241m.\u001b[39mstatus_code \u001b[38;5;241m==\u001b[39m requests\u001b[38;5;241m.\u001b[39mstatus_codes\u001b[38;5;241m.\u001b[39mcodes\u001b[38;5;241m.\u001b[39mTOO_MANY_REQUESTS:\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/sentinelhub_client.py:115\u001b[0m, in \u001b[0;36mSentinelHubDownloadClient._do_download\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 108\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m request\u001b[38;5;241m.\u001b[39murl \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 109\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFaulty request \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrequest\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, no URL specified.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 111\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m requests\u001b[38;5;241m.\u001b[39mrequest(\n\u001b[1;32m 112\u001b[0m request\u001b[38;5;241m.\u001b[39mrequest_type\u001b[38;5;241m.\u001b[39mvalue,\n\u001b[1;32m 113\u001b[0m url\u001b[38;5;241m=\u001b[39mrequest\u001b[38;5;241m.\u001b[39murl,\n\u001b[1;32m 114\u001b[0m json\u001b[38;5;241m=\u001b[39mrequest\u001b[38;5;241m.\u001b[39mpost_values,\n\u001b[0;32m--> 115\u001b[0m headers\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_prepare_headers(request),\n\u001b[1;32m 116\u001b[0m timeout\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39mdownload_timeout_seconds,\n\u001b[1;32m 117\u001b[0m )\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/sentinelhub_client.py:126\u001b[0m, in \u001b[0;36mSentinelHubDownloadClient._prepare_headers\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 124\u001b[0m session_headers: JsonDict \u001b[38;5;241m=\u001b[39m {}\n\u001b[1;32m 125\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m request\u001b[38;5;241m.\u001b[39muse_session:\n\u001b[0;32m--> 126\u001b[0m session_headers \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_execute_thread_safe(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_session_headers)\n\u001b[1;32m 128\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m {\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mSHConstants\u001b[38;5;241m.\u001b[39mHEADERS, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msession_headers, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mrequest\u001b[38;5;241m.\u001b[39mheaders}\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/sentinelhub_client.py:104\u001b[0m, in \u001b[0;36mSentinelHubDownloadClient._execute_thread_safe\u001b[0;34m(self, thread_unsafe_function, *args, **kwargs)\u001b[0m\n\u001b[1;32m 101\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m thread_unsafe_function(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 103\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlock:\n\u001b[0;32m--> 104\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m thread_unsafe_function(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/sentinelhub_client.py:136\u001b[0m, in \u001b[0;36mSentinelHubDownloadClient._get_session_headers\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 130\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_get_session_headers\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m JsonDict:\n\u001b[1;32m 131\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Provides up-to-date session headers\u001b[39;00m\n\u001b[1;32m 132\u001b[0m \n\u001b[1;32m 133\u001b[0m \u001b[38;5;124;03m Note that calling session_headers property triggers update if session has expired therefore this has to be\u001b[39;00m\n\u001b[1;32m 134\u001b[0m \u001b[38;5;124;03m called in a thread-safe way\u001b[39;00m\n\u001b[1;32m 135\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 136\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_session()\u001b[38;5;241m.\u001b[39msession_headers\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/sentinelhub_client.py:152\u001b[0m, in \u001b[0;36mSentinelHubDownloadClient.get_session\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 150\u001b[0m session \u001b[38;5;241m=\u001b[39m SentinelHubDownloadClient\u001b[38;5;241m.\u001b[39m_CACHED_SESSIONS[SentinelHubDownloadClient\u001b[38;5;241m.\u001b[39m_UNIVERSAL_CACHE_KEY]\n\u001b[1;32m 151\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 152\u001b[0m session \u001b[38;5;241m=\u001b[39m SentinelHubSession(config\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig)\n\u001b[1;32m 153\u001b[0m SentinelHubDownloadClient\u001b[38;5;241m.\u001b[39m_CACHED_SESSIONS[cache_key] \u001b[38;5;241m=\u001b[39m session\n\u001b[1;32m 155\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m session\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/session.py:75\u001b[0m, in \u001b[0;36mSentinelHubSession.__init__\u001b[0;34m(self, config, refresh_before_expiry, _token)\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m token_fetching_required \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39msh_client_id \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39msh_client_secret):\n\u001b[1;32m 69\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 70\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mConfiguration parameters \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msh_client_id\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m and \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msh_client_secret\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m have to be set in order \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 71\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mto authenticate with Sentinel Hub service. Check \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 72\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttps://sentinelhub-py.readthedocs.io/en/latest/configure.html for more info.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 73\u001b[0m )\n\u001b[0;32m---> 75\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_token \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_collect_new_token() \u001b[38;5;28;01mif\u001b[39;00m _token \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m _token\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/session.py:129\u001b[0m, in \u001b[0;36mSentinelHubSession._collect_new_token\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Creates a download request and fetches a token from the service.\u001b[39;00m\n\u001b[1;32m 124\u001b[0m \n\u001b[1;32m 125\u001b[0m \u001b[38;5;124;03mNote that the `DownloadRequest` object is created only because retry decorators of `_fetch_token` method\u001b[39;00m\n\u001b[1;32m 126\u001b[0m \u001b[38;5;124;03mrequire it.\u001b[39;00m\n\u001b[1;32m 127\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 128\u001b[0m request \u001b[38;5;241m=\u001b[39m DownloadRequest(url\u001b[38;5;241m=\u001b[39m\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39msh_token_url\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 129\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_fetch_token(request)\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/handlers.py:64\u001b[0m, in \u001b[0;36mretry_temporary_errors.<locals>.new_download_func\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 62\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m attempt_idx \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(download_attempts):\n\u001b[1;32m 63\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 64\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m download_func(\u001b[38;5;28mself\u001b[39m, request)\n\u001b[1;32m 66\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m requests\u001b[38;5;241m.\u001b[39mRequestException \u001b[38;5;28;01mas\u001b[39;00m exception:\n\u001b[1;32m 67\u001b[0m attempts_left \u001b[38;5;241m=\u001b[39m download_attempts \u001b[38;5;241m-\u001b[39m (attempt_idx \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m1\u001b[39m)\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/handlers.py:37\u001b[0m, in \u001b[0;36mfail_user_errors.<locals>.new_download_func\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[38;5;129m@functools\u001b[39m\u001b[38;5;241m.\u001b[39mwraps(download_func)\n\u001b[1;32m 35\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mnew_download_func\u001b[39m(\u001b[38;5;28mself\u001b[39m: Self, request: DownloadRequest) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m T:\n\u001b[1;32m 36\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 37\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m download_func(\u001b[38;5;28mself\u001b[39m, request)\n\u001b[1;32m 38\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m requests\u001b[38;5;241m.\u001b[39mHTTPError \u001b[38;5;28;01mas\u001b[39;00m exception:\n\u001b[1;32m 39\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[1;32m 40\u001b[0m exception\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mstatus_code \u001b[38;5;241m<\u001b[39m requests\u001b[38;5;241m.\u001b[39mstatus_codes\u001b[38;5;241m.\u001b[39mcodes\u001b[38;5;241m.\u001b[39mINTERNAL_SERVER_ERROR\n\u001b[1;32m 41\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m exception\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mstatus_code \u001b[38;5;241m!=\u001b[39m requests\u001b[38;5;241m.\u001b[39mstatus_codes\u001b[38;5;241m.\u001b[39mcodes\u001b[38;5;241m.\u001b[39mTOO_MANY_REQUESTS\n\u001b[1;32m 42\u001b[0m ):\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/sentinelhub/download/session.py:141\u001b[0m, in \u001b[0;36mSentinelHubSession._fetch_token\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 138\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m OAuth2Session(client\u001b[38;5;241m=\u001b[39moauth_client) \u001b[38;5;28;01mas\u001b[39;00m oauth_session:\n\u001b[1;32m 139\u001b[0m oauth_session\u001b[38;5;241m.\u001b[39mregister_compliance_hook(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124maccess_token_response\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compliance_hook)\n\u001b[0;32m--> 141\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m oauth_session\u001b[38;5;241m.\u001b[39mfetch_token(\n\u001b[1;32m 142\u001b[0m token_url\u001b[38;5;241m=\u001b[39mrequest\u001b[38;5;241m.\u001b[39murl,\n\u001b[1;32m 143\u001b[0m client_id\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39msh_client_id,\n\u001b[1;32m 144\u001b[0m client_secret\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39msh_client_secret,\n\u001b[1;32m 145\u001b[0m headers\u001b[38;5;241m=\u001b[39m{\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mDEFAULT_HEADERS, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mSHConstants\u001b[38;5;241m.\u001b[39mHEADERS},\n\u001b[1;32m 146\u001b[0m )\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/requests_oauthlib/oauth2_session.py:366\u001b[0m, in \u001b[0;36mOAuth2Session.fetch_token\u001b[0;34m(self, token_url, code, authorization_response, body, auth, username, password, method, force_querystring, timeout, headers, verify, proxies, include_client_id, client_secret, cert, **kwargs)\u001b[0m\n\u001b[1;32m 363\u001b[0m log\u001b[38;5;241m.\u001b[39mdebug(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvoking hook \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m, hook)\n\u001b[1;32m 364\u001b[0m r \u001b[38;5;241m=\u001b[39m hook(r)\n\u001b[0;32m--> 366\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_client\u001b[38;5;241m.\u001b[39mparse_request_body_response(r\u001b[38;5;241m.\u001b[39mtext, scope\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mscope)\n\u001b[1;32m 367\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtoken \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_client\u001b[38;5;241m.\u001b[39mtoken\n\u001b[1;32m 368\u001b[0m log\u001b[38;5;241m.\u001b[39mdebug(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mObtained token \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtoken)\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/oauthlib/oauth2/rfc6749/clients/base.py:427\u001b[0m, in \u001b[0;36mClient.parse_request_body_response\u001b[0;34m(self, body, scope, **kwargs)\u001b[0m\n\u001b[1;32m 379\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Parse the JSON response body.\u001b[39;00m\n\u001b[1;32m 380\u001b[0m \n\u001b[1;32m 381\u001b[0m \u001b[38;5;124;03mIf the access token request is valid and authorized, the\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 424\u001b[0m \u001b[38;5;124;03m.. _`Section 7.1`: https://tools.ietf.org/html/rfc6749#section-7.1\u001b[39;00m\n\u001b[1;32m 425\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 426\u001b[0m scope \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mscope \u001b[38;5;28;01mif\u001b[39;00m scope \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m scope\n\u001b[0;32m--> 427\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtoken \u001b[38;5;241m=\u001b[39m parse_token_response(body, scope\u001b[38;5;241m=\u001b[39mscope)\n\u001b[1;32m 428\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpopulate_token_attributes(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtoken)\n\u001b[1;32m 429\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtoken\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/oauthlib/oauth2/rfc6749/parameters.py:441\u001b[0m, in \u001b[0;36mparse_token_response\u001b[0;34m(body, scope)\u001b[0m\n\u001b[1;32m 438\u001b[0m params[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexpires_at\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime() \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mint\u001b[39m(params[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexpires_in\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[1;32m 440\u001b[0m params \u001b[38;5;241m=\u001b[39m OAuth2Token(params, old_scope\u001b[38;5;241m=\u001b[39mscope)\n\u001b[0;32m--> 441\u001b[0m validate_token_parameters(params)\n\u001b[1;32m 442\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m params\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/oauthlib/oauth2/rfc6749/parameters.py:448\u001b[0m, in \u001b[0;36mvalidate_token_parameters\u001b[0;34m(params)\u001b[0m\n\u001b[1;32m 446\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Ensures token presence, token type, expiration and scope in params.\"\"\"\u001b[39;00m\n\u001b[1;32m 447\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124merror\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m params:\n\u001b[0;32m--> 448\u001b[0m raise_from_error(params\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124merror\u001b[39m\u001b[38;5;124m'\u001b[39m), params)\n\u001b[1;32m 450\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124maccess_token\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m params:\n\u001b[1;32m 451\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m MissingTokenError(description\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMissing access token parameter.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
"File \u001b[0;32m/usr/local/anaconda3/lib/python3.11/site-packages/oauthlib/oauth2/rfc6749/errors.py:399\u001b[0m, in \u001b[0;36mraise_from_error\u001b[0;34m(error, params)\u001b[0m\n\u001b[1;32m 397\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m _, \u001b[38;5;28mcls\u001b[39m \u001b[38;5;129;01min\u001b[39;00m inspect\u001b[38;5;241m.\u001b[39mgetmembers(sys\u001b[38;5;241m.\u001b[39mmodules[\u001b[38;5;18m__name__\u001b[39m], inspect\u001b[38;5;241m.\u001b[39misclass):\n\u001b[1;32m 398\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mcls\u001b[39m\u001b[38;5;241m.\u001b[39merror \u001b[38;5;241m==\u001b[39m error:\n\u001b[0;32m--> 399\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mcls\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 400\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m CustomOAuth2Error(error\u001b[38;5;241m=\u001b[39merror, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
"\u001b[0;31mUnauthorizedClientError\u001b[0m: (unauthorized_client) Unexpected error when authenticating client"
]
}
],
"source": [
"for slot in slots:\n",
" download_function(slot)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68db3c15-6f94-432e-b315-c329e4251b21",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"for slot in slots:\n",
" merge_files(slot)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb3fa856-a550-4899-844a-e69209bba3ad",
"metadata": {},
"outputs": [],
"source": [
"\n",
"import shutil\n",
" \n",
"# List of folder names\n",
"\n",
"folders_to_empty = [BASE_PATH / 'merged_virtual', BASE_PATH_SINGLE_IMAGES]\n",
" \n",
"# Function to empty folders\n",
"\n",
"def empty_folders(folders):\n",
"\n",
" for folder in folders:\n",
"\n",
" try:\n",
"\n",
" for filename in os.listdir(folder):\n",
"\n",
" file_path = os.path.join(folder, filename)\n",
"\n",
" try:\n",
"\n",
" if os.path.isfile(file_path):\n",
"\n",
" os.unlink(file_path)\n",
"\n",
" elif os.path.isdir(file_path):\n",
"\n",
" shutil.rmtree(file_path)\n",
"\n",
" except Exception as e:\n",
"\n",
" print(f\"Error: {e}\")\n",
"\n",
" print(f\"Emptied folder: {folder}\")\n",
"\n",
" except OSError as e:\n",
"\n",
" print(f\"Error: {e}\")\n",
" \n",
"# Call the function to empty folders\n",
"\n",
"empty_folders(folders_to_empty)"
]
}
],
"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.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}