stac-utils / pystac-client

Python client for searching STAC APIs
https://pystac-client.readthedocs.io
Other
156 stars 48 forks source link

Retrieve formatted search url #299

Closed scottyhq closed 2 years ago

scottyhq commented 2 years ago

Maybe I've overlooked something, but scanning through examples, code and docs, I don't see an easy way to print an encoded search url from Python:

from pystac_client import Client

client = Client.open(
    'https://planetarycomputer.microsoft.com/api/stac/v1',
    ignore_conformance=True,
)

search = client.search(
    collections=['cop-dem-glo-30'],
    bbox=[88.214, 27.927, 88.302,  28.034],
)

# How to get easily get this?:
# https://planetarycomputer.microsoft.com/api/stac/v1/search?collections=cop-dem-glo-30&bbox=88.214,27.927,88.302,28.034

Something like this doesn't quite work b/c of lists and parentheses

from urllib.parse import urlencode
f'{search.url}?{urlencode(search.get_parameters())}'
# 'https://planetarycomputer.microsoft.com/api/stac/v1/search?limit=100&bbox=%2888.214%2C+27.927%2C+88.302%2C+28.034%29&collections=%28%27cop-dem-glo-30%27%2C%29'

I was trying to do this to work with GDAL's STAC reader without saving to a local JSON...

gadomski commented 2 years ago

We use requests under the hood, so something like this should get you what you want w/o too much effort:

import requests

params = {
    "collections": ["cop-dem-glo-30"],
    "bbox": [88.214, 27.927, 88.302,  28.034],
}
response = requests.get("https://planetarycomputer.microsoft.com/api/stac/v1", params=params)
print(response.url)
# https://planetarycomputer.microsoft.com/api/stac/v1?collections=cop-dem-glo-30&bbox=88.214&bbox=27.927&bbox=88.302&bbox=28.034
scottyhq commented 2 years ago

Thanks @gadomski ! That certainly works with a small modification (bbox=','.join([str(x) for x in bbox])

Maybe I'm the only one, but I think it would be nice to access the formatted URL directly from the search object using search.get_parameters() behind the scenes. It's useful to share with others and potentially see other defaults that are being submitted (like 'limit': 100). Since search.url is already spoken for, maybe search.request?

gadomski commented 2 years ago

Shouldn't be a hard add -- I've converted this issue into a feature request.

One thing to note is that not all API requests are sent via GET -- e.g. when I updated your example to actually retrieve items, it used POST. Whatever method name we use for this feature, it should document the fact that the returned URL may not be exactly what is actually sent to the server by the ItemSearch.