Metadata-Version: 2.4
Name: cs-service_api
Version: 20260914
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>=20260912
Requires-Dist: cs.fstags>=20260912
Requires-Dist: cs.logutils>=20260912
Requires-Dist: cs.obj>=20260912
Requires-Dist: cs.pfx>=20260912
Requires-Dist: cs.resources>=20250915
Requires-Dist: cs.sqltags>=20260914
Requires-Dist: cs.upd>=20260912
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.

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.


* `LoginPasswordCredentials`: A credentials class for login/password authentication.


* `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.


* `UsesCredentials`: A mixin for accessing credentials.

# Classes

## 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 0x1097f7ec0>, 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.

## class LoginPasswordCredentials(LoginPasswordCredentials)

A credentials class for login/password authentication.

Its default `from_str(credname)` factory accesses the netrc(5) file.

### `LoginPasswordCredentials.from_netrc(host, netrc_path=None)`

Create an instance from a netrc(5) `host`.
Raise `KeyError` if `host` is unknown.

## class LoginState(cs.obj.Refreshable)



## 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.

## class ServiceAPI(cs.resources.MultiOpenMixin, UsesCredentials, cs.sqltags.UsesSQLTags)

`SewrviceAPI` base class for other APIs talking to services.

### `ServiceAPI.__init__(*a, fstags: Optional[cs.fstags.FSTags] = <function uses_fstags.<locals>.<lambda> at 0x1097f71a0>, **kw)`

Initialise a `ServiceAPI` instance.

The `concurrency` parameter may take the following values:
* `None`: API calls are serialised, setting `.concurrency_sem=None`
  and `.pmap=partial(pmap,concurrent=1)`
* an `int`: API calls are constrained by `.concurrency_sem`,
  set to a `Semaphore` with this initial value, and `.pmap=pmap`
* a `Semaphore`: API calls are constrained by `.concurrency_sem`,
  set to this `Semaphore`, and `.pmap=pmap`

### `ServiceAPI.API_AUTH_GRACETIME`

    None

### `ServiceAPI.API_CONCURRENCY_LIMIT`

    None

### `ServiceAPI.API_RETRY_COUNT`

    3

### `ServiceAPI.API_RETRY_DELAY`

    5

### `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.tagged.Entity`

The login state, a `Entity`, 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`

    <property object at 0x109802430>

### `ServiceAPI.login_state`

    <functools.cached_property object at 0x108c8b070>

### `ServiceAPI.startup_shutdown(self)`

Open/close the `FSTags` and `Entities`.

## class UsesCredentials

A mixin for accessing credentials.

### `UsesCredentials.credentials(self, credname)`

Return the credentials for `credname`.

### `UsesCredentials.default_credentials()`

Return the default credentials for `cls.API_HOSTNAME`.
