Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BAI-1246 Python Logging #1284

Merged
merged 6 commits into from
Jun 6, 2024
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
4 changes: 2 additions & 2 deletions lib/python/docs/notebooks/access_requests_demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": ".venv",
"language": "python",
"name": "python"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand Down
9 changes: 0 additions & 9 deletions lib/python/docs/notebooks/datacards_demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,6 @@
"In order to create helper classes, you will first need to instantiate a `Client()` object from the core. By default, this object will not support any authentication. However, Bailo also supports PKI authentication, which you can use from Python by passing a `PkiAgent()` object into the `Client()` object when you instantiate it."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"! pip install bailo -e ../.."
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
9 changes: 6 additions & 3 deletions lib/python/src/bailo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
Bailo is a ecosystem for managing the lifecycle of managing machine learning models. This package provides support for interacting with models within Bailo.
"""
from __future__ import annotations
import logging


# Package Version 2.3.1
__version__ = "2.3.1"
# Package Version 2.3.2
__version__ = "2.3.2"


from bailo.core.agent import Agent, PkiAgent, TokenAgent
Expand All @@ -19,3 +19,6 @@
from bailo.helper.model import Experiment, Model
from bailo.helper.release import Release
from bailo.helper.schema import Schema


logging.getLogger(__name__).addHandler(logging.NullHandler())
11 changes: 11 additions & 0 deletions lib/python/src/bailo/core/agent.py
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging should not be configured on a library. But instead should be used by developers wanting to debug code in application bound tasks. To prevent general users getting log messages we can add this line to the top level initialiser. logging.getLogger(__name__).addHandler(logging.NullHandler())

There is some good information on logging with libraries here.

Developers can then use something like this to enable logging:

import logging

logging.basicConfig()
logging.getLogger('bailo').propagate = True

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import requests
import os
import getpass
import logging
from requests.auth import HTTPBasicAuth
from bailo.core.exceptions import BailoException, ResponseException

logger = logging.getLogger(__name__)


class Agent:
"""Base API Agent for talking with Bailo.
Expand Down Expand Up @@ -108,16 +111,24 @@ def __init__(
super().__init__()

if access_key is None:
logger.info("Access key not provided. Trying other sources...")
try:
access_key = os.environ["BAILO_ACCESS_KEY"]
logger.info("Access key acquired from BAILO_ACCESS_KEY environment variable.")
except KeyError:
logger.info("Access key not found in BAILO_ACCESS_KEY environment variable. Requires user input.")
access_key = getpass.getpass("BAILO ACCESS KEY:")
logger.info("Access key acquired from user input.")

if secret_key is None:
logger.info("Secret key not provided. Trying other sources...")
try:
secret_key = os.environ["BAILO_SECRET_KEY"]
logger.info("Secret key acquired from BAILO_SECRET_KEY environment variable.")
except KeyError:
logger.info("Secret key not found in BAILO_SECRET_KEY environment variable. Requires user input.")
secret_key = getpass.getpass("BAILO SECRET KEY:")
logger.info("Secret key acquired from user input.")

self.access_key = access_key
self.secret_key = secret_key
Expand Down
14 changes: 14 additions & 0 deletions lib/python/src/bailo/helper/access_request.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from __future__ import annotations

from typing import Any
import logging

from bailo.core.client import Client

logger = logging.getLogger(__name__)


class AccessRequest:
"""Represent a review within Bailo.
Expand Down Expand Up @@ -53,6 +56,8 @@ def from_id(cls, client: Client, model_id: str, access_request_id: str) -> Acces

schema_id = json_access_request["schemaId"]

logger.info(f"Access request %s for model %s successfully retrieved from server.", access_request_id, model_id)

return cls(
client,
model_id,
Expand Down Expand Up @@ -82,6 +87,10 @@ def create(cls, client: Client, model_id: str, schema_id: str, metadata: Any) ->
metadata = access_request_json["metadata"]
created_by = access_request_json["createdBy"]

logger.info(
f"Access request successfully created on server with ID %s for model %s.", access_request_id, model_id
)

return cls(
client,
model_id,
Expand All @@ -98,12 +107,17 @@ def delete(self) -> bool:
:return: A message confirming the removal of the access request.
"""
self.client.delete_access_request(self.model_id, self.access_request_id)

logger.info(f"Access request %s successfully deleted on server.", self.access_request_id)

return True

def update(self):
"""Update the current state of the access request to Bailo."""
self.client.patch_access_request(self.model_id, self.access_request_id, metadata=self.metadata)

logger.info(f"Access request %s successfully updated on server.", self.access_request_id)

def __str__(self) -> str:
return f"Access Request: {self.metadata['overview']['name']} - {self.model_id}"

Expand Down
10 changes: 9 additions & 1 deletion lib/python/src/bailo/helper/datacard.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from __future__ import annotations

from typing import Any
import logging

from bailo.core.client import Client
from bailo.core.enums import EntryKind, ModelVisibility
from bailo.core.exceptions import BailoException
from bailo.helper.entry import Entry

logger = logging.getLogger(__name__)


class Datacard(Entry):
"""Represent a datacard within Bailo.
Expand Down Expand Up @@ -58,9 +61,12 @@ def create(
res = client.post_model(
name=name, kind=EntryKind.DATACARD, description=description, team_id=team_id, visibility=visibility
)
datacard_id = res["model"]["id"]
logger.info(f"Datacard successfully created on server with ID %s.", datacard_id)

datacard = cls(
client=client,
datacard_id=res["model"]["id"],
datacard_id=datacard_id,
name=name,
description=description,
visibility=visibility,
Expand All @@ -84,6 +90,8 @@ def from_id(cls, client: Client, datacard_id: str) -> Datacard:
f"ID {datacard_id} does not belong to a datacard. Did you mean to use Model.from_id()?"
)

logger.info(f"Datacard %s successfully retrieved from server.", datacard_id)

datacard = cls(
client=client,
datacard_id=datacard_id,
Expand Down
16 changes: 16 additions & 0 deletions lib/python/src/bailo/helper/entry.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from __future__ import annotations

from typing import Any
import logging

from bailo.core.client import Client
from bailo.core.enums import EntryKind, ModelVisibility
from bailo.core.exceptions import BailoException

logger = logging.getLogger(__name__)


class Entry:
def __init__(
Expand Down Expand Up @@ -40,6 +43,8 @@ def update(self) -> None:
)
self._unpack(res["model"])

logger.info(f"ID %s updated locally and on server.", self.id)

def card_from_schema(self, schema_id: str) -> None:
"""Create a card using a schema on Bailo.

Expand All @@ -48,6 +53,8 @@ def card_from_schema(self, schema_id: str) -> None:
res = self.client.model_card_from_schema(model_id=self.id, schema_id=schema_id)
self.__unpack_card(res["card"])

logger.info(f"Card for ID %s successfully created using schema ID %s.", self.id, schema_id)

def card_from_template(self):
"""Create a card using a template (not yet implemented).

Expand All @@ -60,6 +67,7 @@ def get_card_latest(self) -> None:
res = self.client.get_model(model_id=self.id)
if "card" in res["model"]:
self.__unpack_card(res["model"]["card"])
logger.info(f"Latest card for ID %s successfully retrieved.", self.id)
else:
raise BailoException(f"A model card doesn't exist for model {self.id}")

Expand All @@ -71,6 +79,8 @@ def get_card_revision(self, version: str) -> None:
res = self.client.get_model_card(model_id=self.id, version=version)
self.__unpack_card(res["modelCard"])

logger.info(f"Card version %s for ID %s successfully retrieved.", version, self.id)

def get_roles(self):
"""Get all roles for the entry.

Expand All @@ -96,6 +106,8 @@ def _update_card(self, card: dict[str, Any] | None = None) -> None:
res = self.client.put_model_card(model_id=self.id, metadata=card)
self.__unpack_card(res["card"])

logger.info(f"Card for %s successfully updated on server.", self.id)

def _unpack(self, res):
self.id = res["id"]
self.name = res["name"]
Expand All @@ -106,6 +118,8 @@ def _unpack(self, res):
else:
self.visibility = ModelVisibility.PUBLIC

logger.info(f"Attributes for ID %s successfully unpacked.", self.id)

def __unpack_card(self, res):
self._card_version = res["version"]
self._card_schema = res["schemaId"]
Expand All @@ -114,3 +128,5 @@ def __unpack_card(self, res):
self._card = res["metadata"]
except KeyError:
self._card = None

logger.info(f"Card attributes for ID %s successfully unpacked.", self.id)
Loading
Loading