Skip to content
Open
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
14 changes: 13 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion prek.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ id = "check-added-large-files"
repo = "https://github.com/astral-sh/ruff-pre-commit"
rev = "v0.15.14"
[[repos.hooks]]
id = "ruff"
id = "ruff-check"
args = ["--fix", "--exit-non-zero-on-fix", "--ignore=C901"]

[[repos.hooks]]
Expand Down
60 changes: 57 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ dependencies = [
"flatdict (==4.1.0)",
"pytest (>=9.0.3,<10.0.0)",
"unyt (>=3.1.0,<4.0.0)",
"pip>=26.1.2",
]

[project.urls]
Expand Down Expand Up @@ -88,9 +89,62 @@ dev = [
]

[tool.ruff]
lint.extend-select = ["C901", "T201"]
lint.mccabe.max-complexity = 11
extend-exclude = ["tests", "examples", "notebooks"]
extend-exclude = ["tests", "examples", "notebooks", "simvue/pynvml.py"]
preview = true

[tool.ruff.lint]
ignore = ["COM812", "PLR0904", "PLR6301", "D203", "D212"]
dummy-variable-rgx = "^_+$"
extend-select = [
"C90",
"D417",
"E",
"F",
"W",
"B",
"UP",
"I",
"SIM",
"ARG",
"RUF",
"RET",
"S",
"BLE",
"FBT",
"COM",
"A",
"C4",
"DTZ",
"ICN",
"G",
"PIE",
"T20",
"INP",
"PYI",
"PT",
"Q",
"RSE",
"SLOT",
"TID",
"TC",
"ARG",
"I",
"D417",
"ERA",
"PL",
"UP",
"FURB",
"N",
]

[tool.ruff.lint.mccabe]
max-complexity = 14

[tool.ruff.lint.pylint]
max-returns = 8
max-args = 20
max-branches = 15
max-statements = 60

[tool.pytest.ini_options]
addopts = "-p no:warnings --no-cov -n 0"
Expand Down
3 changes: 1 addition & 2 deletions simvue/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""
Simvue API
"""Simvue API.
==========

Module contains methods for interacting with a Simvue server
Expand Down
56 changes: 27 additions & 29 deletions simvue/api/objects/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""
Simvue API Objects
"""Simvue API Objects.
==================

The following module defines objects which provide exact representations
Expand All @@ -12,50 +11,49 @@
from .alert import (
Alert,
EventsAlert,
MetricsThresholdAlert,
MetricsRangeAlert,
MetricsThresholdAlert,
UserAlert,
)
from .storage import (
S3Storage,
FileStorage,
Storage,
)
from .artifact import (
Artifact,
FileArtifact,
ObjectArtifact,
Artifact,
)

from .stats import Stats
from .run import Run
from .tag import Tag
from .folder import Folder, get_folder_from_path
from .events import Events as Events
from .metrics import Metrics as Metrics
from .folder import Folder, get_folder_from_path
from .grids import Grid, GridMetrics
from .metrics import Metrics as Metrics
from .run import Run
from .stats import Stats
from .storage import (
FileStorage,
S3Storage,
Storage,
)
from .tag import Tag

__all__ = [
"Alert",
"Artifact",
"Events",
"EventsAlert",
"FileArtifact",
"FileStorage",
"Folder",
"Grid",
"GridMetrics",
"Metrics",
"Events",
"get_folder_from_path",
"Folder",
"Stats",
"Run",
"Tag",
"Artifact",
"FileArtifact",
"MetricsRangeAlert",
"MetricsThresholdAlert",
"ObjectArtifact",
"Run",
"S3Storage",
"FileStorage",
"Stats",
"Storage",
"MetricsRangeAlert",
"MetricsThresholdAlert",
"UserAlert",
"EventsAlert",
"Alert",
"Tag",
"Tenant",
"User",
"UserAlert",
"get_folder_from_path",
]
54 changes: 36 additions & 18 deletions simvue/api/objects/administrator/tenant.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
from typing import Self, override
except ImportError:
from typing_extensions import Self, override

import datetime
import typing
from collections.abc import Generator

import pydantic
import datetime

from simvue.api.objects.base import write_only, SimvueObject, staging_check
from simvue.api.objects.base import SimvueObject, staging_check, write_only
from simvue.models import DATETIME_FORMAT


