Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/python_scripts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Test Python scripts

# NOTE: Added "push" here such that PR authors can test the actions in their forked repository
# before submitting a PR.
# NOTE: It is not possible to avoid the duplication of the paths in the "push" and
# "pull_request" sections. This is a known limitation of the GitHub Actions syntax.
on:
push:
paths:
- 'python/sphinx_docs/**'
- '.github/workflows/python_scripts.yml'
pull_request:
paths:
- 'python/sphinx_docs/**'
- '.github/workflows/python_scripts.yml'

permissions:
contents: read

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.11", "3.12"]
steps:
- name: checkout source code
uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install poetry
uses: abatilo/actions-poetry@v2
- name: Install dependencies
run: |
cd python/sphinx_docs
poetry install
- name: Run tests
run: |
cd python/sphinx_docs
poetry run pytest tests
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Files necessary to build the documentation locally, but these are tracked by other github repositories
dune.module
/dune.module
python/docstrings_common.json
python/docstrings_simulators.json

Expand All @@ -12,3 +12,6 @@ python/sphinx_docs/docs/_build*
# Editor autosave files
*~
*.swp

# Python coverage files
python/sphinx_docs/.coverage
7 changes: 7 additions & 0 deletions python/sphinx_docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,10 @@ docs:

view-docs:
@xdg-open "file://$(GIT_ROOT)/python/sphinx_docs/docs/_build/$(CURRENT_BRANCH)/index.html"

test:
pytest tests/

coverage:
coverage run -m pytest tests
coverage report -m
207 changes: 201 additions & 6 deletions python/sphinx_docs/poetry.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions python/sphinx_docs/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ sphinx-versioned-docs = "^1.3.1"
opmdoc-download-files = "opm_python_docs.download_files:main"
opmdoc-view-doc = "opm_python_docs.view_docs:main"

[tool.poetry.group.dev.dependencies]
pytest = "^8.3.4"
pytest-mock = "^3.14.0"
gitpython = "^3.1.44"
coverage = "^7.6.10"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
1 change: 1 addition & 0 deletions python/sphinx_docs/src/opm_python_docs/view_docs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#! /usr/bin/env python3

import logging
import os

import click

Expand Down
Empty file.
7 changes: 7 additions & 0 deletions python/sphinx_docs/tests/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from typing import Protocol
from pathlib import Path

class CreateGitDirFunc(Protocol): # pragma: no cover
def __call__(self, add_config_ini: bool) -> Path:
pass

45 changes: 45 additions & 0 deletions python/sphinx_docs/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import shutil
from pathlib import Path

import git
import pytest
from pytest_mock.plugin import MockerFixture
from .common import CreateGitDirFunc

@pytest.fixture(scope="session")
def test_file_path() -> Path:
return Path(__file__).parent / "files"

