Skip to content

bookops_worldcat.authorize

This module provides means to authenticate and obtain a WorldCat access token.

WorldcatAccessToken

WorldcatAccessToken(
    key: str,
    secret: str,
    scopes: Union[str, List[str]],
    principal_id: str,
    principal_idns: str,
    agent: Optional[str] = None,
    timeout: Optional[
        Union[
            int, float, Tuple[int, int], Tuple[float, float]
        ]
    ] = None,
)

Requests Worldcat access token. Authenticates and authorizes using Client Credentials Grant. Does not support Explicit Authorization Code and Refresh Token flows. Token with correctly bonded scopes can then be passed into a session of particular web service to authorize requests for resources. More on OCLC's web services authorization: https://www.oclc.org/developer/develop/authentication/oauth/client-credentials-grant.en.html

Parameters:

Name Type Description Default
key str

your WSKey public client_id

required
secret str

your WSKey secret

required
scopes Union[str, List[str]]

request scopes for the access token

required
principal_id str

principalID (required for read/write endpoints)

required
principal_idns str

principalIDNS (required for read/write endpoints)

required
agent Optional[str]

"User-agent" parameter to be passed in the request header; usage strongly encouraged

None
timeout Optional[Union[int, float, Tuple[int, int], Tuple[float, float]]]

how long to wait for server to send data before giving up; default value is 3 seconds

None

Examples:

>>> from bookops_worldcat import WorldcatAccessToken
>>> token = WorldcatAccessToken(
        key="my_WSKey_client_id",
        secret="my_WSKey_secret",
        scope="WorldCatMetadataAPI",
        principal_id="your principalID here",
        principal_idns="your principalIDNS here",
        agent="my_app/1.0.0")
>>> token.token_str
"tk_Yebz4BpEp9dAsghA7KpWx6dYD1OZKWBlHjqW"
>>> token.is_expired()
False
>>> token.server_response.json()
{"token_token": "tk_Yebz4BpEp9dAsghA7KpWx6dYD1OZKWBlHjqW",
 "token_type": "bearer",
 "expires_in": "1199",
 "principalID": "",
 "principalIDNS": "",
 "scopes": "WorldCatMetadataAPI",
 "contextInstitutionId": "00001",
 "expires_at": "2020-08-23 18:45:29Z"}
>>> token.server_response.request.headers
{"User-Agent": "my_app/1.0.0",
 "Accept-Encoding": "gzip, deflate",
 "Accept": "application/json",
 "Connection": "keep-alive",
 "Content-Length": "67",
 "Content-Type": "application/x-www-form-urlencoded",
 "Authorization": "Basic encoded_authorization_here="}
Source code in bookops_worldcat\authorize.py
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def __init__(
    self,
    key: str,
    secret: str,
    scopes: Union[str, List[str]],
    principal_id: str,
    principal_idns: str,
    agent: Optional[str] = None,
    timeout: Optional[
        Union[int, float, Tuple[int, int], Tuple[float, float]]
    ] = None,
) -> None:
    """Constructor"""

    self.agent = agent
    self.grant_type = "client_credentials"
    self.key = key
    self.oauth_server = "https://oauth.oclc.org"
    self.principal_id = principal_id
    self.principal_idns = principal_idns
    self.scopes = scopes
    self.secret = secret
    self.server_response = None
    self.timeout = timeout
    self.token_expires_at = None
    self.token_str = None
    self.token_type = None

    # default bookops-worldcat request header
    if self.agent is None:
        self.agent = f"{__title__}/{__version__}"
    else:
        if type(self.agent) is not str:
            raise WorldcatAuthorizationError("Argument 'agent' must be a string.")

    # asure passed arguments are valid
    if not self.key:
        raise WorldcatAuthorizationError("Argument 'key' is required.")
    else:
        if type(self.key) is not str:
            raise WorldcatAuthorizationError("Argument 'key' must be a string.")

    if not self.secret:
        raise WorldcatAuthorizationError("Argument 'secret' is required.")
    else:
        if type(self.secret) is not str:
            raise WorldcatAuthorizationError("Argument 'secret' must be a string.")

    if not self.principal_id:
        raise WorldcatAuthorizationError(
            "Argument 'principal_id' is required for read/write endpoint of Metadata API."
        )
    if not self.principal_idns:
        raise WorldcatAuthorizationError(
            "Argument 'principal_idns' is required for read/write endpoint of Metadata API."
        )

    # validate passed scopes
    if type(self.scopes) is list:
        self.scopes = " ".join(self.scopes)
    elif type(self.scopes) is not str:
        raise WorldcatAuthorizationError(
            "Argument 'scopes' must a string or a list."
        )
    self.scopes = self.scopes.strip()  # type: ignore
    if self.scopes == "":
        raise WorldcatAuthorizationError("Argument 'scope' is missing.")

    # assign default value for timout
    if not self.timeout:
        self.timeout = (3, 3)

    # initiate request
    self._request_token()

is_expired

is_expired() -> bool

Checks if the access token is expired.

Returns:

Type Description
bool

bool

Example:

token.is_expired() False

Source code in bookops_worldcat\authorize.py
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
def is_expired(self) -> bool:
    """
    Checks if the access token is expired.

    Returns:
        bool

    Example:
    >>> token.is_expired()
    False
    """
    try:
        if (
            datetime.datetime.strptime(self.token_expires_at, "%Y-%m-%d %H:%M:%SZ")  # type: ignore
            < datetime.datetime.utcnow()
        ):
            return True
        else:
            return False
    except TypeError:
        raise
    except ValueError:
        raise