diff --git a/README.md b/README.md index ad35073a..d0e658eb 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,11 @@ -[![Documentation Status](https://readthedocs.org/projects/fmu-sumo/badge/?version=latest)](https://fmu-sumo.readthedocs.io/en/latest/?badge=latest) - - # fmu-sumo -`fmu.sumo` is a Python package intended for interaction with FMU results stored in Sumo.
-`fmu.sumo.explorer` is a Python API for consuming FMU results from Sumo. - -_Note! Access to Sumo is required. For Equinor users, apply through `AccessIT``._ -## Installation -``` -$ pip install fmu-sumo -``` -... or for the latest development version: -``` -$ git clone git@github.com:equinor/fmu-sumo.git -$ cd fmu-sumo -$ pip install . -``` -:warning: OpenVDS does not publish builds for MacOS. You can still use the Explorer without OpenVDS, but some Cube methods will not work. - -#### For development - -``` -$ git clone -$ cd fmu-sumo -$ pip install .[dev] -``` +[![Documentation Status](https://readthedocs.org/projects/fmu-sumo/badge/?version=latest)](https://fmu-sumo.readthedocs.io/en/latest/?badge=latest) -#### Run tests -``` -$ pytest tests/ -``` ## Documentation and guidelines :link: [fmu-sumo documentation](https://fmu-sumo.readthedocs.io/en/latest/) -## Example usage -```python -from fmu.sumo.explorer import Explorer - -# Connect -sumo = Explorer() - -# Apply filters -cases = cases.filter(status=["keep", "offical"], user="peesv", field="DROGON") - -for case in cases: - print(f"{case.name} ({case.uuid})") - -# Select case -case = cases[0] - -# Alternatively, get specific case via case.uuid -case = sumo.get_case_by_uuid() -``` ## Contribute [Contribution guidelines](./CONTRIBUTING.md) - -## License -Apache 2.0 \ No newline at end of file diff --git a/docs/explorer.rst b/docs/explorer.rst index 301a5005..c35102d7 100644 --- a/docs/explorer.rst +++ b/docs/explorer.rst @@ -3,6 +3,30 @@ Sumo Explorer The ``fmu.sumo.explorer`` is a python package for reading data from Sumo in the FMU context. +Note! Access to Sumo is required. For Equinor users, apply through ``AccessIT``. + +Installation +------------- + +.. code-block:: console + + pip install fmu-sumo + +or for the latest development version: + +.. code-block:: console + + git clone git@github.com:equinor/fmu-sumo.git + cd fmu-sumo + pip install .[dev] + +Run tests +--------- + +.. code-block:: console + + pytest tests/ + Api Reference ------------- @@ -319,6 +343,56 @@ If we know the `uuid` of the surface we want to work with we can get it directly print(surface.name) +Pagination: Iterating over large resultsets +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you want to iterate/paginate over large number of results you _must_ use the +`keep_alive` parameter to avoid errors and get an exact and complete list of +objects. The `keep_alive` parameter creates a 'snapshot' in the backend, +which ensures consistent results for you, but at the same time using some +resources on the server-side. To avoid server-side problems, the `keep_alive` +parameter should be as short as possible, but still large enough for you +(or your users) to iterate over the data-set. If you are not sure what to +use, start with 15m, i.e. 15 minutes. This means that you expect that there +will be a maximum of 15 minutes between each time fmu-sumo calls the back-end, +so not the complete time period of a user session. + +The 'snapshot' will of course not reflect any updates to data performed +simultaneously by you or anyone else. + +For how large result-sets should you use the `keep_alive` parameter? As of +early 2024, the `Explorer` uses 500 objects pagination, so you should use +the `keep_alive` parameter for all result-sets larger than 500 objects. + +The 'snapshot' works in exactly the same way for async and sync methods. + +Here is example code iterating over a large result-set using the `keep_alive` +parameter: + +.. code-block:: python + + import asyncio + + from fmu.sumo.explorer import Explorer + from fmu.sumo.explorer.objects import SurfaceCollection + + explorer = Explorer(env="prod", keep_alive="15m") + case = explorer.get_case_by_uuid("dec73fae-bb11-41f2-be37-73ba005c4967") + + surface_collection: SurfaceCollection = case.surfaces.filter( + iteration="iter-1", + ) + + + async def main(): + count = await surface_collection.length_async() + for i in range(count): + print(f"Working on {i} of {count-1}") + surf = await surface_collection.getitem_async(i) + # Do something with surf + + asyncio.run(main()) + Time filtering ^^^^^^^^^^^^^^ The `TimeFilter` class lets us construct time filters to be used in the `SurfaceCollection.filter` method: