Metadata-Version: 2.4
Name: omnia_timeseries
Version: 1.4.4.3
Summary: Official Python SDK for the Omnia Timeseries API
License: MIT
License-File: LICENSE
Keywords: omnia,timeseries,azure,sdk,industrial-iot
Author: Equinor Omnia Industrial IoT Team
Author-email: omniaindiot@equinor.com
Requires-Python: >=3.8, !=2.7.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: azure-core (>=1.30.0,<2.0.0)
Requires-Dist: azure-identity (>=1.19.0,<2.0.0)
Requires-Dist: cryptography (>=46.0.5,<47.0.0)
Requires-Dist: opentelemetry-api (>=1.27.0,<2.0.0)
Requires-Dist: opentelemetry-instrumentation-requests (>=0.54b1,<1.0.0)
Requires-Dist: pyjwt (>=2.9.0,<3.0.0)
Requires-Dist: requests (>=2.28.0,<3.0.0)
Project-URL: Documentation, https://github.com/equinor/omnia-timeseries-python/blob/main/README.md
Project-URL: Homepage, https://github.com/equinor/omnia-timeseries-python
Project-URL: Repository, https://github.com/equinor/omnia-timeseries-python
Project-URL: changelog, https://github.com/equinor/omnia-timeseries-python/blob/main/CHANGELOG.md
Project-URL: issues, https://github.com/equinor/omnia-timeseries-python/issues
Project-URL: repository, https://github.com/equinor/omnia-timeseries-python
Description-Content-Type: text/markdown

# Omnia Timeseries Python API

Python package for interacting with the [Omnia Industrial IoT Timeseries API](https://github.com/equinor/OmniaPlant/wiki).

## Installation

Install from PyPI:

```
pip install omnia-timeseries
```

Install from GitHub (latest unreleased changes):

```
pip install git+https://github.com/equinor/omnia-timeseries-python.git@main
```

Supported Python versions: 3.8+ (excluding 3.9.0 and 3.9.1)

For support, create an issue on GitHub.

## Example usage

For fundamental questions please refer to the MSAL documentation which has [code examples for multiple programming languages and scenarios](https://learn.microsoft.com/en-us/entra/identity-platform/sample-v2-code?tabs=apptype).

You should also familiarize yourself with the [azure.identity](https://learn.microsoft.com/en-us/python/api/overview/azure/identity-readme?view=azure-python) package, which we will use below.

Follow [usage examples](https://github.com/equinor/omnia-timeseries-python/blob/main/examples/usage_examples.ipynb) to learn how to retrieve data in `Json` format.  
Follow [get data as protobuf example](https://github.com/equinor/omnia-timeseries-python/blob/main/examples/get_data_protobuf.ipynb) to learn how to retrieve data in `Protobuf` format.

### Preparing Azure authentication

Read https://github.com/equinor/OmniaPlant/wiki/Authentication-&-Authorization to familiarize yourself with how Timeseries API handles authentication and authorization.

The `TimeseriesAPI` client accepts any `azure.identity` credential that inherits from `MsalCredential`, so you can pick the flow that suits your environment. The options we currently cover are:

- **Service principal with client secret** (`ClientSecretCredential`) for headless service-to-service scenarios.
- **Service principal with certificate** (`ClientCertificateCredential`) when you prefer cert-based authentication instead of a secret.
- **Managed identities / default credential chain** (`ManagedIdentityCredential` or `DefaultAzureCredential`) when running inside Azure.
- **Interactive browser login** (`InteractiveBrowserCredential`) for local development where you can complete the sign-in with a browser.
- **User impersonation** (`DeviceCodeCredential` or other interactive flows that acquire a user token) when you need to act on behalf of a signed-in user; this requires the Timeseries API app to consent to the `user_impersonation` scope.
- **On-behalf-of flow** (`OnBehalfOfCredential`) when a middle-tier service needs to exchange a signed-in user's token for a Timeseries API token and act with delegated permissions.

The supported credential setups are shown below.

#### With service principal credentials (client secret)

Read [Service-to-service using a shared secret](https://github.com/equinor/OmniaPlant/wiki/Authentication-&-Authorization#service-to-service-using-a-shared-secret) and ensure prerequisite steps have been done.

```python
from azure.identity import ClientSecretCredential
import os
credentials = ClientSecretCredential(
    tenant_id=os.environ['AZURE_TENANT_ID'],
    client_id=os.environ['AZURE_CLIENT_ID'],
    client_secret=os.environ['AZURE_CLIENT_SECRET']
)
```

#### With service principal credentials (client certificate)

Use a certificate instead of a shared secret when you want a stronger identity proof and avoid storing plain secrets.

```python
from azure.identity import ClientCertificateCredential
import os
credentials = ClientCertificateCredential(
    tenant_id=os.environ['AZURE_TENANT_ID'],
    client_id=os.environ['AZURE_CLIENT_ID'],
    certificate_path=os.environ['AZURE_CLIENT_CERT_PATH']
)
```

#### With interactive browser login

When developing locally, you can open a browser window and sign in manually.

```python
from azure.identity import InteractiveBrowserCredential
import os
credentials = InteractiveBrowserCredential(
    tenant_id=os.environ['AZURE_TENANT_ID'],
    client_id=os.environ['AZURE_CLIENT_ID']
)
```

#### With user impersonation (device code)

Use a device code or other interactive credential that requests the `user_impersonation` scope so the signed-in user is impersonated by the Timeseries API.

```python
from azure.identity import DeviceCodeCredential
import os
credentials = DeviceCodeCredential(
    tenant_id=os.environ['AZURE_TENANT_ID'],
    client_id=os.environ['AZURE_CLIENT_ID']
)
```

#### With managed / default credentials

Read [Managed Service Identity (For Equinor applications in Azure)](https://github.com/equinor/OmniaPlant/wiki/Authentication-&-Authorization#managed-service-identity-for-equinor-applications-in-azure) and ensure prerequisite steps have been done.

```python
from azure.identity import DefaultAzureCredential
credentials = DefaultAzureCredential()
```

#### With on-behalf-of flow

Use `OnBehalfOfCredential` when a backend service receives a user token (the user assertion) and needs to call the Timeseries API on that user's behalf.

```python
from azure.identity import OnBehalfOfCredential
import os
credentials = OnBehalfOfCredential(
    tenant_id=os.environ['AZURE_TENANT_ID'],
    client_id=os.environ['AZURE_CLIENT_ID'],
    client_secret=os.environ['AZURE_CLIENT_SECRET'],
    user_assertion=os.environ['USER_ASSERTION']
)
```

### Output

The `Json` response from Timeseries API looks like this:
```
>> {'items': [{'id': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'datapoints': [{'time': '2021-02-01T09:54:05.4200000Z', 'value': -0.000286102294921875, 'status': 192}]}]}
```

The `Protobuf` response from Timeseries API looks like this:
```
{ "data": [ { "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "totalCount": "1", "fields": [ "time", "value", "status" ], "values": [ { "int64": "1727263834898000000" }, { "double": 246.56092834472656 }, { "uint32": 192 } ] } ] }
```

### Other use cases

Please consult the [API Reference](https://api.equinor.com/api-details#api=Timeseries-api-v1-7) for a full overview of the API endpoints.

