Skip to content

Commit

Permalink
Rename notification class (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
mtth authored Apr 23, 2023
1 parent b1ef5f4 commit 2af7b08
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 10 deletions.
4 changes: 2 additions & 2 deletions opvious/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from .client import Client, ClientSetting
from .common import __version__
from .data.attempts import Attempt, AttemptRequest, Notification
from .data.attempts import Attempt, AttemptNotification, AttemptRequest
from .data.outcomes import (
CancelledOutcome,
FailedOutcome,
Expand Down Expand Up @@ -55,6 +55,7 @@

__all__ = [
"Attempt",
"AttemptNotification",
"AttemptRequest",
"CancelledOutcome",
"Client",
Expand All @@ -72,7 +73,6 @@
"KeyItem",
"Label",
"LocalSpecification",
"Notification",
"Outcome",
"Outline",
"Relaxation",
Expand Down
6 changes: 3 additions & 3 deletions opvious/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
from .data.attempts import (
Attempt,
attempt_from_graphql,
AttemptNotification,
AttemptRequest,
Notification,
notification_from_graphql,
)
from .data.outcomes import (
Expand Down Expand Up @@ -524,7 +524,7 @@ async def cancel_attempt(self, uuid: str) -> bool:

async def poll_attempt(
self, attempt: Attempt
) -> Union[Notification, Outcome]:
) -> Union[AttemptNotification, Outcome]:
"""Polls an attempt for its outcome or latest progress notification
Args:
Expand Down Expand Up @@ -563,7 +563,7 @@ async def poll_attempt(
)
async def _track_attempt(self, attempt: Attempt) -> Optional[Outcome]:
ret = await self.poll_attempt(attempt)
if isinstance(ret, Notification):
if isinstance(ret, AttemptNotification):
delta = datetime.now(timezone.utc) - attempt.started_at
elapsed = humanize.naturaldelta(delta, minimum_unit="milliseconds")
if ret.dequeued:
Expand Down
6 changes: 3 additions & 3 deletions opvious/data/attempts.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def attempt_from_graphql(data: Any, outline: Outline, url: str) -> Attempt:


@dataclasses.dataclass(frozen=True)
class Notification:
class AttemptNotification:
"""Attempt progress update notification"""

dequeued: bool
Expand All @@ -68,8 +68,8 @@ class Notification:

def notification_from_graphql(
dequeued: bool, data: Any = None
) -> Notification:
return Notification(
) -> AttemptNotification:
return AttemptNotification(
dequeued=dequeued,
relative_gap=data["relativeGap"] if data else None,
lp_iteration_count=data["lpIterationCount"] if data else None,
Expand Down
51 changes: 50 additions & 1 deletion opvious/data/solves.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

@dataclasses.dataclass(frozen=True)
class SolveSummary:
"""Solve summary statistics"""

column_count: int
row_count: int
weight_count: int
Expand Down Expand Up @@ -60,6 +62,8 @@ def _entry_index(entries, bindings):

@dataclasses.dataclass(frozen=True)
class SolveInputs:
"""Solve input data"""

outline: Outline
raw_parameters: list[Any]
raw_dimensions: Optional[list[Any]]
Expand All @@ -84,6 +88,8 @@ def dimension(self, label: Label) -> pd.Index:

@dataclasses.dataclass(frozen=True)
class SolveOutputs:
"""Successful solve output data"""

outline: Outline
raw_variables: list[Any]
raw_constraints: list[Any]
Expand Down Expand Up @@ -141,6 +147,8 @@ def constraint(self, label: Label) -> pd.DataFrame:

@dataclasses.dataclass(frozen=True)
class SolveResponse:
"""Solver response"""

status: SolveStatus
outcome: Outcome
summary: SolveSummary
Expand Down Expand Up @@ -190,6 +198,8 @@ def from_json(

@dataclasses.dataclass(frozen=True)
class Relaxation:
"""Problem relaxation configuration"""

penalty: RelaxationPenalty = _DEFAULT_PENALTY
objective_weight: Optional[float] = None
constraints: Optional[list[ConstraintRelaxation]] = None
Expand All @@ -201,7 +211,7 @@ def from_constraint_labels(
penalty: RelaxationPenalty = _DEFAULT_PENALTY,
objective_weight: Optional[float] = None,
) -> Relaxation:
"""Relaxes all input constraints using a common penalty."""
"""Relaxes all input constraints using a common penalty"""
return Relaxation(
penalty=penalty,
objective_weight=objective_weight,
Expand All @@ -222,6 +232,8 @@ def to_json(self):

@dataclasses.dataclass(frozen=True)
class ConstraintRelaxation:
"""Constraint relaxation configuration"""

label: Label
penalty: Optional[str] = None
cost: Optional[float] = None
Expand All @@ -242,12 +254,49 @@ def to_json(self):

@dataclasses.dataclass(frozen=True)
class SolveOptions:
"""Solving options"""

relative_gap_threshold: Optional[float] = None
"""Relative gap threshold below which a solution is considered optimal
For example a value of 0.1 will cause a solution to be optimal when the
optimality gap is at most 10%. See also `absolute_gap_threshold` for a
non-relative variant.
"""

absolute_gap_threshold: Optional[float] = None
"""Absolute gap threshold below which a solution is considered optimal
See also `relative_gap_threshold` for a relative variant.
"""

zero_value_threshold: Optional[float] = None
"""Positive magnitude below which tensor values are assumed equal to zero
This option is also used on solution results, causing values to be omitted
from the solution if their dual value is also absent. It is finally used as
threshold for rounding integral variables to the nearest integer. The
default is 1e-6.
"""

infinity_value_threshold: Optional[float] = None
"""Positive magnitude used to cap all input values
It is illegal for the reified problem to include coefficients higher or
equal to this value so the input needs to be such that they are masked out
during reification. The default is 1e13.
"""

free_bound_threshold: Optional[float] = None
"""Positive magnitude used to decide whether a bound is free
This value should typically be slightly smaller to the infinity value
threshold to allow for small offsets to infinite values. The default is
1e12.
"""

timeout_millis: Optional[float] = None
"""Upper bound on solving time"""


def solve_options_to_json(
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "opvious"
version = "0.11.4"
version = "0.11.5"
description = "Opvious Python SDK"
authors = ["Opvious Engineering <oss@opvious.io>"]
readme = "README.md"
Expand Down

0 comments on commit 2af7b08

Please sign in to comment.