Metadata-Version: 2.5
Name: evo-objects
Version: 0.6.4
Summary: Python SDK for using the Seequent Evo Geoscience Object API
Project-URL: Source, https://github.com/SeequentEvo/evo-python-sdk
Project-URL: Tracker, https://github.com/SeequentEvo/evo-python-sdk/issues
Project-URL: Homepage, https://www.seequent.com/
Project-URL: Documentation, https://developer.seequent.com/
Author-email: Seequent <support@seequent.com>
License-File: LICENSE.md
Requires-Python: >=3.10
Requires-Dist: evo-sdk-common[jmespath]>=0.5.26
Requires-Dist: pydantic<3,>=2
Provides-Extra: aiohttp
Requires-Dist: evo-sdk-common[aiohttp]; extra == 'aiohttp'
Provides-Extra: blockmodels
Requires-Dist: evo-blockmodels[utils]>=0.2.0; extra == 'blockmodels'
Provides-Extra: notebooks
Requires-Dist: evo-sdk-common[notebooks]; extra == 'notebooks'
Provides-Extra: utils
Requires-Dist: numpy; extra == 'utils'
Requires-Dist: pandas; extra == 'utils'
Requires-Dist: pyarrow; extra == 'utils'
Requires-Dist: pyarrow-stubs; extra == 'utils'
Description-Content-Type: text/markdown

<p align="center"><a href="https://seequent.com" target="_blank"><picture><source media="(prefers-color-scheme: dark)" srcset="https://developer.seequent.com/img/seequent-logo-dark.svg" alt="Seequent logo" width="400" /><img src="https://developer.seequent.com/img/seequent-logo.svg" alt="Seequent logo" width="400" /></picture></a></p>
<p align="center">
    <a href="https://pypi.org/project/evo-objects/"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/evo-objects" /></a>
    <a href="https://github.com/SeequentEvo/evo-python-sdk/actions/workflows/run-all-tests.yaml"><img src="https://github.com/SeequentEvo/evo-python-sdk/actions/workflows/run-all-tests.yaml/badge.svg" alt="" /></a>
</p>
<p align="center">
    <a href="https://developer.seequent.com/" target="_blank">Seequent Developer Portal</a>
    &bull; <a href="https://community.seequent.com/group/19-evo" target="_blank">Seequent Community</a>
    &bull; <a href="https://seequent.com" target="_blank">Seequent website</a>
</p>

# Evo Object API Client

The Geoscience Object API is Seequent's next-generation cloud offering for geoscience
data, empowering our users to build responsive modern workflows. 

## Pre-requisites

* Python ^3.10
* An [application registered in Bentley](https://developer.bentley.com/register/?product=seequent-evo)

## Installation

```shell
pip install evo-objects
```

## Usage

See [the evo-sdk-common documentation](https://github.com/SeequentEvo/evo-python-sdk/blob/main/packages/evo-sdk-common/README.md)
for information on how to authenticate, then select the organisation, hub and workspace that you would like to use.

### Interacting with the Geoscience Object API

To get up and running quickly with the Evo Objects SDK, start by configuring your
[environment and API connector](https://github.com/SeequentEvo/evo-python-sdk/blob/main/packages/evo-sdk-common/docs/quickstart.md).

```python
from evo.objects import ObjectAPIClient

service_client = ObjectAPIClient(environment, connector)
service_health = await service_client.get_service_health()
service_health.raise_for_status()

# The data client is an optional utility that provides helpers for uploading and downloading
# parquet data via pyarrow.Table objects.
data_client = service_client.get_data_client(manager.cache)
...
```

Listing objects is simple, just call the `ObjectAPIClient.list_objects()` method.

```python
offset = 0
while True:
    page = await service_client.list_objects(offset=offset, limit=10)
    if offset == 0:
        print(f"Found {page.total} object{'' if page.total == 1 else 's'}")
    for object in page:
        print(f"{object.path}: <{object.schema_id}> ({object.id})")

    if page.is_last:
        break
    else:
        offset = page.next_offset
```

You can also get a list of all objects. Internally, this recursively calls the `list_objects()` method until all objects are fetched.

Check out the other methods on the `ObjectAPIClient` for more details on how to upload and download objects, or get object versions.

### Typed downhole collections

`DownholeCollection` provides a DataFrame-based API for creating and reading downhole objects. A collection can contain
distance tables, interval tables, or both. `hole_index` is an integer key in the object's `hole_id` lookup table, not a
row position or a pandas categorical code. The creation helper uses dense zero-based keys in sorted hole-ID order unless
an explicit `hole_indices` mapping is supplied. Persisted objects may use arbitrary integer keys. Collection holes may
contain a subset or repeated chunks.

```python
import pandas as pd

from evo.objects.typed import DownholeCollection, DownholeCollectionData
from evo.objects.typed.downhole_collection import IntervalCollection
from evo.objects.utils.downhole import hole_chunks_from_ids

intervals = pd.DataFrame({"from": [0.0], "to": [1.5], "lithology": ["sandstone"]})
collections = [
    IntervalCollection(
        name="geology",
        holes=hole_chunks_from_ids(pd.Series(["DH-01"])),
        table=intervals,
        unit="m",  # Collection coordinate units are set explicitly here.
    )
]

# Build DownholeCollectionData with matching path, location-hole chunks, and collar properties,
# then create it with: await DownholeCollection.create(context, data)
```

Use `await dhc.location.to_dataframe()` and `await dhc.location.path_to_dataframe()` to read collars and paths.
Distance and interval tables provide `to_dataframe()` and `to_dataframe_by_hole()`. Before reading a large object, call
`await dhc.prefetch_collections("geology")` to warm only the requested collection data (and location data by default).
Attribute descriptions for ordinary attributes round-trip through `DataFrame.attrs["attribute_descriptions"]`.
Collection coordinate units come only from `DistanceCollection.unit` or `IntervalCollection.unit`; unit metadata on the
distance or `from` column is ignored.

## Contributing

For instructions on contributing to the development of this library, please refer to the [evo-python-sdk documentation](https://github.com/seequentevo/evo-python-sdk).

## License

The Python SDK for Evo is open source and licensed under the [Apache 2.0 license.](https://github.com/SeequentEvo/evo-python-sdk/tree/main/packages/evo-objects/./LICENSE.md).

Copyright © 2025 Bentley Systems, Incorporated.

Licensed under the Apache License, Version 2.0 (the "License").
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