@pytest.fixture()
def create_git_repo(
tmp_path: Path,
test_file_path: Path,
mocker: MockerFixture,
) -> CreateGitDirFunc:
def _create_git_repo() -> Path:
# Create a temporary directory
git_root = tmp_path / "opm-python-documentation"
git_root.mkdir()
repo = git.Repo.init(str(git_root))
repo.git.checkout("-b", "master")
index = repo.index
# Copy the test files to the temporary directory
test_files = [
{"docstrings_common.json": "python"},
{"docstrings_simulators.json": "python"},
{"dune.module": ""},
{"index.html": "python/sphinx_docs/docs/_build/master"},
]
for file_info in test_files:
# Copy the file to the destination directory, creating any necessary parent directories
for filename, sub_dir in file_info.items():
dest_dir = git_root / sub_dir
dest_dir.mkdir(parents=True, exist_ok=True)
dest_file = dest_dir / filename
shutil.copy(test_file_path / filename, dest_file)
index.add([str(dest_file)])
author = git.Actor("opmuser", "opm.user@gmail.com")
committer = author
index.commit("Initial commit", author=author, committer=committer)
return git_root
return _create_git_repo
172 changes: 172 additions & 0 deletions python/sphinx_docs/tests/files/docstrings_common.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
{
"SummaryStateClass":{
"type": "class",
"signature": "opm.io.sim.SummaryState",
"doc": "The SummaryState class - this is where the current summary results of the simulator are stored.\nThe SummaryState class has methods to get hold of well, group and general variables."
},
"SummaryState_update_well_var": {
"signature": "opm.io.sim.SummaryState.update_well_var(well_name: str, variable_name: str, new_value: double) -> None",
"doc": "Updates the variable of a well.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param variable_name: The name of the variable to update.\n:type variable_name: str\n:param new_value: The new value of the variable.\n:type new_value: double"
},
"SummaryState_update_group_var": {
"signature": "opm.io.sim.SummaryState.update_group_var(group_name: str, variable_name: str, new_value: double) -> None",
"doc": "Updates the variable of a group.\n\n:param group_name: The name of the group.\n:type group_name: str\n:param variable_name: The name of the variable to update.\n:type variable_name: str\n:param new_value: The new value of the variable.\n:type new_value: double"
},
"SummaryState_well_var": {
"signature": "opm.io.sim.SummaryState.well_var(well_name: str, variable_name: str) -> double",
"doc": "Gets the value of a variable for a well.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param variable_name: The name of the variable to retrieve.\n:type variable_name: str\n\n:return: The value of the specified variable for the well. \n:type return: double"
},
"SummaryState_group_var": {
"signature": "opm.io.sim.SummaryState.group_var(group_name: str, variable_name: str) -> double",
"doc": "Gets the value of a variable for a group.\n\n:param group_name: The name of the group.\n:type group_name: str\n:param variable_name: The name of the variable to retrieve.\n:type variable_name: str\n\n:return: The value of the specified variable for the group. \n:type return: double"
},
"SummaryState_elapsed": {
"signature": "opm.io.sim.SummaryState.elapsed() -> double",
"doc": "Returns the elapsed time in seconds of the current simulation.\n\n:return: The elapsed time in seconds. \n:type return: double"
},
"SummaryState_groups": {
"signature": "opm.io.sim.SummaryState.groups -> list",
"doc": "Returns a list of strings containing all group names.\n\n:return: A list of strings representing all group names. \n:type return: list"
},
"SummaryState_wells": {
"signature": "opm.io.sim.SummaryState.wells -> list",
"doc": "Returns a list of strings containing all well names.\n\n:return: A list of strings representing all well names. \n:type return: list"
},
"SummaryState_has_well_var": {
"signature": "opm.io.sim.SummaryState.has_well_var(well_name: str, variable_name: str) -> bool",
"doc": "Checks if a well variable exists.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param variable_name: The name of the variable to check.\n:type variable_name: str\n\n:return: True if the variable exists for the well, False otherwise. \n:type return: bool"
},
"SummaryState_has_group_var": {
"signature": "opm.io.sim.SummaryState.has_group_var(group_name: str, variable_name: str) -> bool",
"doc": "Checks if a group variable exists.\n\n:param group_name: The name of the group.\n:type group_name: str\n:param variable_name: The name of the variable to check.\n:type variable_name: str\n\n:return: True if the variable exists for the group, False otherwise. \n:type return: bool"
},
"EclipseStateClass": {
"type": "class",
"signature": "opm.io.ecl_state.EclipseState",
"doc": "The EclipseState class - this is a representation of all static properties in the model,ranging from porosity to relperm tables.\nThe content of the EclipseState is immutable and may not be changed at runtime."
},
"EclipseState_input_nnc": {
"signature": "opm.io.ecl_state.EclipseState.input_nnc() -> list",
"doc": "Returns a list of non-neighboring connections.\n\nOne non-neighboring connection is a tuple containing the following elements:\n- index1 (int): Index of the first cell.\n- index2 (int): Index of the second cell.\n- transmissibility (double): Transmissibility between the two cells.\n\n:return: A list of non-neighboring connections. \n:type return: list"
},
"EclipseState_faultNames": {
"signature": "opm.io.ecl_state.EclipseState.faultNames() -> list",
"doc": "Returns a list of fault names.\n\n:return: A list containing the names of faults. \n:type return: list"
},
"EclipseState_faultFaces": {
"signature": "opm.io.ecl_state.EclipseState.faultFaces(fault_name: str) -> list",
"doc": "Returns a list of faces of a fault with the given name.\n\n:param fault_name: The name of the fault.\n:type fault_name: str\n\n:return: A list containing the faces of the specified fault. \n:type return: list"
},
"EclipseState_jfunc": {
"signature": "opm.io.ecl_state.EclipseState.jfunc() -> dict",
"doc": "Function returning a dictionary with the following entries: ['FLAG', 'DIRECTION', 'ALPHA_FACTOR', 'BETA_FACTOR', 'OIL_WATER', 'GAS_OIL']\n\n:return: A dictionary containing the specified entries. \n:type return: dict"
},
"EclipseState_simulation": {
"signature": "opm.io.ecl_state.EclipseState.simulation() -> SimulationConfiguration",
"doc": "Returns the simulation configuration.\n\n:return: The simulation configuration. \n:type return: SimulationConfiguration"
},
"ScheduleClass": {
"type": "class",
"signature": "opm.io.schedule.Schedule",
"doc": "The Schedule class - this is a representation of all the content from the SCHEDULE section, notably all well and group information and the timestepping."
},
"Schedule_getitem": {
"signature": "opm.io.schedule.Schedule.__getitem__(report_step: int) -> ScheduleState",
"doc": "Returns the ScheduleState at the given report step.\n\n:param report_step: The report step.\n:type report_step: int\n\n:return: The ScheduleState at the given report step.\n:type return: ScheduleState"
},
"Schedule_shut_well_well_name_step": {
"signature": "opm.io.schedule.Schedule.shut_well(well_name: str, step: int) -> None",
"doc": "Shuts down a well at a given report step.\n\n:param well_name: The name of the well to shut down.\n:type well_name: str\n:param step: The report step at which to shut down the well.\n:type step: int"
},
"Schedule_shut_well_well_name": {
"signature": "opm.io.schedule.Schedule.shut_well(well_name: str) -> None",
"doc": "Shuts down a well at the current report step.\n\n:param well_name: The name of the well to shut down.\n:type well_name: str"
},
"Schedule_open_well_well_name_step": {
"signature": "opm.io.schedule.Schedule.open_well(well_name: str, step: int) -> None",
"doc": "Opens a well at a given report step.\n\n:param well_name: The name of the well to open.\n:type well_name: str\n:param step: The report step at which to open the well.\n:type step: int\n:raises ValueError: If the report step is in the past or exceeds the duration of the simulation."
},
"Schedule_open_well_well_name": {
"signature": "opm.io.schedule.Schedule.open_well(well_name: str) -> None",
"doc": "Opens a well at the current report step.\n\n:param well_name: The name of the well to open.\n:type well_name: str"
},
"Schedule_stop_well_well_name_step":{
"signature": "opm.io.schedule.Schedule.stop_well(well_name: str, step: int) -> None",
"doc": "Stops a well at a given report step.\n\n:param well_name: The name of the well to stop.\n:type well_name: str\n:param step: The report step at which to stop the well.\n:type step: int\n:raises ValueError: If the report step is in the past or exceeds the duration of the simulation."
},
"Schedule_stop_well_well_name": {
"signature": "opm.io.schedule.Schedule.stop_well(well_name: str) -> None",
"doc": "Stops a well at the current report step.\n\n:param well_name: The name of the well to stop.\n:type well_name: str"
},
"Schedule_get_injection_properties": {
"signature": "opm.io.schedule.Schedule.get_injection_properties(well_name: str, report_step: int) -> dict",
"doc": "Gets injection properties for a well at a specific report step.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param report_step: The report step to retrieve properties for.\n:type report_step: int\n\n:return: A dict containing the properties surf_inj_rate, resv_inj_rate, bhp_target, thp_target. \n:type return: dict"
},
"Schedule_get_production_properties": {
"signature": "opm.io.schedule.Schedule.get_production_properties(well_name: str, report_step: int) -> dict",
"doc": "Gets production properties for a well at a specific report step.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param report_step: The report step to retrieve properties for.\n:type report_step: int\n\n:return: A dict containing the properties oil_rate, gas_rate, water_rate, liquid_rate, resv_rate, bhp_target, thp_target, alq_value. \n:type return: dict"
},
"Schedule_groups": {
"signature": "opm.io.schedule.Schedule._groups(report_step: int) -> list",
"doc": "Gets a list of all groups at a specified report step.\n\n:param report_step: The report step to retrieve groups for.\n:type report_step: int\n\n:return: A list containing all groups at the specified report step. \n:type return: list"
},
"Schedule_get_well": {
"signature": "opm.io.schedule.Schedule.get_well(well_name: str, report_step: int) -> Well",
"doc": "Retrieves a well at a given report step.\n\n:param well_name: The name of the well.\n:type well_name: str\n:param report_step: The report step.\n:type report_step: int\n\n:return: Well object at the given report step. \n:type return: well"
},
"Schedule_get_wells": {
"signature": "opm.io.schedule.Schedule.get_wells(well_name_pattern: str) -> list",
"doc": "Gets the names of wells matching a specified pattern.\n\n:param well_name_pattern: The pattern for well names, where '*' acts as a wildcard.\n:type well_name_pattern: str\n\n:return: A list containing the names of wells that match the specified pattern. \n:type return: list"
},
"GroupClass": {
"signature": "Group",
"type": "class",
"doc": "The Group class."
},
"Group_name": {
"signature": "Group.name",
"doc": "Returns the name of this group.\n\n:return: The name of this group.\n:type return: str"
},
"Group_num_wells": {
"signature": "Group.num_wells",
"doc": "Returns the number of wells in this group.\n\n:return: The number of wells in this group.\n:type return: int"
},
"Group_well_names": {
"signature": "Group.well_names",
"doc": "Returns a list of all well names in this group.\n\n:return: A list of all well names in this group.\n:type return: list"
},
"ScheduleStateClass": {
"signature": "ScheduleState",
"type": "class",
"doc": "The ScheduleState class."
},
"ScheduleState_nupcol": {
"signature": "ScheduleState.nupcol",
"doc": "The NUPCOL value at this Schedule State. This is a positive integer that defines the maximum number of Newton iterations used to update well targets within a time step."
},
"ScheduleState_get_group": {
"signature": "ScheduleState.get_group(group_name: str) -> Group",
"doc": "Gets the group with the specified name from the schedule state.\n\n:param group_name: The name of the group to retrieve from the schedule state.\n:type group_name: str\n\n:return: The group with the specified name from the schedule state. \n:type return: Group"
},
"WellClass": {
"type": "class",
"signature": "Well",
"doc": "The Well class."
},
"Well_pos": {
"signature": "Well.pos() -> tuple",
"doc": "Retrieves the position of the well.\n\n:return: A tuple containing the (i, j) coordinates and the reference depth of the well. \n:type return: tuple"
},
"Well_isdefined": {
"signature": "Well.isdefined(report_step: int) -> bool",
"doc": "Checks if the well is defined at a specific report step.\n\n:param report_step: The report step to check for the well's definition.\n:type report_step: int\n\n:return: True if the well is defined at the specified report step, False otherwise. \n:type return: bool"
},
"Well_available_gctrl": {
"signature": "Well.available_gctrl() -> bool",
"doc": "Checks if the well is available for group control.\n\n:return: True if the well is available for group control, False otherwise. \n:type return: bool"
},
"Well_connections": {
"signature": "Well.connections() -> list",
"doc": "Gets a list of all connections associated with the well.\n\n:return: A list containing all connections of the well. \n:type return: list"
}
}
Loading
Loading