A request can wait to be served for longer than the access token it was sent with lives, and comes back refused for a token that was valid when it left. Uploads that take minutes make that wait ordinary. - tell an expired token apart from any other refusal by the code the API returns, and retry only that one, once - prefer a token another process left behind over minting a second: it saves a round trip, and a rotating provider would retire one that is still in use. Assign it rather than read it, since the setter is what rewrites the session header the retry will carry - settle the token before the request so the one compared afterwards is the one that was actually sent - report an overloaded server when the second attempt is refused too, and let API errors out of the upload path with their own type
35 lines
989 B
Python
35 lines
989 B
Python
from typing import Final
|
|
|
|
from pydantic import TypeAdapter
|
|
from pydantic.dataclasses import dataclass
|
|
|
|
from mdrsclient.api.base import BaseApi
|
|
from mdrsclient.api.utils import retry_on_expired_token, token_check
|
|
from mdrsclient.models.doi import Doi
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class DoiRetrieveFolderRef:
|
|
id: str
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class DoiRetrieveResponse:
|
|
id: str
|
|
doi: str
|
|
folder: DoiRetrieveFolderRef
|
|
|
|
|
|
class DoiApi(BaseApi):
|
|
ENTRYPOINT: Final[str] = "v3/doi/"
|
|
|
|
@retry_on_expired_token
|
|
def retrieve(self, doi_id: str) -> Doi:
|
|
"""Retrieve the folder associated with a DOI suffix ID (GET v3/doi/{id}/)."""
|
|
url = self.ENTRYPOINT + doi_id + "/"
|
|
token_check(self.connection)
|
|
response = self.connection.get(url)
|
|
self._raise_response_error(response)
|
|
api_resp = TypeAdapter(DoiRetrieveResponse).validate_python(response.json())
|
|
return Doi(id=api_resp.id, doi=api_resp.doi, folder_id=api_resp.folder.id)
|