Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fall back to STAC_URL environment variable when opening a Client #48

Merged
merged 4 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- `Client.open` falls back to the `STAC_URL` environment variable if no url is provided as an argument [#48](https://github.com/stac-utils/pystac-client/pull/48)

## [v0.1.1] - 2021-04-16

### Added
Expand Down
20 changes: 15 additions & 5 deletions pystac_client/client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from copy import deepcopy
import os
from typing import Callable, Optional
from urllib.request import Request

Expand Down Expand Up @@ -75,28 +76,37 @@ def __repr__(self):
return '<Catalog id={}>'.format(self.id)

@classmethod
def open(cls, url, headers=None):
def open(cls, url=None, headers=None):
"""Alias for PySTAC's STAC Object `from_file` method

Parameters
----------
url : str
The URL of a STAC Catalog
url : str, optional
The URL of a STAC Catalog. If not specified, this will use the `STAC_URL` environment variable.

Returns
-------
catalog : Client
"""
import pystac_client.stac_io

if url is None:
url = os.environ.get("STAC_URL")

if url is None:
raise TypeError(
"'url' must be specified or the 'STAC_URL' environment variable must be set.")

def read_text_method(url):
request = Request(url, headers=headers or {})
return pystac_client.stac_io.read_text_method(request)

old_read_text_method = STAC_IO.read_text_method
STAC_IO.read_text_method = read_text_method
catalog = cls.from_file(url)
STAC_IO.read_text_method = old_read_text_method
try:
catalog = cls.from_file(url)
finally:
STAC_IO.read_text_method = old_read_text_method
catalog.headers = headers
return catalog

Expand Down
95 changes: 95 additions & 0 deletions tests/cassettes/test_client/TestAPI.test_environment_variable.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
interactions:
- request:
body: null
headers:
Connection:
- close
Host:
- eod-catalog-svc-prod.astraea.earth
User-Agent:
- Python-urllib/3.9
method: GET
uri: https://eod-catalog-svc-prod.astraea.earth
response:
body:
string: '{"conformsTo":["http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core","http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30","http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson","http://www.opengis.net/spec/ogcapi_common-2/1.0/req/collections","http://stacspec.org/spec/api/1.0.0-beta.1/core","http://stacspec.org/spec/api/1.0.0-beta.1/req/stac-search","http://stacspec.org/spec/api/1.0.0-beta.1/req/stac-response","http://stacspec.org/spec/api/1.0.0-beta.1/req/fields","http://stacspec.org/spec/api/1.0.0-beta.1/req/context","http://stacspec.org/spec/api/1.0.0-beta.1/req/sort"],"description":"Astraea
Earth OnDemand geospatial imagery query and analysis tool","id":"astraea","links":[{"href":"https://eod-catalog-svc-prod.astraea.earth","rel":"self","title":"Self","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth","rel":"root","title":"Root","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/api","rel":"service-desc","title":"OpenAPI
specification","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/api.html","rel":"service-doc","title":"API
documentation","type":"text/html"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections","rel":"data","title":"Collections","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections","rel":"collections","title":"Collections","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/landsat8_l1tp","rel":"child","title":"Landsat
8 C1 T1","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/mcd43a4","rel":"child","title":"MCD43A4
NBAR","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/mod11a1","rel":"child","title":"MOD11A1
LST","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/myd11a1","rel":"child","title":"MYD11A1
LST","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/mod13a1","rel":"child","title":"MOD13A1
VI","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/myd13a1","rel":"child","title":"MYD13A1
VI","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/sentinel1_l1c_grd","rel":"child","title":"Sentinel-1
L1C GRD","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/sentinel2_l2a","rel":"child","title":"Sentinel-2
L2A","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/sentinel2_l1c","rel":"child","title":"Sentinel-2
L1C","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/naip","rel":"child","title":"NAIP","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/maxar_open_data","rel":"child","title":"Maxar
Open Data","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/collections/spacenet7","rel":"child","title":"SpaceNet
7","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/aggregate","rel":"aggregation","title":"Aggregation","type":"application/json"},{"capabilities":{"parameters":[{"name":"composite","values":[{"description":"Default
View.","name":"default","title":"Default View"},{"description":"True Color
Composite.","name":"true_color","title":"True Color Composite"},{"description":"Normalized
Difference Vegetation Index.","name":"ndvi","title":"NDVI"},{"description":"Normalized
Difference Water Index using Green and NIR per McFeeters(1997).","name":"ndwi","title":"NDWI
(Green & NIR)"},{"description":"Normalized Difference Water Index using NIR
and SWIR per Gao(1997).","name":"ndwi2","title":"NDWI (NIR & SWIR)"},{"description":"Color
Infrared (Vegetation) consisting of Near-infrared, Red, and Green bands.","name":"color_infrared_veg1","title":"Color
Infrared Vegetation (NRG)"},{"description":"Color Infrared (Vegetation) consisting
of Near-infrared, Green, and Blue bands.","name":"color_infrared_veg2","title":"Color
Infrared Vegetation 2 (NGB)"},{"description":"False Color Infrared (Urban).","name":"false_color_urban","title":"False
Color (Urban)"},{"description":"Agriculture.","name":"agriculture","title":"Agriculture"},{"description":"Moisture
Index.","name":"moisture_index","title":"Moisture Index"},{"description":"Geology.","name":"geology","title":"Geology"},{"description":"Bathymetric.","name":"bathymetric","title":"Bathymetric"},{"description":"Atmospheric
Penetration.","name":"atmospheric_penetration","title":"Atmospheric Penetration"},{"description":"SWIR
1.","name":"swir1","title":"SWIR 1"},{"description":"SWIR 2.","name":"swir2","title":"SWIR
2"},{"description":"SAR VV Polarization.","name":"sar_vv","title":"SAR VV
Polarization"},{"description":"SAR VH Polarization.","name":"sar_vh","title":"SAR
VH Polarization"},{"description":"SAR HH Polarization.","name":"sar_hh","title":"SAR
HH Polarization"},{"description":"SAR HV Polarization.","name":"sar_hv","title":"SAR
HV Polarization"},{"description":"SAR False Color (Urban).","name":"sar_false_color_urban","title":"SAR
False Color (Urban)"}]}]},"href":"https://eod-catalog-svc-prod.astraea.earth/aggregate","rel":"aggregate","title":"Aggregate","type":"application/json"},{"capabilities":{"parameters":[{"name":"composite","values":[{"description":"Default
View.","name":"default","title":"Default View"},{"description":"True Color
Composite.","name":"true_color","title":"True Color Composite"},{"description":"Normalized
Difference Vegetation Index.","name":"ndvi","title":"NDVI"},{"description":"Normalized
Difference Water Index using Green and NIR per McFeeters(1997).","name":"ndwi","title":"NDWI
(Green & NIR)"},{"description":"Normalized Difference Water Index using NIR
and SWIR per Gao(1997).","name":"ndwi2","title":"NDWI (NIR & SWIR)"},{"description":"Color
Infrared (Vegetation) consisting of Near-infrared, Red, and Green bands.","name":"color_infrared_veg1","title":"Color
Infrared Vegetation (NRG)"},{"description":"Color Infrared (Vegetation) consisting
of Near-infrared, Green, and Blue bands.","name":"color_infrared_veg2","title":"Color
Infrared Vegetation 2 (NGB)"},{"description":"False Color Infrared (Urban).","name":"false_color_urban","title":"False
Color (Urban)"},{"description":"Agriculture.","name":"agriculture","title":"Agriculture"},{"description":"Moisture
Index.","name":"moisture_index","title":"Moisture Index"},{"description":"Geology.","name":"geology","title":"Geology"},{"description":"Bathymetric.","name":"bathymetric","title":"Bathymetric"},{"description":"Atmospheric
Penetration.","name":"atmospheric_penetration","title":"Atmospheric Penetration"},{"description":"SWIR
1.","name":"swir1","title":"SWIR 1"},{"description":"SWIR 2.","name":"swir2","title":"SWIR
2"},{"description":"SAR VV Polarization.","name":"sar_vv","title":"SAR VV
Polarization"},{"description":"SAR VH Polarization.","name":"sar_vh","title":"SAR
VH Polarization"},{"description":"SAR HH Polarization.","name":"sar_hh","title":"SAR
HH Polarization"},{"description":"SAR HV Polarization.","name":"sar_hv","title":"SAR
HV Polarization"},{"description":"SAR False Color (Urban).","name":"sar_false_color_urban","title":"SAR
False Color (Urban)"}]}]},"href":"https://eod-catalog-svc-prod.astraea.earth/search","rel":"search","title":"Search","type":"application/json"},{"href":"https://eod-catalog-svc-prod.astraea.earth/grid_id_definitions?20200218","rel":"grid_id_definitions","title":"Grid
ID Definitions","type":"application/json"}],"stac_extensions":["eo","proj","context"],"stac_version":"1.0.0-beta.2","title":"Astraea
Earth OnDemand"}'
headers:
Access-Control-Allow-Credentials:
- 'true'
Access-Control-Allow-Headers:
- X-Astraea-Catalog-Client
- Authorization, Content-Type, X-Requested-With
Access-Control-Allow-Origin:
- '*'
Cache-Control:
- no-cache, no-store, must-revalidate
Connection:
- close
Content-Length:
- '7768'
Content-Type:
- application/json
Date:
- Mon, 03 May 2021 15:27:20 GMT
Server:
- akka-http/10.2.3
status:
code: 200
message: OK
version: 1
25 changes: 25 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import datetime
import os

from dateutil.tz import tzutc
import pystac
Expand Down Expand Up @@ -96,6 +97,30 @@ def test_from_file(self):

assert api.title == 'Astraea Earth OnDemand'

@pytest.mark.vcr
def test_environment_variable(self):
old_stac_url = os.environ.get("STAC_URL")
os.environ["STAC_URL"] = ASTRAEA_URL
try:
client = Client.open()
assert client.title == "Astraea Earth OnDemand"
finally:
if old_stac_url:
os.environ["STAC_URL"] = old_stac_url
else:
del os.environ["STAC_URL"]

def test_no_url(self):
old_stac_url = os.environ.get("STAC_URL")
if old_stac_url:
del os.environ["STAC_URL"]
try:
with pytest.raises(TypeError):
Client.open()
finally:
if old_stac_url:
os.environ["STAC_URL"] = old_stac_url


class TestAPISearch:
@pytest.fixture(scope='function')
Expand Down