Skip to content

Commit

Permalink
move other asf functions from download to ASFClient, dont get CDS…
Browse files Browse the repository at this point in the history
…E from netrc if not necessary
  • Loading branch information
scottstanie committed Nov 6, 2023
1 parent a51d078 commit e14780b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 77 deletions.
23 changes: 21 additions & 2 deletions eof/dataspace_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from datetime import datetime, timedelta
from pathlib import Path
from typing import Optional

import requests

Expand Down Expand Up @@ -30,6 +31,19 @@ class DataspaceClient:
T1 = timedelta(seconds=60)

def __init__(self, username: str = "", password: str = ""):
if not (username and password):
logger.debug("Get credentials form netrc")
try:
username, password = get_netrc_credentials(DATASPACE_HOST)
except FileNotFoundError:
logger.warning("No netrc file found.")
except ValueError as e:
if DATASPACE_HOST not in e.args[0]:
raise e
logger.warning(
f"No CDSE credentials found in netrc file. Please create one using {SIGNUP_URL}"
)

self._username = username
self._password = password

Expand Down Expand Up @@ -255,14 +269,19 @@ def query_orbit_file_service(query: str) -> list[dict]:
return query_results


def get_access_token(username, password):
def get_access_token(username, password) -> Optional[str]:
"""Get an access token for the Copernicus Data Space Ecosystem (CDSE) API.
Code from https://documentation.dataspace.copernicus.eu/APIs/Token.html
"""
if not (username and password):
logger.debug("Get credentials form netrc")
username, password = get_netrc_credentials(DATASPACE_HOST)
try:
username, password = get_netrc_credentials(DATASPACE_HOST)
except FileNotFoundError:
logger.warning("No netrc file found.")
return None

data = {
"client_id": "cdse-public",
"username": username,
Expand Down
96 changes: 22 additions & 74 deletions eof/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
import itertools
import os
from multiprocessing.pool import ThreadPool
from zipfile import ZipFile

import requests
from dateutil.parser import parse

from .asf_client import ASFClient
Expand Down Expand Up @@ -89,35 +87,36 @@ def download_eofs(
# First, check that Scihub isn't having issues
if not force_asf:
client = DataspaceClient(username=cdse_user, password=cdse_password)
# try to search on scihub
if sentinel_file:
query = client.query_orbit_for_product(sentinel_file, orbit_type=orbit_type)
else:
query = client.query_orbit_by_dt(orbit_dts, missions, orbit_type=orbit_type)

if query:
logger.info("Attempting download from SciHub")
results = client.download_all(query, output_directory=save_dir)
filenames.extend(results)
dataspace_successful = True
if client._username and client._password:
# try to search on scihub
if sentinel_file:
query = client.query_orbit_for_product(
sentinel_file, orbit_type=orbit_type
)
else:
query = client.query_orbit_by_dt(
orbit_dts, missions, orbit_type=orbit_type
)

if query:
logger.info("Attempting download from SciHub")
results = client.download_all(query, output_directory=save_dir)
filenames.extend(results)
dataspace_successful = True

# For failures from scihub, try ASF
if not dataspace_successful:
from ._auth import NASA_HOST, get_netrc_credentials
if not force_asf:
logger.warning("Dataspace failed, trying ASF")

logger.warning("Dataspace failed, trying ASF")

if not (asf_user and asf_password):
logger.debug("Get credentials form netrc")
asf_user, asf_password = get_netrc_credentials(NASA_HOST)

asfclient = ASFClient()
urls = asfclient.get_download_urls(orbit_dts, missions, orbit_type=orbit_type)
asf_client = ASFClient(username=asf_user, password=asf_password)
urls = asf_client.get_download_urls(orbit_dts, missions, orbit_type=orbit_type)
# Download and save all links in parallel
pool = ThreadPool(processes=MAX_WORKERS)
result_url_dict = {
pool.apply_async(
_download_and_write, args=[url, save_dir, asf_user, asf_password]
asf_client._download_and_write,
args=[url, save_dir],
): url
for url in urls
}
Expand All @@ -133,57 +132,6 @@ def download_eofs(
return filenames


def _download_and_write(url, save_dir=".", asf_user="", asf_password=""):
"""Wrapper function to run the link downloading in parallel
Args:
url (str): url of orbit file to download
save_dir (str): directory to save the EOF files into
Returns:
list[str]: Filenames to which the orbit files have been saved
"""
fname = os.path.join(save_dir, url.split("/")[-1])
if os.path.isfile(fname):
logger.info("%s already exists, skipping download.", url)
return [fname]

logger.info("Downloading %s", url)
login_url = (
"https://urs.earthdata.nasa.gov/oauth/authorize?response_type=code"
f"&client_id=BO_n7nTIlMljdvU6kRRB3g&redirect_uri=https://auth.asf.alaska.edu/login&state={url}"
)
# Add credentials
response = requests.get(login_url, auth=(asf_user, asf_password))
response.raise_for_status()
logger.info("Saving to %s", fname)
with open(fname, "wb") as f:
f.write(response.content)
if fname.endswith(".zip"):
_extract_zip(fname, save_dir=save_dir)
# Pass the unzipped file ending in ".EOF", not the ".zip"
fname = fname.replace(".zip", "")
return fname


def _extract_zip(fname_zipped, save_dir=None, delete=True):
if save_dir is None:
save_dir = os.path.dirname(fname_zipped)
with ZipFile(fname_zipped, "r") as zip_ref:
# Extract the .EOF to the same direction as the .zip
zip_ref.extractall(path=save_dir)

# check that there's not a nested zip structure
zipped = zip_ref.namelist()[0]
zipped_dir = os.path.dirname(zipped)
if zipped_dir:
no_subdir = os.path.join(save_dir, os.path.split(zipped)[1])
os.rename(os.path.join(save_dir, zipped), no_subdir)
os.rmdir(os.path.join(save_dir, zipped_dir))
if delete:
os.remove(fname_zipped)


def find_current_eofs(cur_path):
"""Returns a list of SentinelOrbit objects located in `cur_path`"""
return sorted(
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="sentineleof",
version="0.9.1",
version="0.9.2",
author="Scott Staniewicz",
author_email="scott.stanie@gmail.com",
description="Download precise orbit files for Sentinel 1 products",
Expand Down

0 comments on commit e14780b

Please sign in to comment.