Sentinel-1 SAR Images - Python Requests

I have python experience but totally new to APIs via Python and Sentinel-1 API.

I am doing research on the Antarctic using Sentinel-1 SAR images from different dates. But getting an error UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x124112b10>.

I have followed the beginner’s guide and have the current code, with the first Sentinel-1 example copied. The code is simply designed to have my code working, so then I can use it for Antarctic regions by changing my bbox coordinates:

from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
from PIL import Image
import io
import numpy as np
import matplotlib.pyplot as plt

CLIENT_ID = "**************"
CLIENT_SECRET = "***************"

# set up credentials
client = BackendApplicationClient(client_id=CLIENT_ID)
oauth = OAuth2Session(client=client)

# get an authentication token
token = oauth.fetch_token(token_url='https://services.sentinel-hub.com/auth/realms/main/protocol/openid-connect/token',
                          client_secret=CLIENT_SECRET, include_client_id=True)

bbox = [
  -60.54347,
  -78.699106,
  -27.896624,
  -72.127936
]
start_date = "2020-06-01"
end_date = "2020-08-31"
collection_id = "sentinel-1-grd"

evalscript: """
//VERSION=3
function setup() {
    return {
        input: ["VV"],
        output: { id:"default", 
                bands: 1}  
    };
}

function evaluatePixel(samples) {
    return [2 * samples.VV]}":
"""
# evalscript

evalscript = """
//VERSION=3

function setup() {
  return {
    input: ["B02", "B03", "B04"],
    output: { id: 'default',
              bands: 3 }
  };
}

function evaluatePixel(sample) {
  return [2.5 * sample.B04, 2.5 * sample.B03, 2.5 * sample.B02];
}
"""

# request body/payload
json_request = {
  "input": {
    "bounds": {
      "bbox": [
        1360000,
        5121900,
        1370000,
        5131900
      ],
      "properties": {
        "crs": "http://www.opengis.net/def/crs/EPSG/0/3857"
      }
    },
    "data": [
      {
        "dataFilter": {
          "timeRange": {
            "from": "2019-02-02T00:00:00Z",
            "to": "2019-04-02T23:59:59Z"
          }
        },
        "processing": {
          "orthorectify": "true"
        },
        "type": "sentinel-1-grd"
      }
    ]
  },
  "output": {
    "width": 512,
    "height": 511.727,
    "responses": [
      {
        "identifier": "default",
        "format": {
          "type": "image/png"
        }
      }
    ]
  },
    'evalscript': evalscript
}

# Set the request url and headers
url_request = 'https://services.sentinel-hub.com/api/v1/process'
headers_request = {
    "Authorization" : "Bearer %s" %token['access_token']
}

#Send the request
response = oauth.request(
    "POST", url_request, headers=headers_request, json = json_request
)
# read the image as numpy array
image_arr = np.array(Image.open(io.BytesIO(response.content)))

# plot the image for visualization
plt.figure(figsize=(16,16))
plt.axis('off')
plt.tight_layout()
plt.imshow(image_arr)
---------------------------------------------------------------------------
UnidentifiedImageError                    Traceback (most recent call last)
Cell In[26], line 2
      1 # read the image as numpy array
----> 2 image_arr = np.array(Image.open(io.BytesIO(response.content)))
      4 # plot the image for visualization
      5 plt.figure(figsize=(16,16))

File ~/anaconda3/envs/SentinelHub_VM/lib/python3.11/site-packages/PIL/Image.py:3339, in open(fp, mode, formats)
   3337     warnings.warn(message)
   3338 msg = "cannot identify image file %r" % (filename if filename else fp)
-> 3339 raise UnidentifiedImageError(msg)

UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x124112b10>

If anyone is able to help make my code run well or already has Sentinel-1 SAR code (doesn’t matter on the bands etc) that would be willing to provide, it would be much appreciated.

Hi Samuel,

As you are a beginner I would recommend running through the examples in the Sentinel Hub Python package documentation to get you started.

You will then find plenty of examples for Sentinel-1 GRD data here and here.

If you are still having issues then do let us know :slight_smile:

Hi, unfortunately your response does not answer my question - why I am getting an error in the first place.

