From cad99a6b7778f9776cb255c17cc83868945fe972 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 19 Sep 2022 06:28:43 -0500 Subject: [PATCH 1/3] Added retry, backoff to planetary_computer.sign Retries on failed HTTP requests to the SAS API. Parameter names are taken from `azure.core`: https://learn.microsoft.com/en-us/azure/developer/python/sdk/azure-sdk-library-usage-patterns?tabs=pip#arguments-for-libraries-based-on-azurecore --- CHANGELOG.md | 6 ++++++ planetary_computer/sas.py | 34 ++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73d202a..a097a46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.4.8 + +## New Features + +* `sign` now automatically retries failed HTTP requests. + # 0.4.7 ## New Features diff --git a/planetary_computer/sas.py b/planetary_computer/sas.py index fe382d1..afd7701 100644 --- a/planetary_computer/sas.py +++ b/planetary_computer/sas.py @@ -8,11 +8,13 @@ from functools import singledispatch from urllib.parse import urlparse, parse_qs import requests +import requests.adapters from pydantic import BaseModel, Field from pystac import Asset, Item, ItemCollection, STACObjectType, Collection from pystac.utils import datetime_to_str from pystac.serialization.identify import identify_stac_object_type from pystac_client import ItemSearch +import urllib3.util.retry from planetary_computer.settings import Settings from planetary_computer.utils import ( @@ -397,7 +399,12 @@ def sign_mapping(mapping: Mapping, copy: bool = True) -> Mapping: sign_reference_file = sign_mapping -def get_token(account_name: str, container_name: str) -> SASToken: +def get_token( + account_name: str, + container_name: str, + retry_total: int = 10, + retry_backoff_factor=0.08, +) -> SASToken: """ Get a token for a container in a storage account. @@ -407,6 +414,10 @@ def get_token(account_name: str, container_name: str) -> SASToken: Args: account_name (str): The storage account name. container_name (str): The storage container name. + retry_total (int): The number of allowable retry attempts for REST API calls. + Use retry_total=0 to disable retries. A backoff factor to apply between + attempts. + retry_backoff_factor (float): Returns: SASToken: the generated token """ @@ -417,13 +428,24 @@ def get_token(account_name: str, container_name: str) -> SASToken: # Refresh the token if there's less than a minute remaining, # in order to give a small amount of buffer if not token or token.ttl() < 60: - headers = ( - {"Ocp-Apim-Subscription-Key": settings.subscription_key} - if settings.subscription_key - else None + session = requests.Session() + retry = urllib3.util.retry.Retry( + total=retry_total, + backoff_factor=retry_backoff_factor, + ) + adapter = requests.adapters.HTTPAdapter(max_retries=retry) + session.mount("http://", adapter) + session.mount("https://", adapter) + response = session.get( + token_request_url, + headers=( + {"Ocp-Apim-Subscription-Key": settings.subscription_key} + if settings.subscription_key + else None + ), ) - response = requests.get(token_request_url, headers=headers) response.raise_for_status() + token = SASToken(**response.json()) if not token: raise ValueError(f"No token found in response: {response.json()}") From bdb84b73e222907366b0dd2628099bdba58888fa Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Mon, 19 Sep 2022 06:36:54 -0500 Subject: [PATCH 2/3] mypy --- planetary_computer/sas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planetary_computer/sas.py b/planetary_computer/sas.py index afd7701..1213db0 100644 --- a/planetary_computer/sas.py +++ b/planetary_computer/sas.py @@ -403,7 +403,7 @@ def get_token( account_name: str, container_name: str, retry_total: int = 10, - retry_backoff_factor=0.08, + retry_backoff_factor: float = 0.08, ) -> SASToken: """ Get a token for a container in a storage account. From b33bb16a08806852974460b0ba55e0290176eb15 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Wed, 21 Sep 2022 08:57:03 -0500 Subject: [PATCH 3/3] fixed docstring --- planetary_computer/sas.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/planetary_computer/sas.py b/planetary_computer/sas.py index 1213db0..42775aa 100644 --- a/planetary_computer/sas.py +++ b/planetary_computer/sas.py @@ -403,7 +403,7 @@ def get_token( account_name: str, container_name: str, retry_total: int = 10, - retry_backoff_factor: float = 0.08, + retry_backoff_factor: float = 0.8, ) -> SASToken: """ Get a token for a container in a storage account. @@ -417,7 +417,14 @@ def get_token( retry_total (int): The number of allowable retry attempts for REST API calls. Use retry_total=0 to disable retries. A backoff factor to apply between attempts. - retry_backoff_factor (float): + retry_backoff_factor (float): A backoff factor to apply between attempts + after the second try (most errors are resolved immediately by a second + try without a delay). Retry policy will sleep for: + + ``{backoff factor} * (2 ** ({number of total retries} - 1))`` seconds. + If the backoff_factor is 0.1, then the retry will sleep for + [0.0s, 0.2s, 0.4s, ...] between retries. The default value is 0.8. + Returns: SASToken: the generated token """