diff --git a/examples/02_plan_and_execute.py b/examples/02_plan_and_execute.py index d7d9849e..9b513cdb 100644 --- a/examples/02_plan_and_execute.py +++ b/examples/02_plan_and_execute.py @@ -17,8 +17,6 @@ async def main(): controllers = await cell.controllers() controller = controllers[0] - # Define a home position - # Connect to the controller and activate motion groups async with controller[0] as motion_group: home_joints = await motion_group.joints() diff --git a/nova/core/logging_setup.py b/nova/core/logging_setup.py new file mode 100644 index 00000000..b2980613 --- /dev/null +++ b/nova/core/logging_setup.py @@ -0,0 +1,13 @@ +import sys +from loguru import logger + + +def configure_logging(log_level: str = "INFO"): + logger.remove() + logger.add( + sys.stderr, + level=log_level, + format="<green>{time}</green> | <level>{level}</level> | <level>{message}</level>", + ) + + return logger diff --git a/nova/core/nova.py b/nova/core/nova.py index dad9517c..9488c370 100644 --- a/nova/core/nova.py +++ b/nova/core/nova.py @@ -1,5 +1,6 @@ from nova.core.controller import Controller from nova.core.exceptions import ControllerNotFoundException +from nova.core.logging_setup import configure_logging from nova.gateway import ApiGateway import wandelbots_api_client as wb from decouple import config @@ -14,13 +15,17 @@ def __init__( password: str | None = None, access_token: str | None = None, version: str = "v1", + verify_ssl: bool = True, + log_level: str = "INFO", ): + configure_logging(log_level) self._api_client = ApiGateway( host=host, username=username, password=password, access_token=access_token, version=version, + verify_ssl=verify_ssl, ) def cell(self, cell_id: str = config("CELL_NAME", default="cell")) -> "Cell": diff --git a/nova/gateway.py b/nova/gateway.py index 388b1fa0..a6cbaad3 100644 --- a/nova/gateway.py +++ b/nova/gateway.py @@ -30,26 +30,33 @@ def __getattr__(self, name): @functools.wraps(original_attr) async def async_wrapper(*args, **kwargs): - logger.info(f"Calling {name} with args={args}, kwargs={kwargs}") start = time.time() try: return await original_attr(*args, **kwargs) + except Exception as e: + logger.error(f"API CALL: {name} failed with error: {e}") + logger.debug(f"API CALL FAILED: {name} with args={args}, kwargs={kwargs}") + raise e finally: duration = time.time() - start - logger.info(f"{name} took {duration:.2f} seconds") + logger.info(f"API CALL: {name} took {duration:.2f} seconds") + logger.debug(f"API CALL: {name} with args={args}, kwargs={kwargs}") return async_wrapper # Wrap sync callables @functools.wraps(original_attr) def sync_wrapper(*args, **kwargs): - logger.debug(f"Calling {name} with args={args}, kwargs={kwargs}") start = time.time() try: return original_attr(*args, **kwargs) + except Exception as e: + logger.error(f"API CALL: {name} failed with error: {e}") + raise e finally: duration = time.time() - start - logger.debug(f"{name} took {duration:.2f} seconds") + logger.info(f"API CALL: {name} took {duration:.2f} seconds") + logger.debug(f"API CALL: {name} with args={args}, kwargs={kwargs}") return sync_wrapper @@ -65,6 +72,7 @@ def __init__( password: str | None = None, access_token: str | None = None, version: str = "v1", + verify_ssl: bool = True, ): if host is None: host = config("NOVA_API", default=INTERNAL_CLUSTER_NOVA_API) @@ -78,9 +86,6 @@ def __init__( if access_token is None: access_token = config("NOVA_ACCESS_TOKEN", default=None) - if (username is None or password is None) and access_token is None: - raise ValueError("Please provide either username and password or an access token") - # Access token has more prio than username and password if both are provided at the same time, set username and # password to None if access_token is not None: @@ -94,8 +99,9 @@ def __init__( password=password, access_token=access_token, ) + api_client_config.verify_ssl = verify_ssl - self._api_client = wb.ApiClient(api_client_config) + self._api_client = wb.ApiClient(configuration=api_client_config) self._host = host # Use the intercept function to wrap each API client