However, I have followed the the first example on Sentinel Hub Process API ReadTheDocs page, but getting an error saying my client ID and secret have not been set (I have put spaces in links to get around the max 2 links per user):

from sentinelhub import SHConfig

config = SHConfig()

config

SHConfig(
instance_id=‘’,
sh_client_id=‘‘,
sh_client_secret=’
******’,
sh_base_url=‘https: //services.sentinel-hub. com’,
sh_auth_base_url=‘https: //services.sentinel-hub. com’,
)
/Users/samuel/anaconda3/lib/python3.11/site-packages/sentinelhub/config.py:54: SHDeprecationWarning: The parameter sh_auth_base_url of SHConfig has been replaced with sh_token_url. Please update your configuration, for now the parameters were automatically adjusted to sh_token_url = sh_auth_base_url + '/oauth/token'.
warnings.warn(
SHConfig(
instance_id=‘’,
sh_client_id=‘********************************d674’,
sh_client_secret=‘****************************Gyyr’,
sh_base_url=‘https: //services.sentinel-hub. com’,
sh_auth_base_url=‘https: //services.sentinel-hub. com’,
sh_token_url=‘https: //services. sentinel- hub. com /oauth/ token’,
geopedia_wms_url=‘https: //service. geopedia. world’,
geopedia_rest_url=‘https: //www. geopedia. world/r est’,
aws_access_key_id=‘’,
aws_secret_access_key=‘’,
aws_session_token=‘’,
aws_metadata_url=‘https: //roda.sentinel-hub. com’,
aws_s3_l1c_bucket=‘sentinel-s2-l1c’,
aws_s3_l2a_bucket=‘sentinel-s2-l2a’,
opensearch_url=‘http: //opensearch. sentinel-hub. com/resto/api/collections/ Sentinel2’,
max_wfs_records_per_query=100,
max_opensearch_records_per_query=500,
max_download_attempts=4,
download_sleep_time=5.0,
download_timeout_seconds=120.0,
number_of_download_processes=1,
max_retries=None,
)
%reload_ext autoreload
%autoreload 2
%matplotlib inline
import datetime
import os

import matplotlib.pyplot as plt
import numpy as np

from sentinelhub import (
CRS,
BBox,
DataCollection,
DownloadRequest,
MimeType,
MosaickingOrder,
SentinelHubDownloadClient,
SentinelHubRequest,
bbox_to_dimensions,
)
betsiboka_coords_wgs84 = (46.16, -16.15, 46.51, -15.58)
resolution = 60
betsiboka_bbox = BBox(bbox=betsiboka_coords_wgs84, crs=CRS.WGS84)
betsiboka_size = bbox_to_dimensions(betsiboka_bbox, resolution=resolution)

print(f"Image shape at {resolution} m resolution: {betsiboka_size} pixels")
Image shape at 60 m resolution: (631, 1047) pixels
evalscript_true_color = “”"
//VERSION=3

function setup() {
    return {
        input: [{
            bands: ["B02", "B03", "B04"]
        }],
        output: {
            bands: 3
        }
    };
}

function evaluatePixel(sample) {
    return [sample.B04, sample.B03, sample.B02];
}

“”"

request_true_color = SentinelHubRequest(
evalscript=evalscript_true_color,
input_data=[
SentinelHubRequest.input_data(
data_collection=DataCollection.SENTINEL2_L1C,
time_interval=(“2020-06-12”, “2020-06-13”),
)
],
responses=[SentinelHubRequest.output_response(“default”, MimeType.PNG)],
bbox=betsiboka_bbox,
size=betsiboka_size,
config=config,
)
true_color_imgs = request_true_color.get_data()

ValueError: Configuration parameters ‘sh_client_id’ and ‘sh_client_secret’ have to be set in order to authenticate with Sentinel Hub service. Check https ://sentinelhub-py.readthedocs.io/en/latest/configure. html for more info.

Please tell me how I can the error in either my original post or this new code.

This is an error with the credentials you are setting. Please read through this page carefully and make sure to create your credentials in your Sentinel Hub Dashboard.

Although aimed at Copernicus Data Space Ecosystem users, you can also follow this tutorial which will show you step by step how to create the credentials and enter them into your code.