Expand All @@ -33,7 +36,7 @@ def __init__(
server_token: pydantic.SecretStr | None = None,
**kwargs,
) -> None:
"""Initialise a Tenant
"""Initialise a Tenant.

If an identifier is provided a connection will be made to the
object matching the identifier on the target server.
Expand All @@ -51,9 +54,13 @@ def __init__(
token for alternative server, default None
**kwargs : dict
any additional arguments to be passed to the object initialiser

"""
super().__init__(
identifier, server_url=server_url, server_token=server_token, **kwargs
identifier,
server_url=server_url,
server_token=server_token,
**kwargs,
)

@override
Expand Down Expand Up @@ -123,7 +130,7 @@ def get(
offset: pydantic.NonNegativeInt | None = None,
server_url: str | None = None,
server_token: pydantic.SecretStr | None = None,
**kwargs,
**kwargs: typing.Any,
) -> Generator[tuple[str, Self | None]]:
"""Retrieve tenants from the server.

Expand All @@ -137,6 +144,8 @@ def get(
alternative server URL, default None
server_token : str | None, optional
token for alternative server, default None
**kwargs : Any
additional arguments for retrieval

Yields
------
Expand All @@ -146,86 +155,95 @@ def get(
Returns
-------
Generator[tuple[str, Tenant | None]]

"""
# Currently no tenant filters
_ = kwargs.pop("filters", None)
return super().get(
count=count, offset=offset, server_url=server_url, server_token=server_token
count=count,
offset=offset,
server_url=server_url,
server_token=server_token,
)

@property
def name(self) -> str:
"""Retrieve the name of the tenant"""
"""Retrieve the name of the tenant."""
return self._get_attribute("name")

@name.setter
@write_only
@pydantic.validate_call
def name(self, name: str) -> None:
"""Change name of tenant"""
"""Change name of tenant."""
self._staging["name"] = name

@property
@staging_check
def is_enabled(self) -> bool:
"""Retrieve if tenant is enabled"""
"""Retrieve if tenant is enabled."""
return self._get_attribute("is_enabled")

@is_enabled.setter
@write_only
@pydantic.validate_call
def is_enabled(self, is_enabled: bool) -> None:
"""Enable/disable tenant"""
"""Enable/disable tenant."""
self._staging["is_enabled"] = is_enabled

@property
@staging_check
def max_request_rate(self) -> int:
"""Retrieve the tenant's maximum request rate"""
"""Retrieve the tenant's maximum request rate."""
return self._get_attribute("max_request_rate")

@max_request_rate.setter
@write_only
@pydantic.validate_call
def max_request_rate(self, max_request_rate: int) -> None:
"""Update tenant's maximum request rate"""
"""Update tenant's maximum request rate."""
self._staging["max_request_rate"] = max_request_rate

@property
@staging_check
def max_runs(self) -> int:
"""Retrieve the tenant's maximum runs"""
"""Retrieve the tenant's maximum runs."""
return self._get_attribute("max_runs")

@max_runs.setter
@write_only
@pydantic.validate_call
def max_runs(self, max_runs: int) -> None:
"""Update tenant's maximum runs"""
"""Update tenant's maximum runs."""
self._staging["max_runs"] = max_runs

@property
@staging_check
def max_data_volume(self) -> int:
"""Retrieve the tenant's maximum data volume"""
"""Retrieve the tenant's maximum data volume."""
return self._get_attribute("max_data_volume")

@max_data_volume.setter
@write_only
@pydantic.validate_call
def max_data_volume(self, max_data_volume: int) -> None:
"""Update tenant's maximum data volume"""
"""Update tenant's maximum data volume."""
self._staging["max_data_volume"] = max_data_volume

@property
def created(self) -> datetime.datetime | None:
"""Set/retrieve created datetime for the run.
"""Set/retrieve created datetime in UTC for the run.

Returns
-------
datetime.datetime

"""
_created: str | None = self._get_attribute("created")
return (
datetime.datetime.strptime(_created, DATETIME_FORMAT) if _created else None
datetime.datetime.strptime(_created, DATETIME_FORMAT).astimezone(
datetime.UTC,
)
if _created
else None
)
Loading
Loading