diff --git a/.github/workflows/build_docs.yaml b/.github/workflows/build_docs.yaml new file mode 100644 index 0000000..c950115 --- /dev/null +++ b/.github/workflows/build_docs.yaml @@ -0,0 +1,34 @@ +# Build the docs here, to show errors. +# The actual deployment of docs is configured in ReadTheDocs.org. + +name: Build and deploy docs + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + build_pywheels: + name: Build docs with Python ${{ matrix.python-version }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: ["3.10"] + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v1 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install and build docs + run: | + pip install pip -U && pip install wheel -U + pip install .[docs] + pip list + sphinx-build docs build/sphinx/html diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 0000000..60117de --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,17 @@ +{% extends "!layout.html" %} + {% block footer %} {{ super() }} + + +{% endblock %} diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..d4be669 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,9 @@ +API +=== + +The details of classes and methods + +.. automodule:: sumo.wrapper.sumo_client + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index ee64318..a60c67e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,23 +10,17 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # -# flake8: noqa -# pylint: skip-file import os import sys -from pathlib import Path -import sphinx -from datetime import date -sys.path.insert(0, os.path.abspath('../src/')) +sys.path.insert(0, os.path.abspath("../src/")) # -- Project information ----------------------------------------------------- -project = 'sumo-wrapper-python' -current_year = date.today().year -copyright = "Equinor " + str(current_year) -author = 'Sudo Team @ Equinor' +project = "sumo-wrapper-python" +copyright = "2024, Sudo Team @ Equinor" +author = "Sudo Team @ Equinor" # -- General configuration --------------------------------------------------- @@ -34,15 +28,18 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.napoleon', 'sphinx.ext.autodoc'] +extensions = [ + "sphinx.ext.napoleon", + "sphinx.ext.autodoc", +] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Options for HTML output ------------------------------------------------- @@ -50,14 +47,12 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" +html_logo = "_static/equinor-logo2.jpg" -html_theme_options = { - "style_nav_header_background": "#C0C0C0", -} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ['_static'] +html_static_path = ["_static"] diff --git a/docs/index.rst b/docs/index.rst index fff961a..72ba299 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,132 +3,13 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -#################################### -sumo-wrapper-python -#################################### - -A thin python wrapper class that can be used by Sumo client applications to -communicate with the Sumo core server. It has methods for GET, PUT, POST and DELETE, -and handles authentication and automatic network retries. - -A higher level alternative is available -here: `fmu-sumo `_ - -API is described at `https://main-sumo-prod.radix.equinor.com/swagger-ui/ `_ - -Access ------- - -For internal Equinor users: Apply for Equinor AccessIT, search for SUMO. - -Install -------- - -For internal Equinor users, this package is available through the Komodo -distribution. In other cases it can be pip installed: - -.. code-block:: - - pip install sumo-wrapper-python - - -SumoClient ----------- - -This class is for communicating with the Sumo core server using the Sumo API. - - -Initialization -^^^^^^^^^^^^^^ - -.. code-block:: python - - from sumo.wrapper import SumoClient - - Sumo = SumoClient() - - -`token` logic -^^^^^^^^^^^^^ - -No token provided: this will trigger -an authentication process and then handles token, token refresh and -re-authentication as automatic as possible. - -If an access token is provided in the `token` parameter, it will be used as long -as it's valid. An error will be raised when it expires. - -If we are unable to decode the provided `token` as a JWT, we treat it as a -refresh token and attempt to use it to retrieve an access token. - - -Methods -^^^^^^^ - -`SumoClient` has one method for each HTTP-method that is used in the Sumo -API: GET, PUT, POST and DELETE. -The Sumo API documentation is available from the Swagger button in -the Sumo frontend. - -Methods accepts a path argument. Path parameters can be interpolated into -the path string. - -Async methods -^^^^^^^^^^^^^ - -`SumoClient` also has *async* alternatives `get_async`, `post_async`, `put_async` and `delete_async`. -These accept the same parameters as their synchronous counterparts, but have to be *awaited*. - -Example -^^^^^^^^ - -.. code-block:: python - - from sumo.wrapper import SumoClient - sumo = SumoClient() - - # The line above will trigger the authentication process, and - # the behaviour depends on how long since your last login. - # It could re-use existing login or it could take you through - # a full Microsoft authentication process including - # username, password, two-factor. - - - # List your Sumo permissions: - print("My permissions:", sumo.get("/userpermissions").json()) - - # Get the first case from the list of cases you have access to: - case = sumo.get("/searchroot").json()["hits"]["hits"][0] - print("Case metadata:", case["_source"]) - case_uuid = case["_source"]["fmu"]["case"]["uuid"] - print("Case uuid: ", case_uuid) - - # Get the first child object: - child = sumo.get(f"/objects('{case_uuid}')/search").json()["hits"]["hits"][0] - print("Child metadata", child["_source"]) - child_uuid = child["_id"] - print("Child uuid: ", child_uuid) - - # Get the binary of the child - binary_object = sumo.get(f"/objects('{child_uuid}')/blob").content - print("Size of child binary object:", len(binary_object)) - +Welcome to sumo-wrapper-python's documentation! +=============================================== .. toctree:: :maxdepth: 2 :caption: Contents: -.. automodule:: sumo.wrapper.sumo_client - :members: - :undoc-members: - :show-inheritance: - -.. - Indices and tables - ================== - - * :ref:`genindex` - * :ref:`modindex` - * :ref:`search` - - \ No newline at end of file + self + sumo-wrapper-python + api diff --git a/docs/sumo-wrapper-python.rst b/docs/sumo-wrapper-python.rst new file mode 100644 index 0000000..ea3c6f6 --- /dev/null +++ b/docs/sumo-wrapper-python.rst @@ -0,0 +1,129 @@ +sumo-wrapper-python +################### + +Short introduction +******************* + +A thin python wrapper class that can be used by Sumo client applications to +communicate with the Sumo core server. It has methods for GET, PUT, POST and DELETE, +and handles authentication and automatic network retries. + +This is low-level and close to the Sumo API and primarily intended for developers. +For usage in the FMU context, the higher-level alternative +`fmu-sumo `_ is recommended. + +The Sumo API is described at +`https://main-sumo-prod.radix.equinor.com/swagger-ui/ `_ + +The data model and schema is described at +`https://fmu-dataio.readthedocs.io/en/latest/datamodel.html `_ + +Information on Sumo can be found `here `_ + +Preconditions +************* + +Access +------ + +For internal Equinor users: Apply for access to Sumo in Equinor AccessIT, search for Sumo. + +Install +******* + +For internal Equinor users, this package is included in the Komodo distribution. +For other use cases it can be pip installed directly from PyPI: + +.. code-block:: + + pip install sumo-wrapper-python + +Initialization +************** + +.. code-block:: python + + from sumo.wrapper import SumoClient + + Sumo = SumoClient() + +`token` logic +************* + +No token provided: this will trigger +an authentication process and then handles token, token refresh and +re-authentication as automatic as possible. This would be the most common +usecase. + +If an access token is provided in the `token` parameter, it will be used as long +as it's valid. An error will be raised when it expires. + +If we are unable to decode the provided `token` as a JWT, we treat it as a +refresh token and attempt to use it to retrieve an access token. + + +Methods +******* + +`SumoClient` has one method for each HTTP-method that is used in the Sumo +API: GET, PUT, POST and DELETE. In addition a method to get a blob client +which handles blob contents. + +The methods accepts a path argument. A path is the path to a +Sumo `API `_ method, for +example "/search" or "/smda/countries". Path parameters can be added into +the path string, for example + +.. code-block:: python + +f"/objects('{case_uuid}')/search" + +The Sumo API documentation is available from the Swagger button in +the Sumo frontend, or you can use this link: +`https://main-sumo-prod.radix.equinor.com/swagger-ui/ `_. + +Async methods +************* + +`SumoClient` also has *async* alternatives `get_async`, `post_async`, `put_async` and `delete_async`. +These accept the same parameters as their synchronous counterparts, but have to be *awaited*. + +Usage and examples +****************** + +.. code-block:: python + + from sumo.wrapper import SumoClient + sumo = SumoClient() + + # The line above will trigger the authentication process, and + # the behaviour depends on how long since your last login. + # It could re-use existing login or it could take you through + # a full Microsoft authentication process including + # username, password, two-factor. + + + # List your Sumo permissions: + print("My permissions:", sumo.get("/userpermissions").json()) + + # Get the first case from the list of cases you have access to: + case = sumo.get("/searchroot").json()["hits"]["hits"][0] + print("Case metadata:", case["_source"]) + case_uuid = case["_source"]["fmu"]["case"]["uuid"] + print("Case uuid: ", case_uuid) + + # Get the first child object: + child = sumo.get(f"/objects('{case_uuid}')/search").json()["hits"]["hits"][0] + print("Child metadata", child["_source"]) + child_uuid = child["_id"] + print("Child uuid: ", child_uuid) + + # Get the binary of the child + binary_object = sumo.get(f"/objects('{child_uuid}')/blob").content + print("Size of child binary object:", len(binary_object)) + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: +