Metadata-Version: 2.1
Name: h2o-authn
Version: 1.0.0
Summary: H2O Python Clients Authentication Helpers
Home-page: https://github.com/h2oai/authn-py
License: Apache-2.0
Author: H2O.ai
Author-email: support@h2o.ai
Requires-Python: >=3.7,<4.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Internet
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Security
Classifier: Topic :: Utilities
Requires-Dist: httpx (>=0.16)
Project-URL: Repository, https://github.com/h2oai/authn-py
Description-Content-Type: text/markdown

# `h2o-authn`

[![licence](https://img.shields.io/github/license/h2oai/authn-py?style=flat-square)](https://github.com/h2oai/authn-py/main/LICENSE)
[![pypi](https://img.shields.io/pypi/v/h2o-authn?style=flat-square)](https://pypi.org/project/h2o-authn/)

H2O Python Clients Authentication Helpers.

## Installation

```sh
pip install h2o-authn
```

## Usage

Package provides two top level classes `h2o_authn.TokenProvider` and `h2o_authn.AsyncTokenProvider` with identical constructors accepting following arguments:

- `refresh_token`: Refresh token which will used for the access token exchange.
- `client_id`: OAuth 2.0 client id that will be used or the access token
    exchange.
- `issuer_url` or `token_endpoint_url` **needs to be provided**
  - `issuer_url`: Base URL of the issuer. This URL will be used for the discovery
        to obtain token endpoint. Mutually exclusive with the
        token_endpoint_url argument.
  - `token_endpoint_url`: URL of the token endpoint that should be used for the
        access token exchange. Mutually exclusive with the issuer_url argument.
- `client_secret`: Optional OAuth 2.0 client secret for the confidential
    clients. Used only when provided.
- `scope`: Optionally sets the the scope for which the access token should be
    requested.
- `expiry_threshold`: How long before token expiration should token be
    refreshed when needed. This does not mean that the token will be
    refreshed before it expires, only indicates the earliest moment before
    the expiration when refresh would occur. (default: 5s)
- `expires_in_fallback`: Fallback value for the expires_in value. Will be used
    when token response does not contains expires_in field.
- `minimal_refresh_period`: Optionally minimal period between the earliest token
    refresh exchanges.

Both classes has identical interface in sync or async variant.

```python
provider = h2o_authn.TokenProvider(...)
aprovider = h2o_authn.AsyncTokenProvider(...)


# Calling the providers directly makes sure that fresh access token is available
# and returns it.
access_token = provider()
access_token = await aprovider()


# Calling the token() returns h2o_authn.token.Token instance.
token = provider.token()
token = await aprovider.token()

# It can used as str.
assert token == access_token

# And contains additional attributes when available.
token.exp  # Is expiration of the token as datetime.datetime
token.scope  # Is scope of the token if server provided it.


# Sync/Async variants can be converted from one to another.
provider = aprovider.as_sync()
aprovider = provider.as_async()


# When access token with different scope is needed new instance can cloned from
# the current with different scope.
provider = provider.with_scope("new scopes")
aprovider = aprovider.with_scope("new scopes")
```

### Examples

#### Example: Use with H2O.ai MLOps Python CLient

```python
import h2o_authn
import h2o_mlops_client as mlops

provider = h2o_authn.TokenProvider(...)
mlops_client = mlops.Client(
    gateway_url="https://mlops-api.cloud.h2o.ai",
    token_provider=provider,
)
...
```

#### Example: Use with H2O.ai Drive Python Client within the Wave App

```python
import h2o_authn
import h2o_drive
from h2o_wave import Q, app, ui
from h2o_wave import main

@app("/")
async def serve(q: Q):
    provider = h2o_authn.AsyncTokenProvider(
        refresh_token=q.auth.refresh_token,
        issuer_url=os.getenv("H2O_WAVE_OIDC_PROVIDER_URL"),
        client_id=os.getenv("H2O_WAVE_OIDC_CLIENT_ID"),
        client_secret=os.getenv("H2O_WAVE_OIDC_CLIENT_SECRET"),
    )
    my_home = await h2o_drive.MyHome(token=provider)

    ...
```

#### Example: Use with H2O.ai Enterprise Steam Python Client

```python
import h2o_authn
import h2osteam
import h2osteam.clients

provider = h2o_authn.TokenProvider(...)

h2osteam.login(
    url="https://steam.cloud-dev.h2o.ai", access_token=provider()
)
client = h2osteam.clients.DriverlessClient()

...
```

