Source code for syd.support
from abc import ABCMeta
from typing import Any, List, Union
from warnings import warn
from contextlib import contextmanager
import matplotlib.pyplot as plt
def show_open_servers():
"""Show all open Flask servers."""
from .flask_deployment.deployer import server_manager
print(server_manager.servers)
def close_servers(port: Union[int, None] = None):
"""Close any Flask servers running on a given port (or all of them).
Parameters
----------
port : int | None, optional
The port of the Flask server to close. If None, all servers will be closed.
Examples
--------
>>> close() # Close all Flask servers
>>> close(8000) # Close the Flask server running on port 8000
"""
from .flask_deployment.deployer import server_manager
server_manager.close_app(port)
@contextmanager
def plot_context():
plt.ioff()
try:
yield
finally:
plt.ion()
[docs]
class NoUpdate:
"""Singleton class to represent a non-update in parameter operations."""
_instance = None
_noupdate_identifier = "NO_UPDATE"
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __eq__(self, other: Any):
"""This makes sure all comparisons of NoUpdate objects return True"""
return isinstance(other, NoUpdate) or (
hasattr(other, "_noupdate_identifier")
and other._noupdate_identifier == self._noupdate_identifier
)
def __repr__(self):
return "NotUpdated"
[docs]
class NoInitialValue:
"""Singleton class to represent a non-initial value in parameter operations."""
_instance = None
_noinitialvalue_identifier = "NO_INITIAL_VALUE"
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __eq__(self, other: Any):
"""This makes sure all comparisons of NoInitialValue objects return True"""
return isinstance(other, NoInitialValue) or (
hasattr(other, "_noinitialvalue_identifier")
and other._noinitialvalue_identifier == self._noinitialvalue_identifier
)
def __repr__(self):
return "NotInitialized"
# Keep original Parameter class and exceptions unchanged
[docs]
class ParameterAddError(Exception):
"""
Exception raised when there is an error creating a new parameter.
Parameters
----------
parameter_name : str
Name of the parameter that failed to be created
parameter_type : str
Type of the parameter that failed to be created
message : str, optional
Additional error details
"""
def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
self.parameter_name = parameter_name
self.parameter_type = parameter_type
super().__init__(
f"Failed to create {parameter_type} parameter '{parameter_name}'"
+ (f": {message}" if message else "")
)
[docs]
class ParameterUpdateError(Exception):
"""
Exception raised when there is an error updating an existing parameter.
Parameters
----------
parameter_name : str
Name of the parameter that failed to update
parameter_type : str
Type of the parameter that failed to update
message : str, optional
Additional error details
"""
def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
self.parameter_name = parameter_name
self.parameter_type = parameter_type
super().__init__(
f"Failed to update {parameter_type} parameter '{parameter_name}'"
+ (f": {message}" if message else "")
)
[docs]
class ParameterUpdateWarning(Warning):
"""
Warning raised when there is a non-critical issue updating a parameter.
Parameters
----------
parameter_name : str
Name of the parameter that had the warning
parameter_type : str
Type of the parameter
message : str, optional
Additional warning details
"""
def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
self.parameter_name = parameter_name
self.parameter_type = parameter_type
super().__init__(
f"Warning updating {parameter_type} parameter '{parameter_name}'"
+ (f": {message}" if message else "")
)
[docs]
def warn_parameter_update(
parameter_name: str, parameter_type: str, message: str = None
):
"""
Warn the user that a parameter has been updated to a value behind the scenes.
"""
warn(ParameterUpdateWarning(parameter_name, parameter_type, message))
[docs]
def get_parameter_attributes(param_class) -> List[str]:
"""
Get all valid attributes for a parameter class.
Parameters
----------
param_class : class
The parameter class to inspect
Returns
-------
list of str
Names of all valid attributes for the parameter class
"""
attributes = []
# Walk through class hierarchy in reverse (most specific to most general)
for cls in reversed(param_class.__mro__):
if hasattr(cls, "__annotations__"):
# Only add annotations that haven't been specified by a more specific class
for name in cls.__annotations__:
if not name.startswith("_"):
attributes.append(name)
return attributes