Metadata-Version: 2.4
Name: cs-service_api
Version: 20260531
Summary: ServiceAPI, a base class for APIs which talk to a service, typically a web service via HTTP.
Keywords: python3
Author-email: Cameron Simpson <cs@cskk.id.au>
Description-Content-Type: text/markdown
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Requires-Dist: cs.deco>=20260525
Requires-Dist: cs.fstags>=20260531
Requires-Dist: cs.logutils>=20250323
Requires-Dist: cs.pfx>=20250914
Requires-Dist: cs.resources>=20250915
Requires-Dist: cs.sqltags>=20260531
Requires-Dist: cs.tagset>=20260531
Requires-Dist: cs.upd>=20260526
Requires-Dist: icontract
Requires-Dist: requests
Project-URL: MonoRepo Commits, https://bitbucket.org/cameron_simpson/css/commits/branch/main
Project-URL: Monorepo Git Mirror, https://github.com/cameron-simpson/css
Project-URL: Monorepo Hg/Mercurial Mirror, https://hg.sr.ht/~cameron-simpson/css
Project-URL: Source, https://github.com/cameron-simpson/css/blob/main/lib/python/cs/service_api.py

ServiceAPI, a base class for APIs which talk to a service,
typically a web service via HTTP.

*Latest release 20260531*:
* HTTPServiceAPI: add __truediv__(suburl) which does a GET.
* HTTPServiceAPI: default .API_HOSTNAME comes from the subclass.
* HTTPServiceAPI.json: catch requests.exceptions.JSONDecodeError also.
* HTTPServiceAPI: new mode ("response", "json", "data", callable) parameter.
* HTTPServiceAPI: new check_json optional dict of expected fields and values in JSON responses.

An instance of a `ServiceAPI` embodies some basic features
that feel common to web based services:
- a notion of a login
- local state, an `SQLTags` for data about entities of the service
- downloads, if that is a thing, with `FSTags` for file annotations

Short summary:
* `HTTPServiceAPI`: `HTTPServiceAPI` base class for other APIs talking to HTTP services.
* `RequestsNoAuth`: This is a special purpose subclass of `requests.auth.AuthBase` to apply no authorisation at all. This is for services with their own special purpose authorisation and avoids things like automatic netrc based auth.
* `ServiceAPI`: `SewrviceAPI` base class for other APIs talking to services.

Module contents:
- <a name="HTTPServiceAPI"></a>`class HTTPServiceAPI(ServiceAPI)`: `HTTPServiceAPI` base class for other APIs talking to HTTP services.

  Subclasses must define:
  * `API_BASE`: the base URL of API calls.
    For example, the `PlayOnAPI` defines this as `f'https://{API_HOSTNAME}/v3/'`.

*`HTTPServiceAPI.get(self, suburl, **kw) -> requests.models.Response`*:
Call `slef.suburl` with `method="GET"`.

*`HTTPServiceAPI.post(self, suburl, **kw) -> requests.models.Response`*:
Call `slef.suburl` with `method="POST"`.

*`HTTPServiceAPI.response_as_json(self, rsp: requests.models.Response) -> dict`*:
Return `rsp.json()`.

*`HTTPServiceAPI.response_as_json_data(self, rsp: requests.models.Response) -> dict`*:
Return the `"data"` element from a JSON response.

*`HTTPServiceAPI.suburl(self, suburl, *, base_url=None, method='GET', mode=None, check=True, cookies=None, headers=None, runstate: Optional[cs.resources.RunState] = <function uses_runstate.<locals>.<lambda> at 0x111844fe0>, verbose: bool, **rqkw) -> Union[requests.models.Response, dict]`*:
Request `suburl` from the service, by default using a `GET`.
The `suburl` must be a URL subpath not commencing with `'/'`.

Return:
- `mode(Response)` if `mode` is callable
- the `Response` if `mode=="response"`
- the `Response.json()` if `mode=="json"`
- the `Response.json()["data"]` if `mode=="data"`

Keyword parameters:
* `base_url`: the base request domain, default from `self.API_BASE`
* `method`: optional request method, default `'GET'`
* `check`: if true, raise an HTTP error if the response
  status is not 200; default `True`
* `cookies`: optional cookie jar, default from `self.cookies`
* `mode`: optional result mode, default from `self.mode`
Other keyword parameters are passed to the requests method.
- <a name="RequestsNoAuth"></a>`class RequestsNoAuth(requests.auth.AuthBase)`: This is a special purpose subclass of `requests.auth.AuthBase`
  to apply no authorisation at all.
  This is for services with their own special purpose authorisation
  and avoids things like automatic netrc based auth.
- <a name="ServiceAPI"></a>`class ServiceAPI(cs.resources.MultiOpenMixin, cs.sqltags.UsesSQLTags)`: `SewrviceAPI` base class for other APIs talking to services.

*`ServiceAPI.available(self) -> Set[cs.sqltags.SQLTagSet]`*:
Return a set of the `SQLTagSet` instances representing available
items at the service, for example purchased books
available to your login.

*`ServiceAPI.get_login_state(self, do_refresh=False) -> cs.tagset.HasTags`*:
The login state, a `HasTags`, stored as `login.state.`*login_userid*.
This performs a login if necessary or if `do_refresh` is true
(default `False`).

*`ServiceAPI.login(self) -> Mapping`*:
Do a login: authenticate to the service, return a mapping of related information.

Not all services require this and we expect such subclasses
to avoid use of login-based methods.

*`ServiceAPI.login_expiry`*:
Expiry UNIX time for the login state.
This implementation returns `None`.

*`ServiceAPI.startup_shutdown(self)`*:
Open/close the `FSTags` and `UsesTagSets`.

# Release Log



*Release 20260531*:
* HTTPServiceAPI: add __truediv__(suburl) which does a GET.
* HTTPServiceAPI: default .API_HOSTNAME comes from the subclass.
* HTTPServiceAPI.json: catch requests.exceptions.JSONDecodeError also.
* HTTPServiceAPI: new mode ("response", "json", "data", callable) parameter.
* HTTPServiceAPI: new check_json optional dict of expected fields and values in JSON responses.

*Release 20241007*:
HTTPServiceAPI.suburl: support interruption by RunState.cancel.

*Release 20240723*:
ServiceAPI: acquire the fstags automatically at init.

*Release 20230703*:
Retry logic for requests.

*Release 20230217*:
Initial release.
