From 345567372364ea6bedaac9042d646c725d4b699d Mon Sep 17 00:00:00 2001 From: BW27492 Date: Tue, 16 Jul 2024 11:16:58 +0000 Subject: [PATCH 1/3] Updated python notebooks for 2.5.0 --- .../notebooks/experiment_tracking_demo.ipynb | 37 ++++++++++++++++- .../models_and_releases_demo_pytorch.ipynb | 41 +++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/lib/python/docs/notebooks/experiment_tracking_demo.ipynb b/lib/python/docs/notebooks/experiment_tracking_demo.ipynb index ed17d944f..d0ed12cf4 100644 --- a/lib/python/docs/notebooks/experiment_tracking_demo.ipynb +++ b/lib/python/docs/notebooks/experiment_tracking_demo.ipynb @@ -249,7 +249,19 @@ "## Publishing results to Bailo\n", "\n", "Experiment runs can be published to the model card using the `Experiment.publish()` method, **one at a time**. This is because the intended use is only to publish the most successful run.\n", - "Therefore, you must specify the **run_id** to publish, as well as specify the location of the metrics in your schema (in this case *performance.performanceMetrics* as per the schema we defined earlier)." + "Therefore, you must specify the **run_id** to publish, or specify an order so the client can select the best result. As well as this, you must specify the location of the metrics in your schema (in this case *performance.performanceMetrics* as per the schema we defined earlier).\n", + "\n", + "Examples for both scenarios can be seen below." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Publishing a specific run\n", + "\n", + "To publish a specific run, you must pass the `run_id` into the method. In this example, use one of the IDs we created in the previous steps." ] }, { @@ -266,7 +278,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "If successful, our metrics should now be under the **Performance** tab of your model card on the UI! Additionally, our artifact will have been published as a new release." + "### Publishing the best run\n", + "\n", + "To publish the best run, you must define what the best is for your use case. This can be done using the `select_by` parameter with a string e.g. `accuracy MIN|MAX`. Depending on the requirements, `accuracy` could be any metric you have defined in your experiment.\n", + "\n", + "In the below example, we will use `accuracy MAX` to publish the experiment run with the highest accuracy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "experiment_mlflow.publish(mc_loc=\"performance.performanceMetrics\", select_by=\"accuracy MAX\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If successful, our metrics should now be under the **Performance** tab of your model card on the UI! Additionally, our artifact will have been published as a new release (*this will have been done twice if you ran both the above steps*)." ] } ], diff --git a/lib/python/docs/notebooks/models_and_releases_demo_pytorch.ipynb b/lib/python/docs/notebooks/models_and_releases_demo_pytorch.ipynb index 0f10c491a..040b49f50 100644 --- a/lib/python/docs/notebooks/models_and_releases_demo_pytorch.ipynb +++ b/lib/python/docs/notebooks/models_and_releases_demo_pytorch.ipynb @@ -348,6 +348,47 @@ "source": [ "If the message \"**All keys matched successfully**\" is displayed, we have successfully initated our model." ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Searching for models" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to fetching specific models, you can also use the `Model.search()` method to return a list of `Model()` objects that match your parameters. These parameters can be:\n", + "\n", + "* Task of the model (e.g. image classification).\n", + "* Libraries used for the model (e.g. PyTorch).\n", + "* Model card search (string to be found in model cards).\n", + "\n", + "In the below example, we'll just search for all models with no filters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "models = Model.search(client=client)\n", + "\n", + "print(models)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We should now have a list of `Model()` objects." + ] } ], "metadata": { From 892309842776e183f72b5b3388241531c073cdac Mon Sep 17 00:00:00 2001 From: BW27492 Date: Tue, 16 Jul 2024 11:21:19 +0000 Subject: [PATCH 2/3] Updated documentation --- .../_modules/bailo/core/agent/index.html | 62 +++- .../_modules/bailo/core/client/index.html | 6 +- .../_modules/bailo/core/enums/index.html | 11 + .../bailo/helper/access_request/index.html | 23 +- .../_modules/bailo/helper/datacard/index.html | 10 +- .../_modules/bailo/helper/entry/index.html | 41 ++- .../_modules/bailo/helper/model/index.html | 305 +++++++++++++++--- .../_modules/bailo/helper/release/index.html | 72 ++++- .../_modules/bailo/helper/schema/index.html | 25 +- .../notebooks/access_requests_demo.ipynb.txt | 4 +- .../notebooks/datacards_demo.ipynb.txt | 9 - .../experiment_tracking_demo.ipynb.txt | 37 ++- ...models_and_releases_demo_pytorch.ipynb.txt | 45 ++- .../_build/dirhtml/bailo.core/index.html | 52 ++- .../_build/dirhtml/bailo.helper/index.html | 87 ++++- .../_build/dirhtml/genindex/index.html | 37 ++- backend/python-docs/_build/dirhtml/index.html | 1 + .../notebooks/access_requests_demo.ipynb | 4 +- .../notebooks/access_requests_demo/index.html | 5 +- .../dirhtml/notebooks/datacards_demo.ipynb | 9 - .../notebooks/datacards_demo/index.html | 8 - .../notebooks/experiment_tracking_demo.ipynb | 37 ++- .../experiment_tracking_demo/index.html | 28 +- .../models_and_releases_demo_pytorch.ipynb | 45 ++- .../index.html | 26 +- .../python-docs/_build/dirhtml/objects.inv | Bin 12883 -> 13079 bytes .../python-docs/_build/dirhtml/searchindex.js | 2 +- .../html/_modules/bailo/core/agent.html | 62 +++- .../html/_modules/bailo/core/client.html | 6 +- .../html/_modules/bailo/core/enums.html | 11 + .../_modules/bailo/helper/access_request.html | 24 +- .../html/_modules/bailo/helper/datacard.html | 10 +- .../html/_modules/bailo/helper/entry.html | 41 ++- .../html/_modules/bailo/helper/model.html | 305 +++++++++++++++--- .../html/_modules/bailo/helper/release.html | 72 ++++- .../html/_modules/bailo/helper/schema.html | 26 +- .../notebooks/access_requests_demo.ipynb.txt | 4 +- .../notebooks/datacards_demo.ipynb.txt | 9 - .../experiment_tracking_demo.ipynb.txt | 37 ++- ...models_and_releases_demo_pytorch.ipynb.txt | 45 ++- .../python-docs/_build/html/bailo.helper.html | 87 ++++- backend/python-docs/_build/html/genindex.html | 37 ++- backend/python-docs/_build/html/index.html | 1 + .../html/notebooks/access_requests_demo.html | 5 +- .../_build/html/notebooks/datacards_demo.html | 8 - .../notebooks/experiment_tracking_demo.html | 28 +- .../models_and_releases_demo_pytorch.html | 26 +- backend/python-docs/_build/html/objects.inv | Bin 12944 -> 13141 bytes .../python-docs/_build/html/searchindex.js | 2 +- 49 files changed, 1566 insertions(+), 271 deletions(-) diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/core/agent/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/core/agent/index.html index 5af901ecb..2081657e6 100644 --- a/backend/python-docs/_build/dirhtml/_modules/bailo/core/agent/index.html +++ b/backend/python-docs/_build/dirhtml/_modules/bailo/core/agent/index.html @@ -91,9 +91,14 @@

Source code for bailo.core.agent

 from json import JSONDecodeError
 
 import requests
+import os
+import getpass
+import logging
 from requests.auth import HTTPBasicAuth
 from bailo.core.exceptions import BailoException, ResponseException
 
+logger = logging.getLogger(__name__)
+
 
 
[docs] @@ -103,9 +108,21 @@

Source code for bailo.core.agent

     Wraps each request in an exception handler that maps API errors to Python Bailo errors, among status codes less than 400.
     """
 
+
+[docs] + def __init__( + self, + verify: str | bool = True, + ): + """Initiate a standard agent. + + :param verify: Path to certificate authority file, or bool for SSL verification. + """ + self.verify = verify
+ + def __request(self, method, *args, **kwargs): - if "verify" not in kwargs: - kwargs["verify"] = True + kwargs["verify"] = self.verify res = requests.request(method, *args, **kwargs) @@ -175,39 +192,40 @@

Source code for bailo.core.agent

         :param key: Path to key file
         :param auth: Path to certificate authority file
         """
+        super().__init__(verify=auth)
+
         self.cert = cert
-        self.key = key
-        self.auth = auth
+ self.key = key
[docs] def get(self, *args, **kwargs): - return super().get(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
+ return super().get(*args, cert=(self.cert, self.key), **kwargs)
[docs] def post(self, *args, **kwargs): - return super().post(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
+ return super().post(*args, cert=(self.cert, self.key), **kwargs)
[docs] def put(self, *args, **kwargs): - return super().put(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
+ return super().put(*args, cert=(self.cert, self.key), **kwargs)
[docs] def patch(self, *args, **kwargs): - return super().patch(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
+ return super().patch(*args, cert=(self.cert, self.key), **kwargs)
[docs] def delete(self, *args, **kwargs): - return super().delete(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
+ return super().delete(*args, cert=(self.cert, self.key), **kwargs) @@ -219,14 +237,36 @@

Source code for bailo.core.agent

 [docs]
     def __init__(
         self,
-        access_key: str,
-        secret_key: str,
+        access_key: str | None = None,
+        secret_key: str | None = None,
     ):
         """Initiate an agent for API token authentication.
 
         :param access_key: Access key
         :param secret_key: Secret key
         """
+        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
         self.basic = HTTPBasicAuth(access_key, secret_key)
diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/core/client/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/core/client/index.html index b49482dcc..d3b575d83 100644 --- a/backend/python-docs/_build/dirhtml/_modules/bailo/core/client/index.html +++ b/backend/python-docs/_build/dirhtml/_modules/bailo/core/client/index.html @@ -150,6 +150,7 @@

Source code for bailo.core.client

 [docs]
     def get_models(
         self,
+        kind: EntryKind = EntryKind.MODEL,
         task: str | None = None,
         libraries: list[str] | None = None,
         filters: list[str] | None = None,
@@ -157,9 +158,10 @@ 

Source code for bailo.core.client

     ):
         """Find and returns a list of models based on provided search terms.
 
+        :param kind: Either a Model or a Datacard
         :param task: Model task (e.g. image classification), defaults to None
-        :param libraries: Model library (e.g. TensorFlow), defaults to []
-        :param filters: Custom filters, defaults to []
+        :param libraries: Model library (e.g. TensorFlow), defaults to None
+        :param filters: Custom filters, defaults to None
         :param search: String to be located in model cards, defaults to ""
         :return: JSON response object
         """
diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/core/enums/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/core/enums/index.html
index 1c83f7828..887dcb1e3 100644
--- a/backend/python-docs/_build/dirhtml/_modules/bailo/core/enums/index.html
+++ b/backend/python-docs/_build/dirhtml/_modules/bailo/core/enums/index.html
@@ -135,6 +135,17 @@ 

Source code for bailo.core.enums

     MODEL = "model"
     DATACARD = "data-card"
+ + +
+[docs] +class MinimalSchema(ValuedEnum): + """A minimal schema.""" + + MODEL = "minimal-general-v10" + DATACARD = "minimal-data-card-v10" + ACCESS_REQUEST = "minimal-access-request-general-v10"
+
diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/access_request/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/access_request/index.html index 741f0db91..c1470881d 100644 --- a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/access_request/index.html +++ b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/access_request/index.html @@ -89,8 +89,12 @@

Source code for bailo.helper.access_request

 from __future__ import annotations
 
 from typing import Any
+import logging
 
 from bailo.core.client import Client
+from bailo.core.enums import MinimalSchema
+
+logger = logging.getLogger(__name__)
 
 
 
@@ -145,6 +149,8 @@

Source code for bailo.helper.access_request

 
         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,
@@ -159,7 +165,9 @@ 

Source code for bailo.helper.access_request

 
[docs] @classmethod - def create(cls, client: Client, model_id: str, schema_id: str, metadata: Any) -> AccessRequest: + def create( + cls, client: Client, model_id: str, metadata: Any, schema_id: str = MinimalSchema.ACCESS_REQUEST + ) -> AccessRequest: """Make an access request for the model. Posts an access request to Bailo to be reviewed @@ -167,7 +175,7 @@

Source code for bailo.helper.access_request

         :param client: A client object used to interact with Bailo
         :param name: The name of the access request
         :param model_id: A unique model ID within Bailo
-        :param schema_id: A unique schema ID
+        :param schema_id: A unique schema ID, defaults to minimal-access-request-general-v10
         :return: JSON response object
         """
         access_request_json = client.post_access_request(model_id, metadata, schema_id)["accessRequest"]
@@ -177,6 +185,10 @@ 

Source code for bailo.helper.access_request

         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,
@@ -196,6 +208,9 @@ 

Source code for bailo.helper.access_request

         :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
@@ -203,7 +218,9 @@

Source code for bailo.helper.access_request

 [docs]
     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)
+ 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: diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/datacard/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/datacard/index.html index 4e32154bf..acec0efda 100644 --- a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/datacard/index.html +++ b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/datacard/index.html @@ -89,12 +89,15 @@

Source code for bailo.helper.datacard

 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__)
+
 
 
[docs] @@ -150,9 +153,12 @@

Source code for bailo.helper.datacard

         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,
@@ -179,6 +185,8 @@ 

Source code for bailo.helper.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,
diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/entry/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/entry/index.html
index d59730b00..e579678e9 100644
--- a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/entry/index.html
+++ b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/entry/index.html
@@ -89,11 +89,15 @@ 

Source code for bailo.helper.entry

 from __future__ import annotations
 
 from typing import Any
+import logging
+import warnings
 
 from bailo.core.client import Client
-from bailo.core.enums import EntryKind, ModelVisibility
+from bailo.core.enums import EntryKind, ModelVisibility, MinimalSchema
 from bailo.core.exceptions import BailoException
 
+logger = logging.getLogger(__name__)
+
 
 
[docs] @@ -130,18 +134,28 @@

Source code for bailo.helper.entry

             description=self.description,
             visibility=self.visibility,
         )
-        self._unpack(res["model"])
+ self._unpack(res["model"]) + + logger.info(f"ID %s updated locally and on server.", self.id)
[docs] - def card_from_schema(self, schema_id: str) -> None: + def card_from_schema(self, schema_id: str | None = None) -> None: """Create a card using a schema on Bailo. - :param schema_id: A unique schema ID + :param schema_id: A unique schema ID, defaults to None. If None, either minimal-general-v10 or minimal-data-card-v10 is used """ + if schema_id is None: + if self.kind == EntryKind.MODEL: + schema_id = MinimalSchema.MODEL + if self.kind == EntryKind.DATACARD: + schema_id = MinimalSchema.DATACARD + res = self.client.model_card_from_schema(model_id=self.id, schema_id=schema_id) - self.__unpack_card(res["card"])
+ self.__unpack_card(res["card"]) + + logger.info(f"Card for ID %s successfully created using schema ID %s.", self.id, schema_id)
@@ -161,8 +175,11 @@

Source code for bailo.helper.entry

         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}")
+ warnings.warn( + f"ID {self.id} does not have any associated cards. If needed, create a card with the .card_from_schema() method." + )
@@ -173,7 +190,9 @@

Source code for bailo.helper.entry

         :param version: Entry card version
         """
         res = self.client.get_model_card(model_id=self.id, version=version)
-        self.__unpack_card(res["modelCard"])
+ self.__unpack_card(res["modelCard"]) + + logger.info(f"Card version %s for ID %s successfully retrieved.", version, self.id)
@@ -207,6 +226,8 @@

Source code for bailo.helper.entry

         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"]
@@ -217,6 +238,8 @@ 

Source code for bailo.helper.entry

         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"]
@@ -224,7 +247,9 @@ 

Source code for bailo.helper.entry

         try:
             self._card = res["metadata"]
         except KeyError:
-            self._card = None
+ self._card = None + + logger.info(f"Card attributes for ID %s successfully unpacked.", self.id)
diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/model/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/model/index.html index 6d3d8945b..20aa1d8a4 100644 --- a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/model/index.html +++ b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/model/index.html @@ -92,9 +92,11 @@

Source code for bailo.helper.model

 import shutil
 import tempfile
 from typing import Any
+import logging
+import warnings
 
 from bailo.core.client import Client
-from bailo.core.enums import EntryKind, ModelVisibility
+from bailo.core.enums import EntryKind, ModelVisibility, MinimalSchema
 from bailo.core.exceptions import BailoException
 from bailo.core.utils import NestedDict
 from bailo.helper.entry import Entry
@@ -108,6 +110,8 @@ 

Source code for bailo.helper.model

 except ImportError:
     ml_flow = False
 
+logger = logging.getLogger(__name__)
+
 
 
[docs] @@ -158,9 +162,12 @@

Source code for bailo.helper.model

         res = client.post_model(
             name=name, kind=EntryKind.MODEL, description=description, team_id=team_id, visibility=visibility
         )
+        model_id = res["model"]["id"]
+        logger.info(f"Model successfully created on server with ID %s.", model_id)
+
         model = cls(
             client=client,
-            model_id=res["model"]["id"],
+            model_id=model_id,
             name=name,
             description=description,
             visibility=visibility,
@@ -185,6 +192,8 @@ 

Source code for bailo.helper.model

         if res["kind"] != "model":
             raise BailoException(f"ID {model_id} does not belong to a model. Did you mean to use Datacard.from_id()?")
 
+        logger.info(f"Model %s successfully retrieved from server.", model_id)
+
         model = cls(
             client=client,
             model_id=model_id,
@@ -198,6 +207,126 @@ 

Source code for bailo.helper.model

         return model
+
+[docs] + @classmethod + def search( + cls, + client: Client, + task: str | None = None, + libraries: list[str] | None = None, + filters: list[str] | None = None, + search: str = "", + ) -> list[Model]: + """Return a list of model objects from Bailo, based on search parameters. + + :param client: A client object used to interact with Bailo + :param task: Model task (e.g. image classification), defaults to None + :param libraries: Model library (e.g. TensorFlow), defaults to None + :param filters: Custom filters, defaults to None + :param search: String to be located in model cards, defaults to "" + :return: List of model objects + """ + res = client.get_models(kind=EntryKind.MODEL, task=task, libraries=libraries, filters=filters, search=search) + models = [] + + for model in res["models"]: + res_model = client.get_model(model_id=model["id"])["model"] + model_obj = cls(client=client, model_id=model["id"], name=model["name"], description=model["description"]) + model_obj._unpack(res_model) + model_obj.get_card_latest() + models.append(model_obj) + + return models
+ + +
+[docs] + @classmethod + def from_mlflow( + cls, + client: Client, + mlflow_uri: str, + team_id: str, + name: str, + schema_id: str = MinimalSchema.MODEL, + version: str | None = None, + files: bool = True, + visibility: ModelVisibility | None = None, + ) -> Model: + """Import an MLFlow Model into Bailo. + + :param client: A client object used to interact with Bailo + :param mlflow_uri: MLFlow server URI + :param team_id: A unique team ID + :param name: Name of model (on MLFlow). Same name will be used on Bailo + :param schema_id: A unique schema ID, only required when files is True, defaults to minimal-general-v10 + :param version: Specific MLFlow model version to import, defaults to None + :param files: Import files?, defaults to True + :param visibility: Visibility of model on Bailo, using ModelVisibility enum (e.g Public or Private), defaults to None + :return: A model object + """ + if not ml_flow: + raise ImportError("Optional MLFlow dependencies (needed for this method) are not installed.") + + mlflow_client = mlflow.tracking.MlflowClient(tracking_uri=mlflow_uri) + mlflow.set_tracking_uri(mlflow_uri) + filter_string = f"name = '{name}'" + + res = mlflow_client.search_model_versions(filter_string=filter_string, order_by=["version_number DESC"]) + if not len(res): + raise BailoException("No MLFlow models found. Are you sure the name/alias/version provided is correct?") + + sel_model = None + if version: + for model in res: + if model.version == version: + sel_model = model + else: + sel_model = res[0] + + if sel_model is None: + raise BailoException("No MLFlow model found. Are you sure the name/alias/version provided is correct?") + + name = sel_model.name + description = sel_model.description + " Imported from MLFlow." + bailo_res = client.post_model( + name=name, kind=EntryKind.MODEL, description=description, team_id=team_id, visibility=visibility + ) + model_id = bailo_res["model"]["id"] + logger.info(f"MLFlow model successfully imported to Bailo with ID %s.", model_id) + + model = cls( + client=client, + model_id=model_id, + name=name, + description=description, + visibility=visibility, + ) + model._unpack(bailo_res["model"]) + + if files: + model.card_from_schema(schema_id=schema_id) + release = model.create_release(version=Version.coerce(str(sel_model.version)), notes=" ") + run_id = sel_model.run_id + if run_id is None: + raise BailoException( + "MLFlow model does not have an assosciated run_id, therefore artifacts cannot be transfered." + ) + + mlflow_run = mlflow_client.get_run(run_id) + artifact_uri = mlflow_run.info.artifact_uri + if artifact_uri is None: + raise BailoException("Artifact URI could not be found, therefore artifacts cannot be transfered.") + + if len(mlflow.artifacts.list_artifacts(artifact_uri=artifact_uri)): + temp_dir = os.path.join(tempfile.gettempdir(), "mlflow_model") + mlflow_dir = os.path.join(temp_dir, f"mlflow_{run_id}") + mlflow.artifacts.download_artifacts(artifact_uri=artifact_uri, dst_path=mlflow_dir) + release.upload(mlflow_dir) + return model
+ +
[docs] def update_model_card(self, model_card: dict[str, Any] | None = None) -> None: @@ -271,6 +400,8 @@

Source code for bailo.helper.model

         for release in res["releases"]:
             releases.append(self.get_release(version=release["semver"]))
 
+        logger.info(f"Successfully retrieved all releases for model %s.", self.model_id)
+
         return releases
@@ -295,6 +426,10 @@

Source code for bailo.helper.model

         releases = self.get_releases()
         if releases == []:
             raise BailoException("This model has no releases.")
+
+        latest_release = max(releases)
+        logger.info(f"latest_release (%s) for %s retrieved successfully.", str(latest_release.version), self.model_id)
+
         return max(releases)
@@ -307,6 +442,8 @@

Source code for bailo.helper.model

         """
         res = self.client.get_all_images(model_id=self.model_id)
 
+        logger.info(f"Images for %s retreived successfully.", self.model_id)
+
         return res["images"]
@@ -342,7 +479,13 @@

Source code for bailo.helper.model

 
     @model_card_schema.setter
     def model_card_schema(self, value):
-        self._card_schema = value
+ self._card_schema = value + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({str(self)})" + + def __str__(self) -> str: + return f"{self.model_id}"
@@ -407,7 +550,7 @@

Source code for bailo.helper.model

         self.raw.append(self.run_data)
 
         if not is_mlflow:
-            print(f"Bailo tracking run {self.run}.")
+ logger.info(f"Bailo tracking run %d.", self.run)
@@ -459,53 +602,77 @@

Source code for bailo.helper.model

         :param experiment_id: MLFlow Tracking experiment ID
         :raises ImportError: Import error if MLFlow not installed
         """
-        if ml_flow:
-            client = mlflow.tracking.MlflowClient(tracking_uri=tracking_uri)
-            runs = client.search_runs(experiment_id)
-
-            for run in runs:
-                data = run.data
-                info = run.info
-                inputs = run.inputs
-
-                artifact_uri = info.artifact_uri
-                run_id = info.run_id
-                status = info.status
-                datasets = inputs.dataset_inputs
-                datasets_str = [dataset.name for dataset in datasets]
-
-                artifacts = []
-
-                # MLFlow run must be status FINISHED
-                if status != "FINISHED":
-                    continue
-
-                if len(mlflow.artifacts.list_artifacts(artifact_uri=artifact_uri)) > 0:
-                    mlflow_dir = os.path.join(self.temp_dir, f"mlflow_{run_id}")
-                    mlflow.artifacts.download_artifacts(artifact_uri=artifact_uri, dst_path=mlflow_dir)
-                    artifacts.append(mlflow_dir)
-
-                self.start_run(is_mlflow=True)
-                self.log_params(data.params)
-                self.log_metrics(data.metrics)
-                self.log_artifacts(artifacts)
-                self.log_dataset("".join(datasets_str))
-                self.run_data["run"] = info.run_id
+        if not ml_flow:
+            raise ImportError("Optional MLFlow dependencies (needed for this method) are not installed.")
+
+        client = mlflow.tracking.MlflowClient(tracking_uri=tracking_uri)
+        runs = client.search_runs(experiment_id)
+        if len(runs):
+            logger.info(
+                f"Successfully retrieved MLFlow experiment %s from tracking server. %d were found.",
+                experiment_id,
+                len(runs),
+            )
         else:
-            raise ImportError("Optional MLFlow dependencies (needed for this method) are not installed.")
+ warnings.warn( + f"MLFlow experiment {experiment_id} does not have any runs and publishing requires at least one valid run. Are you sure the ID is correct?" + ) + + for run in runs: + data = run.data + info = run.info + inputs = run.inputs + + artifact_uri = info.artifact_uri + run_id = info.run_id + status = info.status + datasets = inputs.dataset_inputs + datasets_str = [dataset.name for dataset in datasets] + + artifacts = [] + + # MLFlow run must be status FINISHED + if status != "FINISHED": + continue + + if len(mlflow.artifacts.list_artifacts(artifact_uri=artifact_uri)): + mlflow_dir = os.path.join(self.temp_dir, f"mlflow_{run_id}") + mlflow.artifacts.download_artifacts(artifact_uri=artifact_uri, dst_path=mlflow_dir) + artifacts.append(mlflow_dir) + logger.info( + f"Successfully downloaded artifacts for MLFlow experiment %s to %s.", experiment_id, mlflow_dir + ) + + self.start_run(is_mlflow=True) + self.log_params(data.params) + self.log_metrics(data.metrics) + self.log_artifacts(artifacts) + self.log_dataset("".join(datasets_str)) + self.run_data["run"] = info.run_id + + logger.info(f"Successfully imported MLFlow experiment %s.", experiment_id)
[docs] - def publish(self, mc_loc: str, run_id: str, semver: str = "0.1.0", notes: str = ""): + def publish( + self, + mc_loc: str, + semver: str = "0.1.0", + notes: str = "", + run_id: str | None = None, + select_by: str | None = None, + ): """Publishes a given experiments results to the model card. :param mc_loc: Location of metrics in the model card (e.g. performance.performanceMetrics) - :param run_id: Local experiment run ID to be selected :param semver: Semantic version of release to create (if artifacts present), defaults to 0.1.0 or next :param notes: Notes for release, defaults to "" + :param run_id: Local experiment run ID to be selected, defaults to None + :param select_by: String describing experiment to be selected (e.g. "accuracy MIN|MAX"), defaults to None ..note:: mc_loc is dependent on the model card schema being used + ..warning:: User must specify either run_id or select_by, otherwise the code will error """ mc = self.model.model_card if mc is None: @@ -513,15 +680,23 @@

Source code for bailo.helper.model

 
         mc = NestedDict(mc)
 
-        if len(self.raw) > 0:
+        if len(self.raw) == 0:
+            raise BailoException(f"This experiment has no runs to publish.")
+        if (select_by is None) and (run_id is None):
+            raise BailoException(
+                "Either select_by (e.g. 'accuracy MIN|MAX') or run_id is required to publish an experiment run."
+            )
+
+        if (select_by is not None) and (run_id is None):
+            sel_run = self.__select_run(select_by=select_by)
+
+        if run_id is not None:
             for run in self.raw:
                 if run["run"] == run_id:
                     sel_run = run
                     break
             else:
                 raise NameError(f"Run {run_id} does not exist.")
-        else:
-            raise BailoException(f"This experiment has no runs to publish.")
 
         values = []
 
@@ -536,7 +711,7 @@ 

Source code for bailo.helper.model

 
         # Creating a release and uploading artifacts (if artifacts present)
         artifacts = sel_run["artifacts"]
-        if len(artifacts) > 0:
+        if len(artifacts):
             # Create new release
             try:
                 release_latest_version = self.model.get_latest_release().version
@@ -548,12 +723,52 @@ 

Source code for bailo.helper.model

             notes = f"{notes} (Run ID: {run_id})"
             release_new = self.model.create_release(version=release_new_version, minor=True, notes=notes)
 
+            logger.info(
+                f"Uploading %d artifacts to version %s of model %s.",
+                len(artifacts),
+                str(release_new_version),
+                self.model.model_id,
+            )
+
             for artifact in artifacts:
                 release_new.upload(path=artifact)
 
             if os.path.exists(self.temp_dir) and os.path.isdir(self.temp_dir):
-                shutil.rmtree(self.temp_dir)
-
+ shutil.rmtree(self.temp_dir) + + logger.info(f"Successfully published experiment run %s to model %s.", str(run_id), self.model.model_id)
+ + + def __select_run(self, select_by: str): + # Parse target and order from select_by string + select_by_split = select_by.split(" ") + if len(select_by_split) != 2: + raise BailoException("Invalid select_by string. Expected format is 'metric_name MIN|MAX'.") + order_str = select_by_split[1].upper() + order_opt = ["MIN", "MAX"] + if order_str not in order_opt: + raise BailoException(f"Runs can only be ordered by MIN or MAX, not {order_str}.") + target_str = select_by_split[0] + + # Extract target value for each run + runs = self.raw + for run in runs: + metrics = run["metrics"] + for metric in metrics: + target_value = metric.get(target_str, None) + if target_value is not None: + run["target"] = target_value + else: + raise BailoException( + f"Target '{target_str}' could not be found in at least one experiment run, or is not an integer. Therefore ordering cannot take place." + ) + + # Sort experiment runs by target value into ascending order, and select first or last depending on order_str + ordered_runs = sorted(runs, key=lambda run: run["target"]) + if order_str == "MIN": + return ordered_runs[0] + if order_str == "MAX": + return ordered_runs[-1]
diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/release/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/release/index.html index 541c9345a..b925f1ac4 100644 --- a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/release/index.html +++ b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/release/index.html @@ -92,7 +92,9 @@

Source code for bailo.helper.release

 import fnmatch
 import shutil
 from io import BytesIO
-from typing import Any, Union
+from typing import Any
+import logging
+import warnings
 from tqdm import tqdm
 from tqdm.utils import CallbackIOWrapper
 
@@ -102,6 +104,7 @@ 

Source code for bailo.helper.release

 from semantic_version import Version
 
 BLOCK_SIZE = 1024
+logger = logging.getLogger(__name__)
 
 
 
@@ -144,8 +147,6 @@

Source code for bailo.helper.release

         if images is None:
             images = []
 
-        if isinstance(version, str):
-            version = Version(version)
         self.version = version
 
         self.model_card_version = model_card_version
@@ -194,6 +195,7 @@ 

Source code for bailo.helper.release

             minor,
             draft,
         )
+        logger.info(f"Release %s successfully created on server for model with ID %s.", str(version), model_id)
 
         return cls(
             client,
@@ -227,6 +229,8 @@ 

Source code for bailo.helper.release

         minor = res["minor"]
         draft = res["draft"]
 
+        logger.info(f"Release %s of model ID %s successfully retrieved from server.", str(version), model_id)
+
         return cls(
             client,
             model_id,
@@ -252,6 +256,7 @@ 

Source code for bailo.helper.release

         :return: A JSON response object
         """
         res = self.client.get_download_by_filename(self.model_id, str(self.version), filename)
+        logger.info(f"Downloading file %s from version %s of %s...", filename, str(self.version), self.model_id)
 
         if write:
             if path is None:
@@ -276,6 +281,12 @@ 

Source code for bailo.helper.release

                         t.update(len(data))
                         f.write(data)
 
+            logger.info(f"File written to %s", path)
+
+        logger.info(
+            f"Downloading of file %s from version %s of %s completed.", filename, str(self.version), self.model_id
+        )
+
         return res
@@ -294,6 +305,7 @@

Source code for bailo.helper.release

         if files_metadata == []:
             raise BailoException("Release has no associated files.")
         file_names = [file_metadata["name"] for file_metadata in files_metadata]
+        orig_file_names = file_names
 
         if isinstance(include, str):
             include = [include]
@@ -308,6 +320,13 @@ 

Source code for bailo.helper.release

                 file for file in file_names if not any([fnmatch.fnmatch(file, pattern) for pattern in exclude])
             ]
 
+        logger.info(
+            f"Downloading %d of %%d files for version %s of %s...",
+            len(file_names),
+            len(orig_file_names),
+            str(self.version),
+            {self.model_id},
+        )
         os.makedirs(path, exist_ok=True)
         for file in file_names:
             file_path = os.path.join(path, file)
@@ -320,15 +339,17 @@ 

Source code for bailo.helper.release

         """Upload a file to the release.
 
         :param path: The path, or name of file or directory to be uploaded
-        :param data: A BytesIO object if not loading from disk
+        :param data: A BytesIO object if not loading from disk, defaults to None
 
         :return: The unique file ID of the file uploaded
         ..note:: If path provided is a directory, it will be uploaded as a zip
         """
+        logger.info(f"Uploading file(s) to version %s of %s...", str(self.version), self.model_id)
         name = os.path.split(path)[-1]
 
         if data is None:
             if is_zip := os.path.isdir(path):
+                logger.info(f"Given path (%s) is a directory. This will be converted to a zip file for upload.", path)
                 shutil.make_archive(name, "zip", path)
                 path = f"{name}.zip"
                 name = path
@@ -358,6 +379,8 @@ 

Source code for bailo.helper.release

         self.update()
         if not isinstance(data, BytesIO):
             data.close()
+        logger.info(f"Upload of file %s to version %s of %s complete.", name, str(self.version), self.model_id)
+
         return res["file"]["id"]
@@ -370,7 +393,7 @@

Source code for bailo.helper.release

         """
         return self.client.put_release(
             self.model_id,
-            str(self.version),
+            str(self.__version_raw),
             self.notes,
             self.draft,
             self.files,
@@ -386,19 +409,44 @@ 

Source code for bailo.helper.release

         :return: JSON Response object
         """
         self.client.delete_release(self.model_id, str(self.version))
+        logger.info(f"Release %s of %s successfully deleted.", str(self.version), self.model_id)
+
         return True
+ @property + def version(self): + return self.__version_obj + + @version.setter + def version(self, value): + if ("_Release__version_obj" not in self.__dict__) and ("_Release__version_raw" not in self.__dict__): + if isinstance(value, str): + if value.startswith("v"): + value = value[1:] + version_obj = Version.coerce(value) + elif isinstance(value, Version): + version_obj = value + else: + raise TypeError("Provided version not of a supported type.") + + self.__version_obj = version_obj + self.__version_raw = value + else: + raise BailoException( + "Version attribute has already been set once. You must create a new Release object to create a new version, or use Model.create_release()." + ) + def __repr__(self) -> str: return f"{self.__class__.__name__}({str(self)})" def __str__(self) -> str: - return f"{self.model_id} v{self.version}" + return f"{self.model_id} v{self.__version_obj}" def __eq__(self, other) -> bool: if not isinstance(other, self.__class__): return NotImplemented - return self.version == other.version + return self.__version_obj == other.__version_obj def __ne__(self, other): if not isinstance(other, self.__class__): @@ -408,25 +456,25 @@

Source code for bailo.helper.release

     def __lt__(self, other):
         if not isinstance(other, self.__class__):
             return NotImplemented
-        return self.version < other.version
+        return self.__version_obj < other.__version_obj
 
     def __le__(self, other):
         if not isinstance(other, self.__class__):
             return NotImplemented
-        return self.version <= other.version
+        return self.__version_obj <= other.__version_obj
 
     def __gt__(self, other):
         if not isinstance(other, self.__class__):
             return NotImplemented
-        return self.version > other.version
+        return self.__version_obj > other.__version_obj
 
     def __ge__(self, other):
         if not isinstance(other, self.__class__):
             return NotImplemented
-        return self.version >= other.version
+        return self.__version_obj >= other.__version_obj
 
     def __hash__(self) -> int:
-        return hash((self.model_id, self.version))
+ return hash((self.model_id, self.__version_obj))
diff --git a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/schema/index.html b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/schema/index.html index 1aaa1c2d5..421f512ff 100644 --- a/backend/python-docs/_build/dirhtml/_modules/bailo/helper/schema/index.html +++ b/backend/python-docs/_build/dirhtml/_modules/bailo/helper/schema/index.html @@ -88,11 +88,14 @@

Source code for bailo.helper.schema

 from __future__ import annotations
 
-from typing import Any
+import logging
+from typing import Any, List
 
 from bailo.core.client import Client
 from bailo.core.enums import SchemaKind
 
+logger = logging.getLogger(__name__)
+
 
 
[docs] @@ -156,6 +159,7 @@

Source code for bailo.helper.schema

         res = client.post_schema(
             schema_id=schema_id, name=name, description=description, kind=kind, json_schema=json_schema
         )
+        logger.info(f"Schema successfully created on server with ID %s.", schema_id)
         schema.__unpack(res["schema"])
 
         return schema
@@ -180,11 +184,26 @@

Source code for bailo.helper.schema

             json_schema={"temp": "temp"},
         )
         res = client.get_schema(schema_id=schema_id)
+        logger.info(f"Schema %s successfully retrieved from server.", schema_id)
         schema.__unpack(res["schema"])
 
         return schema
+
+[docs] + @staticmethod + def get_all_schema_ids(client: Client, kind: SchemaKind | None = None) -> list[str]: + """Return all schema ids for a given type. + + :param client: A client object used to interact with Bailo + :param kind: Enum to define schema kind (e.g. Model or AccessRequest), defaults to None + :return: List of schema IDs + """ + all_schemas = client.get_all_schemas(kind=kind) + return [schema["id"] for schema in all_schemas["schemas"]]
+ + def __unpack(self, res) -> None: self.schema_id = res["id"] self.name = res["name"] @@ -195,7 +214,9 @@

Source code for bailo.helper.schema

         if kind == "model":
             self.kind = SchemaKind.MODEL
         if kind == "accessRequest":
-            self.kind = SchemaKind.ACCESS_REQUEST
+ self.kind = SchemaKind.ACCESS_REQUEST + + logger.info(f"Attributes for Schema ID %s successfully unpacked.", self.schema_id)
diff --git a/backend/python-docs/_build/dirhtml/_sources/notebooks/access_requests_demo.ipynb.txt b/backend/python-docs/_build/dirhtml/_sources/notebooks/access_requests_demo.ipynb.txt index 334f257fc..8ba5b485f 100644 --- a/backend/python-docs/_build/dirhtml/_sources/notebooks/access_requests_demo.ipynb.txt +++ b/backend/python-docs/_build/dirhtml/_sources/notebooks/access_requests_demo.ipynb.txt @@ -190,9 +190,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": ".venv", "language": "python", - "name": "python" + "name": "python3" }, "language_info": { "codemirror_mode": { diff --git a/backend/python-docs/_build/dirhtml/_sources/notebooks/datacards_demo.ipynb.txt b/backend/python-docs/_build/dirhtml/_sources/notebooks/datacards_demo.ipynb.txt index 7fa8bf248..d84816d45 100644 --- a/backend/python-docs/_build/dirhtml/_sources/notebooks/datacards_demo.ipynb.txt +++ b/backend/python-docs/_build/dirhtml/_sources/notebooks/datacards_demo.ipynb.txt @@ -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, diff --git a/backend/python-docs/_build/dirhtml/_sources/notebooks/experiment_tracking_demo.ipynb.txt b/backend/python-docs/_build/dirhtml/_sources/notebooks/experiment_tracking_demo.ipynb.txt index ed17d944f..d0ed12cf4 100644 --- a/backend/python-docs/_build/dirhtml/_sources/notebooks/experiment_tracking_demo.ipynb.txt +++ b/backend/python-docs/_build/dirhtml/_sources/notebooks/experiment_tracking_demo.ipynb.txt @@ -249,7 +249,19 @@ "## Publishing results to Bailo\n", "\n", "Experiment runs can be published to the model card using the `Experiment.publish()` method, **one at a time**. This is because the intended use is only to publish the most successful run.\n", - "Therefore, you must specify the **run_id** to publish, as well as specify the location of the metrics in your schema (in this case *performance.performanceMetrics* as per the schema we defined earlier)." + "Therefore, you must specify the **run_id** to publish, or specify an order so the client can select the best result. As well as this, you must specify the location of the metrics in your schema (in this case *performance.performanceMetrics* as per the schema we defined earlier).\n", + "\n", + "Examples for both scenarios can be seen below." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Publishing a specific run\n", + "\n", + "To publish a specific run, you must pass the `run_id` into the method. In this example, use one of the IDs we created in the previous steps." ] }, { @@ -266,7 +278,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "If successful, our metrics should now be under the **Performance** tab of your model card on the UI! Additionally, our artifact will have been published as a new release." + "### Publishing the best run\n", + "\n", + "To publish the best run, you must define what the best is for your use case. This can be done using the `select_by` parameter with a string e.g. `accuracy MIN|MAX`. Depending on the requirements, `accuracy` could be any metric you have defined in your experiment.\n", + "\n", + "In the below example, we will use `accuracy MAX` to publish the experiment run with the highest accuracy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "experiment_mlflow.publish(mc_loc=\"performance.performanceMetrics\", select_by=\"accuracy MAX\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If successful, our metrics should now be under the **Performance** tab of your model card on the UI! Additionally, our artifact will have been published as a new release (*this will have been done twice if you ran both the above steps*)." ] } ], diff --git a/backend/python-docs/_build/dirhtml/_sources/notebooks/models_and_releases_demo_pytorch.ipynb.txt b/backend/python-docs/_build/dirhtml/_sources/notebooks/models_and_releases_demo_pytorch.ipynb.txt index 8eacdfee8..040b49f50 100644 --- a/backend/python-docs/_build/dirhtml/_sources/notebooks/models_and_releases_demo_pytorch.ipynb.txt +++ b/backend/python-docs/_build/dirhtml/_sources/notebooks/models_and_releases_demo_pytorch.ipynb.txt @@ -79,7 +79,7 @@ "\n", "# Instantiating the Bailo client\n", "\n", - "client = Client(\"http://127.0.0.1:8080\") # <- INSERT BAILO URL (if not hosting locally)\n" + "client = Client(\"http://127.0.0.1:8080\") # <- INSERT BAILO URL (if not hosting locally)" ] }, { @@ -336,7 +336,7 @@ "metadata": {}, "outputs": [], "source": [ - "weights = torch.load(\"bailo_resnet50_weights.pth\")\n", + "weights = torch.load(\"downloads/resnet50_weights.pth\")\n", "torch_model = resnet50()\n", "torch_model.load_state_dict(weights)" ] @@ -348,6 +348,47 @@ "source": [ "If the message \"**All keys matched successfully**\" is displayed, we have successfully initated our model." ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Searching for models" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to fetching specific models, you can also use the `Model.search()` method to return a list of `Model()` objects that match your parameters. These parameters can be:\n", + "\n", + "* Task of the model (e.g. image classification).\n", + "* Libraries used for the model (e.g. PyTorch).\n", + "* Model card search (string to be found in model cards).\n", + "\n", + "In the below example, we'll just search for all models with no filters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "models = Model.search(client=client)\n", + "\n", + "print(models)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We should now have a list of `Model()` objects." + ] } ], "metadata": { diff --git a/backend/python-docs/_build/dirhtml/bailo.core/index.html b/backend/python-docs/_build/dirhtml/bailo.core/index.html index 5de248b56..917e51896 100644 --- a/backend/python-docs/_build/dirhtml/bailo.core/index.html +++ b/backend/python-docs/_build/dirhtml/bailo.core/index.html @@ -54,6 +54,7 @@ @@ -182,7 +186,7 @@
-classmethod create(client: Client, model_id: str, schema_id: str, metadata: Any) AccessRequest[source]
+classmethod create(client: Client, model_id: str, metadata: Any, schema_id: str = MinimalSchema.ACCESS_REQUEST) AccessRequest[source]

Make an access request for the model.

Posts an access request to Bailo to be reviewed

@@ -191,7 +195,7 @@
  • client – A client object used to interact with Bailo

  • name – The name of the access request

  • model_id – A unique model ID within Bailo

  • -
  • schema_id – A unique schema ID

  • +
  • schema_id – A unique schema ID, defaults to minimal-access-request-general-v10

  • Returns:
    @@ -322,11 +326,11 @@

    Bases: object

    -card_from_schema(schema_id: str) None[source]
    +card_from_schema(schema_id: str | None = None) None[source]

    Create a card using a schema on Bailo.

    Parameters:
    -

    schema_id – A unique schema ID

    +

    schema_id – A unique schema ID, defaults to None. If None, either minimal-general-v10 or minimal-data-card-v10 is used

    @@ -490,19 +494,21 @@
    -publish(mc_loc: str, run_id: str, semver: str = '0.1.0', notes: str = '')[source]
    +publish(mc_loc: str, semver: str = '0.1.0', notes: str = '', run_id: str | None = None, select_by: str | None = None)[source]

    Publishes a given experiments results to the model card.

    Parameters:
    • mc_loc – Location of metrics in the model card (e.g. performance.performanceMetrics)

    • -
    • run_id – Local experiment run ID to be selected

    • semver – Semantic version of release to create (if artifacts present), defaults to 0.1.0 or next

    • notes – Notes for release, defaults to “”

    • +
    • run_id – Local experiment run ID to be selected, defaults to None

    • +
    • select_by – String describing experiment to be selected (e.g. “accuracy MIN|MAX”), defaults to None

    -

    ..note:: mc_loc is dependent on the model card schema being used

    +

    ..note:: mc_loc is dependent on the model card schema being used +..warning:: User must specify either run_id or select_by, otherwise the code will error

    @@ -603,6 +609,29 @@
    +
    +
    +classmethod from_mlflow(client: Client, mlflow_uri: str, team_id: str, name: str, schema_id: str = MinimalSchema.MODEL, version: str | None = None, files: bool = True, visibility: ModelVisibility | None = None) Model[source]
    +

    Import an MLFlow Model into Bailo.

    +
    +
    Parameters:
    +
      +
    • client – A client object used to interact with Bailo

    • +
    • mlflow_uri – MLFlow server URI

    • +
    • team_id – A unique team ID

    • +
    • name – Name of model (on MLFlow). Same name will be used on Bailo

    • +
    • schema_id – A unique schema ID, only required when files is True, defaults to minimal-general-v10

    • +
    • version – Specific MLFlow model version to import, defaults to None

    • +
    • files – Import files?, defaults to True

    • +
    • visibility – Visibility of model on Bailo, using ModelVisibility enum (e.g Public or Private), defaults to None

    • +
    +
    +
    Returns:
    +

    A model object

    +
    +
    +
    +
    get_image()[source]
    @@ -676,6 +705,26 @@ property model_card_version
    +
    +
    +classmethod search(client: Client, task: str | None = None, libraries: list[str] | None = None, filters: list[str] | None = None, search: str = '') list[Model][source]
    +

    Return a list of model objects from Bailo, based on search parameters.

    +
    +
    Parameters:
    +
      +
    • client – A client object used to interact with Bailo

    • +
    • task – Model task (e.g. image classification), defaults to None

    • +
    • libraries – Model library (e.g. TensorFlow), defaults to None

    • +
    • filters – Custom filters, defaults to None

    • +
    • search – String to be located in model cards, defaults to “”

    • +
    +
    +
    Returns:
    +

    List of model objects

    +
    +
    +
    +
    update_model_card(model_card: dict[str, Any] | None = None) None[source]
    @@ -813,7 +862,7 @@
    Parameters:
    • path – The path, or name of file or directory to be uploaded

    • -
    • data – A BytesIO object if not loading from disk

    • +
    • data – A BytesIO object if not loading from disk, defaults to None

    Returns:
    @@ -823,6 +872,11 @@

    ..note:: If path provided is a directory, it will be uploaded as a zip

    +
    +
    +property version
    +
    +
    @@ -879,6 +933,23 @@
    +
    +
    +static get_all_schema_ids(client: Client, kind: SchemaKind | None = None) list[str][source]
    +

    Return all schema ids for a given type.

    +
    +
    Parameters:
    +
      +
    • client – A client object used to interact with Bailo

    • +
    • kind – Enum to define schema kind (e.g. Model or AccessRequest), defaults to None

    • +
    +
    +
    Returns:
    +

    List of schema IDs

    +
    +
    +
    + diff --git a/backend/python-docs/_build/dirhtml/genindex/index.html b/backend/python-docs/_build/dirhtml/genindex/index.html index c85cacef6..a9fdd35d3 100644 --- a/backend/python-docs/_build/dirhtml/genindex/index.html +++ b/backend/python-docs/_build/dirhtml/genindex/index.html @@ -104,14 +104,17 @@

    Index

    | S | T | U + | V

    _

  • Importing existing experiments from MLFlow into Bailo
  • -
  • Publishing results to Bailo
  • +
  • Publishing results to Bailo +
  • Managing Models & Releases (ResNet-50 Example with PyTorch)
  • @@ -282,7 +286,11 @@

    Importing existing experiments from MLFlow into Bailo

    Publishing results to Bailo

    -

    Experiment runs can be published to the model card using the Experiment.publish() method, one at a time. This is because the intended use is only to publish the most successful run. Therefore, you must specify the run_id to publish, as well as specify the location of the metrics in your schema (in this case performance.performanceMetrics as per the schema we defined earlier).

    +

    Experiment runs can be published to the model card using the Experiment.publish() method, one at a time. This is because the intended use is only to publish the most successful run. Therefore, you must specify the run_id to publish, or specify an order so the client can select the best result. As well as this, you must specify the location of the metrics in your schema (in this case performance.performanceMetrics as per the schema we defined earlier).

    +

    Examples for both scenarios can be seen below.

    +
    +

    Publishing a specific run

    +

    To publish a specific run, you must pass the run_id into the method. In this example, use one of the IDs we created in the previous steps.

    [ ]:
     
    @@ -291,7 +299,21 @@

    Publishing results to Bailo +

    Publishing the best run

    +

    To publish the best run, you must define what the best is for your use case. This can be done using the select_by parameter with a string e.g. accuracy MIN|MAX. Depending on the requirements, accuracy could be any metric you have defined in your experiment.

    +

    In the below example, we will use accuracy MAX to publish the experiment run with the highest accuracy.

    +
    +
    [ ]:
    +
    +
    +
    experiment_mlflow.publish(mc_loc="performance.performanceMetrics", select_by="accuracy MAX")
    +
    +
    +
    +

    If successful, our metrics should now be under the Performance tab of your model card on the UI! Additionally, our artifact will have been published as a new release (this will have been done twice if you ran both the above steps).

    +

    diff --git a/backend/python-docs/_build/dirhtml/notebooks/models_and_releases_demo_pytorch.ipynb b/backend/python-docs/_build/dirhtml/notebooks/models_and_releases_demo_pytorch.ipynb index 8eacdfee8..040b49f50 100644 --- a/backend/python-docs/_build/dirhtml/notebooks/models_and_releases_demo_pytorch.ipynb +++ b/backend/python-docs/_build/dirhtml/notebooks/models_and_releases_demo_pytorch.ipynb @@ -79,7 +79,7 @@ "\n", "# Instantiating the Bailo client\n", "\n", - "client = Client(\"http://127.0.0.1:8080\") # <- INSERT BAILO URL (if not hosting locally)\n" + "client = Client(\"http://127.0.0.1:8080\") # <- INSERT BAILO URL (if not hosting locally)" ] }, { @@ -336,7 +336,7 @@ "metadata": {}, "outputs": [], "source": [ - "weights = torch.load(\"bailo_resnet50_weights.pth\")\n", + "weights = torch.load(\"downloads/resnet50_weights.pth\")\n", "torch_model = resnet50()\n", "torch_model.load_state_dict(weights)" ] @@ -348,6 +348,47 @@ "source": [ "If the message \"**All keys matched successfully**\" is displayed, we have successfully initated our model." ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Searching for models" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to fetching specific models, you can also use the `Model.search()` method to return a list of `Model()` objects that match your parameters. These parameters can be:\n", + "\n", + "* Task of the model (e.g. image classification).\n", + "* Libraries used for the model (e.g. PyTorch).\n", + "* Model card search (string to be found in model cards).\n", + "\n", + "In the below example, we'll just search for all models with no filters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "models = Model.search(client=client)\n", + "\n", + "print(models)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We should now have a list of `Model()` objects." + ] } ], "metadata": { diff --git a/backend/python-docs/_build/dirhtml/notebooks/models_and_releases_demo_pytorch/index.html b/backend/python-docs/_build/dirhtml/notebooks/models_and_releases_demo_pytorch/index.html index 3c48b5bff..a59baf506 100644 --- a/backend/python-docs/_build/dirhtml/notebooks/models_and_releases_demo_pytorch/index.html +++ b/backend/python-docs/_build/dirhtml/notebooks/models_and_releases_demo_pytorch/index.html @@ -85,6 +85,7 @@
  • Loading the model using PyTorch
  • +
  • Searching for models
  • Managing Schemas
  • @@ -166,7 +167,7 @@

    Introduction# Instantiating the Bailo client client = Client("http://127.0.0.1:8080") # <- INSERT BAILO URL (if not hosting locally) -
    + @@ -325,7 +326,7 @@

    Loading the model using PyTorch
    [ ]:
     
    -
    weights = torch.load("bailo_resnet50_weights.pth")
    +
    weights = torch.load("downloads/resnet50_weights.pth")
     torch_model = resnet50()
     torch_model.load_state_dict(weights)
     
    @@ -334,6 +335,27 @@

    Loading the model using PyTorch +

    Searching for models

    +

    In addition to fetching specific models, you can also use the Model.search() method to return a list of Model() objects that match your parameters. These parameters can be:

    +
      +
    • Task of the model (e.g. image classification).

    • +
    • Libraries used for the model (e.g. PyTorch).

    • +
    • Model card search (string to be found in model cards).

    • +
    +

    In the below example, we’ll just search for all models with no filters.

    +
    +
    [ ]:
    +
    +
    +
    models = Model.search(client=client)
    +
    +print(models)
    +
    +
    +
    +

    We should now have a list of Model() objects.

    + diff --git a/backend/python-docs/_build/dirhtml/objects.inv b/backend/python-docs/_build/dirhtml/objects.inv index 489cb22cb2c3435262291257702d2d587372a402..0ec025491f9f9deb1466034b0add90d3e800c710 100644 GIT binary patch delta 12819 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 delta 12718 zcmV;fF;UK!X47Plh=1#j-8how|9T2edAG|3QpcCB?!ne#ez@#(w=uTMlXi7sfdO)q z=P)zX){#!@;`Hgk0P`CAdix~9xR4?xQ6eSHVlZ9Kqlk|Yyat28;7yw4r8u2`I+lkv zm*SatME^?uhe*D=fv>xLS;<{`CyT}*>^?r7;@Q2_oclbjYk%?FVf1tC4lwk2=mvwzz$-lL-j+D6vb(`gK6+or_lhz9{R7crFnITTS0w~X~v!m)A zD>1lcR-)AVdwEP(f;2Kcu7Eg{4@F+4hwGa&c9z#_dS3C?iD(zAu98g?AQCW zI;_R0%Jq6&x3#P`L0ZATdM2pk*GxXFkbuU@a();l%YV7C4OWb_u1j6tR^@S(Hn@sz zGPM%YiqS#<%c~Za^ldZ&pf!pB|Ef;T2++${0Icd40I;Gh+VwLZV63XeIy;_ndEK61 z5ebEmMa$zd++IVT-DS~K=YP(ML!iah0Jm)Do? zqWRxLLx24xtFxOd&zf_T_&wg;$E&x0dHMNrtqi-5zyAF0?W<^*tCB2*VEKW8s_pvI z<%hSwTwPyXe){;!hfi;Res_8O%bPcEUtL};5`$4cU%vYDhqtd@zEi+|d3*WWQnX)w z`>=rZ6HWoqow8%wy?piR^3x|J{J;Eq`RVft0e|8<=eNB)HCb6i4@bke`x$<{)PDnx z`50RG?n>4t^F73o8JyQE zunZ23ob0d}UVA!3YOCl|vyjC#pJv^?wlD(QY{0vqp@tani&>UWRjH`dq`wBpvNX2A z`+q8{ng`k%zy%#=2tvK(+NrfrGzly7f=+{cw5~^V7mI5busevvX{55IB0Har1Unx@ z1CUYEJProTW8F!X0{J$=!2pxn=^&K&$*9|z#C0m<+g*NB|IUu1j>YLBE!G9|&;SBE z)iJ-#%ZF7sd3kr8R!w%B?wfiw5)AWNHh-&e6mymB*UNKCt8qU;ILxWN$+OYpqHv75 zQB{0hwM9J2d)-~5`WkXA?q)XkwRC#?3LyVxGzewEYGkv+bc5dJ)d2Mx1e(3q*2T0N zFcxC5LavJ<+|(GySY!rypcYv`HWr&LlTH{fkli$KiwtwBO_M6~eg^B`;*{>cs9C+w`w0I`;Ln6fyl`W*p(WU7NUCJ=P zXZ+{D()0+8EL5{iehn1?!Wd%92Y(*_r_hoq2qLy@;+pyxTz*-{tBy<)-+~K=AgJiV zfobAfc;O2aZ~c0=0cxMVWU(X6#BX`OgcsW_$?@fPyz?Xx5=9UGer(wsL4+)Evw#z) zHu*I|gxKkz7xFgqJw}kYdBF{zoBkXlMY~Lhc2b6rk=j78SnOD};`t`N#eWpOWWT znC7qoj^zxIz>VPaeF!eo6VDkfi3cZ+JX&fD-&-sza)%H_%cZ>>i$&7_fpp;lj)c3$ z3poN3LAyrSdJ}2u7;)=Jd4Idm-G!od0D*Mz0vhk;auE$gFlD@$I`DY8lo}zFFkVKA zwp=bD@rRMcNjDlYy-d(isA!Ib;xC-!hZy0cagtIP_%aEJcb+6pB09)jCK2(@lPr*k zP779uMF4?xO9Z3?_cam{LMY)98Lh~GHG*0&QPc}WUL|OVc#%RaH-FD;?hv9_x#;%6 zQn`pbgeXofJ|I~p7BdIX#0iBV(=;ajdHs%Y?E30_nm9^xW%+7t{k3Ngpow z=p~YPu}5K|sAEN5x&qtWAw;oqEgUr#a{x_*P$M^M7DzXO5`q+E+26 zU|trK;A?kTE?k!WHM=>2XjyirD*KuS9;;1X-wP#NAR|O0?|;{bNH+rm>E;E5?Q(=T zc*Ah?*RZ14*sf)fm1?g}cgwOHH93^Gx7l7+k+RHRUR=f&rA;IE_eHi(b6(hht87m;pYPJEj$oD7Y~iQT%xIq@x~@ZADie(qvuIBArmu@nB_zUeH*q&VFz zQ2e#K^%*3Q_kSL02vMM1JcG!^q7ARN2GVH(b%gJDN8;#K=dXT1X@~G=>J}&cInil# zByITp*(fQqD_6P~VM)BXHVDeYVNz7G-Q?m|v_ z<^h7T2GkT+uTYpfWtrkO7lMF>%} zY<7-{#RA$O!IaUWx@j;L3+uu}&@K{KXWLjMt_BIFTqLSa=&?#v4H8VbNL0=lvPx3M z2qlb`Qzs=^ETjeqqKX!;%XhL^zz!miE=)+TLw|Has`pkj!|+2yxyvSNCzs32_jqBh z7cXhPEHUAv3#6Sm1P>L}Jqe$sixDz*k2#j#W{x06o-XOl5{WwQd6Gp^)$7En1LUe> z1?wf~St?);CW1Cr;I)zliMUR-daZDEkaSUPJss{dE8HO1XOd=_V6lFU>9k7Wqzk2u zb$<)aq;86!jS+a5*lCHpLzHmRIcasSpV)!j&mA@OF;a%fi|`@B^zXvYP{oQDX;*pj zTm{g?3Kn_v=SiOxKoc#PPOG(8Gz}0$wNyOJ*tJ$f1PP{$71c=!wp3IHB$zT*)JP|q zCv8~(O}t>M`l1s)I!QAp7$+TzTzK6SX@CAtQKiRDYNPqqW+~!CirwFg=Wv@R8Ig+9 z(@iCZpO7kmdpyD>D-QD8FgQp2Ci8uHl%gpG#vT1oi;w5#UX5N(T5%}%E$neqi1qmg z3y71&osc>iONuc{fu*=**r2w8Jv8T2wA@A6$eXhKQa|lw47fhXW4X&t=i0MUb35t>sS0)8PNLi1t-zxSbO$zyt5M?sj2WBLB^lB1He-)`vUj=;?<~B`` zu(&v53B@W&U;AaERb{}EU+1}WYp`}?#|JN2X~*H+W} z06?MEGuXoh>)~6BxvR7y1r57RWcs579#L8Tqk#N5Sk8~5$KE_vwz};Omcl0 zgQmC9(#*_YzJ``*W&_iQmUOFAd1~{nN@E-6qldlw9a|u{^4+OOe#`2{uAES@u4Z7| zsYrhh7jwZp)E9As8K^rRxo#?DhAO6jxyZ-$R9KM*pZSY;$eMe$D1Rs3zk7ox=Aj}y z+Lr|m1f^+5nN)32M@#qUm46?r`y{N>CHNF4Yat0Al%AedC&hGNcv3aLS~VIYTsLbU z+T-z@Q1C*pCKgEB$E7Cj<63J1l5tPy)%G%dU={M6EJmu(gX*nh_Gx0UpjJib&sO(H zewT~|t%Qi(4YuU71N<`sa}{qtD6`|Ktau#p#Mp7v3CuXUd#SasTz@(c-UbxIy$y>Y zeGFGOD_dLwxOC?OuIPajvbs;`6td3GNN}p;DXpl(?%TRi)j*z& zQ=@{&1pBZQnb2f0`cUKt6kN%=%^TcJE$lQON5R;mVZI6eCKhx6HBS}BE-*t7M;_Uf zGcK19Ev}}^_<5uZW`7}b#Ef_x=wJs>4G@divri{j=UO&6{@Rls*vq@wrw)rpubGzk zlQO>b5dA#TohU=qwX)L9X)HotEA7f^e?M)#%yCv!Tx9}PdglJy7KB!76O zrqvV@1yButJbwn>C-GwT7c$i`3oIZ({@LBxtUCSW&1ldSFn_vj>olb}rm@{yyo#d- zjSIEWSeD=>c3_2!YLjU8RGI^4z_HY8%S4|m!r6&xN?`&NV4l@!+SVy*ZQfGu4^z9O zNF9CXj(Q!DYCq~~{Ty;0O1%lc>$PQp zDrSx$dbK4mlg;C9osqPVk#)fUPnN4`yh`tNp;xBRZtc0W3)QRV|L2vrv!lBv(fxm; zHvc$Vgl_%Ls_xofkF&M?!1jr)pDwP(&}@I$is``Py?LY7Fk?4advq$IOmjOK~=m1ZVTJ~ zO`55)p>J|Jy5x}IJdsxCq%4$mR#s{kCo82_A$@hQ4fsm|I2a-!@Noga5gG>viO!kV z;rwr*fCK;uh@=9bovV2z@6_(H0xz1fc%gb!T{ruCJt(0fp~2|v;;XX2(wkg0RF+8e zynpSXRh!bM`&RHT1tWOmIyHO*TL zwNeu!ycIgG(2_0Q`!FWxb8uZ{B{me7);wRz4(p6QO1$Ys}b-k@e41NkgZ7@<4}d{vN#*`bz*3dMl%* zyl#}*tK3dpb}ODj5*mq)^_pIPMt|wBbCriPikINy(s&(r~yIV~XE z7ep$wS~3`U!8NcDenfv%Xj*$r`~p;H5M{L**hB3fviv~NYS>%!VKrJ+HBs3vH1?9g zZ4g(_I3UtU^Ke&X1CDvf;2|Cy_m1#InxAVuTGT|5=QnC@Q!{0`{{qFSircH|Ru$dW zXi_9~dqUcqlH7W*c)oxo)1%dvCA=h)ffE^j0#<9c9@L6of31_RS>2|2Qa9}(E0c5C zqHt+mm&qMi3t*bzbWrgql*ye>@imZWO(<^hnAioeKiP@@Q?{rg00;m;#~1<7Xuc3~ zcem@S*W9x9mbiiW6R?EFQg!v#U4g4RycWPKJ&q+bW~dihwze8jIS88F z70UiRz=%uRyn)U+e4NeH!DjF;8Hu-JIDipJ0FrIW0}|8%Bkja%f`X1uFS%Lj>*|9- z(2dcYbDu8bwBtWJUF{}4nEeRX#KV1mrYeE0tu%i~&oyXY$y*%p-7Z)42j2RQOSKX9 z&*{NzbhwHUM%!@&1J%kf7oyuctA3W!hPtP=m47$!Wa91g7$^Sz=hRBBdm+p}zjw=$ zXbvf*dNz+XlC;T_%x-Z!@@-gvszt&Y*j3sR(`MED-pZ+jHp`o=AFgRM&|md`Kb#7L z`B!GJp3@9`R3j#XQ={ylMqPHB$*Oj{4tY@2uHw`-IGo3e-2xcqcEX_9U1JCf!|jjM zs~=xHf$a*sa|}3reN{!aRnbXwDjR@P3zH6KQez$xYk%)!qmn zv?r)eaRX(ds}M?bP-;kWuOX;^3)Sw<)W5%%U~N3y%R+5;pm!$aDg9e3b=g_X8mMLg zD%w4n6E?G#@>IZP@Ps5Z5*Vn2#F~NqsgaOM7$n?`3IpY+U*@Ws4>He=S%cG}Y7b>d zTPxK82HFwqN|~w|wZu+bJM%nB?x}zc3wY&X3BUqd-C7I{mH;e)SU=Q%g0KXwRecxNCJ@rAR#S%CZxXJaE;$MCvV#V9jYuE4GrqN zG*%Mq?a=%XdE`}i4d^R><~M#$!%u3^C}aMe_zgOs27q{|p@QF3nKkrrxI&N-)P(3` zUAV`cEfRwYH_e{7aC99Qr5guc^T<8HuUJ7oluNcz`sgMA(3E8+&lv@Zh#`!u)yHNZTlL;(uG6+y?p;lucJR!MZOmVWbKeY)nx!jte@{drWBJ z>LZ{DK%1@y(=PvQ^{}FZVLh1UUsn%`yOMhxWqRB>+h_KF&O~m?SEIf*0A`pw+i`aE z1a8C+S&i-i96k-6c->}|T2aVFC1Ix`3nZyea3+U?<*`aG;A&7b3eI(;wpkWnDwG0CzH|2$ACnFxnLLOh0s8-mt~;tvI+I|?C`iIN9dU157V+gh$P{E|I=@- zUu9b81tyzpfCOIMqLNMO@x)*L^B6`#ka!hf@fa6Hn0(f~fQU8xaCoRs-m;4r+sLF4B zimnH~)FDEI0rm=xV4|e6C>q(~v4XKbKDiL@-ax~@x_b9!*VCAfILPq~xl&GzFA~B_ zZGAwOv;N?eg?1Rl&Z!pGM+v8sOe-4QCB#sFIOldPr1#(j1;Q|V9cdeAwCyMy56<8C zkOEO?#sHN5$)Lg!-*-!$g8IJKtH2)7lNOHN!xVw)LAYjG3*e+k4n)GgwP*6Y zTdO{XRy4{Y9bDd9qqT#&L|NL56F^Tzn8wJNtiuU#RY~&l?v9;;M1ua5QjJIQp3+?y zpNi{H-_XoRerX+-fB=F4^yEnZJE0JN*cVF(|8uA%9-+V$fQ+^l)~~P^xm8f+6AM;P z>9+{4Bf7wg2N_)={rCT{zrcnD*!5S#?siXh%qIAp1fC(9N*NQ{ORm2N^M!?Rio27A ztZ37&mvlJ6R9mWSpP822tEp8H6&y!ZsM+gpEu5~@9EEd8%CFMnyWX}4jb>SY5O7M$ zXxwvzg9a`FgC=zBAD}rkG3AZW+jm|^Jd;2i#I(mk@AozN6Svv&@+Qsg0OGE|XU~50 zh&RJT-|e_#7VEK+OA+)$D9g|=1Z{6bxKlPm|C0g=40F&x0qzw%PvZ1>90SlrpUbLJ zvxDyIm4sJ;N(u!~{qig9Q+*qM2^^yPEcZostfLD~8y0Z~+?`xFfOI``W23C!9Aznlg%vF^8_`MoOKNYm`eHG#C(@ z=aT%%UR5_MU>XY|pHt_5m>g?C+gKQ|1X$>@cIyCk`f3Ia2siZ5j{n@NX(eh-=cyb` zq^zBLaM0=7ZJrWm`Iv;Rh&d$s;+!i<-5uUiXnIllF1LATv${LCrI_>&W$)(Mgd3rj zl3WNF{?9H1^7qXXcKjKEeyI{o5n@8xjskW=h+&;fG_ixV4Da|+G5bJd|6 zt?7Y6UzB}L#x6R4acVO#^d1QERdFn*Y6^}n_lKHn2mg*Q%XUa?Olu?_s(O2+_FN|D zR9rFCAjm|^M-l&gi5HAq4(RF!&%1}ItjFp5g8-d*4R|o6$KI&FDuPGqVdqMsneQkE%4#K5-U#@~LSM@+cY*v)%{kd&0aBQpb2D9G3-SPxZXC zj?-}#&8HVL>Oe7}8PzUVaf-B#(MA3DBr7}wGSkRtr2kjCdbz;C?yU$%ihNm%?l49ErEzlQpmwTx-v>4&SzQTpMbD zYM?Hem;quZfnRYg7Mvx)afN++f%h7+x+Z4}A_k6@sJ#N+Ra~!6bf42)!%o3kKGVH*yk#!{iLUCFC;EL%cgUoZH0d2V7?nW^MxQp( zIT=NNu$y)*sMZwt1@NQGQt^ZR=wy)>A=N-c+j(c0 zs`eW`;MT8!)#zG(1`?0cdSG;N$Tm>Xr6zlS9(V#B1)wg*wEtV1<`4^Za7(8Kf)R;+ zcDhPrjZ?KlrTgKN%C802x*HsKf}^H~(T<*c#_8q&jWecq=T6nKa9A9UIDO~bc)-*^ z#QP-Ow`tAS!)x6;Pp(#0Bf-el)W&9410J1=ki>~Uj;Y_dA#3CIA28gn$6guX?R{fZM%Z}|a zDO$9UFw2WB9wQF)(3)!5SdjNbFNmIhGQwz4F-}2`!lz@cHBwq<*FkZ5aDe-?diKAb zy$F_i4rfI0&K3m8_0W2(c*GU(JeiUGrYv(w?oJa*2i+ett#m$5mf`syLv@M99qPsq zPB0$~DNNncc~G^k&;K~9Yo+!F_hVgRA`eeI%!nq)G2XW@CC!ZB`}-8O@34h`EDLiN zY$AzX9K=xIjv8W3^rf+3KD=Q$7_H3{C@u1V0uC96Vo|g>O{+*VCrqgp&w6!(&%ulc ziX6)uoUe{@uAH^<2ciwt;A^VHIHAq7GRnL)Q*nPzdmgI8G{{hNrXQabpU=${_=3!y zYiGRBAA=_mtgfT&>OE-xCr==o6CDO7&A6 zkBycdBU$k&7lNUD>esfF)5VdT=QZ{`=l2 z&%S}H38BHwBH2r>>?%0e#SN$|4jh5c)R5;gD{4r?gSmD*T5W)gKeGzpx?vEo+2HgT zBW?hMB5A%y^6$lCz!4TsPiK8~uE~y4M<{TR&+!P(a~uWWUCi|FkTSYuS6p`=!=w3j z_~w2dK#9j33BeIXh=pB$mK>Ow{$PPw*FKyoIO`nH$1}TOj%S_!jjDTGwRt{6veP8H z_vb4nc?Bd+V_-kP0ADpFV(>ro3hES)hZzI?%UVtcpGTu$&*7`scpadEeni~}f@tu1 zKw0Zu=s@O~P$Y-K8+PPmtud)}b)=b_32wfeS%eREVjGixS4XCQrB1rI7&+~9ZVLtN zLCi?1siQ@u*=PfS$APBBrs1(x_?04u3mPq6iAQEDx@!+%Mo1=(meUw$i{_rfB)?1KTB1JN(nK+UL445?bdEizKx9XC$}ST z2*89RZ;0Jb3p}TQJH%ztWJN0v6E4n;us?MBdxW91I|qC}oM8mP!2JM%!IT9WX6O{< z)Q={^^}Wnb6wxFrJQ{&m7ra_=kZEpS*;ZRtWu$kzcVA|_?cfQ?%AO5S6f)I8(ajEq zB5NC=tb}@hZniwg)t43KWkS4?p+tq;w+Gl&$wSt_2&7=0aTTK=;LbQvqwIKzLn(yR zu=N6Jp{d=L@^voUPZR@UIueuLAgh6w(IJAr@%W4W?g6T8W>(N{2X3`dzB@aaZZ7$W z#}X2#*N|P6w#R%ohm))ye8Oy30PbV6f_7Svo|Mvm=~-A8g27-WKrmszs1s?hVJ+16 zkO7~Tgt|*90!Ox#LGcz&%lA^hc%e%ADmg_3B#yr?A110`3-n(=fBcsQ>avv(km!K; zZH=9H2S}U*19C+uen)q@OW}AQ>Uj5qNA-=s`I?5~*Ql2`Hf+t|Z6=R>L7(t{osM$K z_Fpi6{b`<)Tk4QD^pbp@Vh(-CY+7ZtH!o)lz(=GNhE@PAy62EqShTK?6^sbac+?;H zzdc3@2d3zRe$2BEZ<0qx1yiI#KN{LC{e0Ja(d(wCFoy*H+VNkHpY*`!8F@@TTf$7Z zhYfcN&l#xBhnGvvH9hmCq{-;HW(b&@3KL&{jmn9lDU)p}7y#@{M4+oH=X!_FhS>;X zVdMHPNz@QMSulYy@SNHP49)KWMbZk;HSrb ztC&rL@MC

    D&ppT;*Bh5REy!^c z4^rOt!rRK*NYTpo(kyiX8h83)&F7&*)b6?UEyWG~jLyz>0XO~hB$=5VbgD+@sg^QW z@um19+B@43bSu!CXJ(4i2_c=AV4Reep-=yg(9JyC%eQk%%z>vbG4jil>5blFW(D4I zsuS7lljrLHiWe_lB%Z+Um5`c$``^IK*HyMKs`f^Ku#o=3T7rcJ$H@B zBnIiC>Qc20T@HZN5g%@U;zLEwNr=ye!Az?kQ_C>%W%pzZzxeEteM5W&B{USj48>=j z21;MX*RQo@n2NJ|mIknP;;lRI@QDMuAKQTW$U9!Df z{GbdP!Vs5$!7DCf?6miuL2Ol(u{SO&d{F=I9?CST3ehycBVcy{t2>$1^lwLjcllZL zlf|C22;0Gb1|-2qy%n@J6$5LF9ckX>e=#p2zx1mQc}OVGNPo>mw{4#5yufAEz3X9O zk^&Tt19Vk{geJtRrZwQzNr=m;dly9W?k1J08#oPWi!Vj_Q0U}WC1=y=rdM8+;9i3F zb+e7I2dW~BU>KcdtK>XA2xBjKcn6~Qy4gT7IFL`$8?`4GbUYl8xb=7_C|C$>U*jYW zQ+-7N1N{L@Ab-}NZ{x_v-3?&rboU0!Uk7c0s}pCt?$RfB!>hrk#VEC5@--{-iMWA{ zuwBgwMkn0v(ldACmSHeul`t?9{ry2|A?P|gnC2`kze^)e6LP=@&P8xl4W8Z-frJ zeFk#l>L6DzZi8tAU?vv`7t`;0^s=J%RYxK4EL`%*ccT3**l%jTUh}LljiPW&#ojXQ z!Xc_%UnI4QHIJ57!!ZXmnJ9!Q+<+fP3B}qANehz_-B++e>`n5TV_MC{+?NE z%L0C_t;@>>3k@2;675NRB+ay!6|{dwDa$Re{(encoNPtf&q}KG4}YX=iI|&!JnT8V zpWLYSsJ(ix!PJ&38>7|+TUhLrx?b^4>PJ37 zSY%9SDMTQ*=v=JYe*$ld`*hu`08Ye>3NhGI4aP4Gc3`-mSzv;|1cUV|p-OJ6Ocn>V zRKlrDZ99J5s|Eb5&$NGK6{5q8heWmQMRu75GLL&$v{TofL#@p6{BEgNg)nCA__Zfk zE9tzZa|F{bfsGby9vY?px{Tnkpj&hYJvThi^A8Pd5^=q_e`_J27^XT1amZ@-patKw z_Xf0XS-@{#STfdyHZLCNp$P(mN<%O~V4@F(Q#F9Om4N9S)k>c7m50s%HXCB~MW&eb zksrOaT-jarF;5+AhR^vT35s?y#=JKDU3~#4^QNxjH2=YX{V=S9tWHLE0bPO|ytMOo zd@}|f?8JC;e;v1QbM`My8{$(PWHqPy?d>tTv^*M0zY2;0?K()}=GrXE#VYfr_L<+y9o{eot$96E ziuXn4FHhm0XQpb(V~^`m_cej9K9m970JT!x>L{;OO???iV|{xnepXgVsgH_Y5gwK>U%chwIS(fins3`FuDAB{TKwdeuf-W>VCjq%21IYoKL=1>A&CMf1ui#H3oJTilzJYsr7GNHOvGzvpHnS zVWZ!lI)53~J6S-u!8cb#{p(XzTk1dGbtH@|ev|ng!hO_iievu&{pbI!-El9RLGcgY zslCKVNvCt7KRgxh=}@1_gzWb>W%;FkN(Z{vaFbBgQhj}p$I=#Nno_~Sbw;S}&nO0+ioWEoY$qH9V^VS?VXCebi6IrTHR0^B1xwXr}$0 zc>nHAUOreQtLl__eXWMAst09ts0}(|U8|Y8tRRYZOoBNsOWpTKs*1j1Lh<-Y)*ob( z{Nb6B7hh>389$ys1Md?{x>~KU$8@TibZrW&)KB#DcPD6hArX_ZQb3glsT^Zt`l3^R?=9A>uEIw?53KSO)!S3-VkAhR7@Ek35_ o?~E1T7UeZCtZBvOm^A`wnd)9)DuI4`Dn8M-k1$jG7qdo`ErCO?i~s-t diff --git a/backend/python-docs/_build/dirhtml/searchindex.js b/backend/python-docs/_build/dirhtml/searchindex.js index 49123dc95..3b65e59d4 100644 --- a/backend/python-docs/_build/dirhtml/searchindex.js +++ b/backend/python-docs/_build/dirhtml/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["bailo.core", "bailo.helper", "index", "notebooks/access_requests_demo", "notebooks/datacards_demo", "notebooks/experiment_tracking_demo", "notebooks/models_and_releases_demo_pytorch", "notebooks/schemas_demo", "pre-commit-config", "pylint", "pyproject", "readme_link"], "filenames": ["bailo.core.rst", "bailo.helper.rst", "index.rst", "notebooks/access_requests_demo.ipynb", "notebooks/datacards_demo.ipynb", "notebooks/experiment_tracking_demo.ipynb", "notebooks/models_and_releases_demo_pytorch.ipynb", "notebooks/schemas_demo.ipynb", "pre-commit-config.md", "pylint.md", "pyproject.md", "readme_link.md"], "titles": ["bailo.core package", "bailo.helper package", "Welcome to Bailo\u2019s Python Client documentation!", "Managing Access Requests", "Managing Datacards", "Experiment Tracking with Bailo & MLFlow", "Managing Models & Releases (ResNet-50 Example with PyTorch)", "Managing Schemas", "pre-commit-config.yaml", "A comma-separated list of package or module names from where C extensions may", "pypyroject.toml", "Bailo Python Client"], "terms": {"The": [0, 1, 3, 4, 5, 6, 7, 8, 10, 11], "contain": [0, 5, 6, 10], "suppport": 0, "one": [0, 5, 6], "endpoint": [0, 3, 4, 6, 7], "It": [0, 10], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11], "recommend": 0, "us": [0, 1, 5, 8, 10, 11], "helper": [0, 2, 3, 4, 6, 7], "most": [0, 5], "class": [0, 1, 3, 4, 5, 6, 7], "agent": [0, 2, 3, 4, 6, 7], "sourc": [0, 1], "base": [0, 1], "object": [0, 1, 3, 4, 5, 6, 7], "api": [0, 11], "talk": 0, "wrap": 0, "each": [0, 4, 6], "request": [0, 1, 2], "an": [0, 1], "except": 0, "handler": 0, "map": 0, "error": [0, 1, 4, 6], "python": [0, 1, 3, 4, 6, 7, 8, 10], "among": 0, "statu": 0, "code": [0, 6, 8], "less": 0, "than": 0, "400": 0, "default": [0, 1, 3, 4, 6, 7, 11], "timeout": [], "5": [1, 5, 7, 9], "second": [], "delet": [0, 1], "arg": [0, 9], "kwarg": 0, "get": [0, 1, 2], "patch": 0, "post": [0, 1], "push": 0, "put": 0, "pkiagent": [0, 2, 3, 4, 6, 7], "cert": [0, 3, 4, 6, 7], "str": [0, 1, 5], "kei": [0, 2, 3, 4, 6, 7], "auth": [0, 3, 4, 6, 7], "__init__": [0, 1], "initi": [0, 6], "pki": [0, 3, 4, 6, 7], "authent": [0, 3, 4, 6, 7], "paramet": [0, 1, 3, 4, 5, 6, 7], "path": [0, 1, 6], "file": [0, 1, 6, 10, 11], "certif": 0, "author": 0, "tokenag": [0, 2], "access_kei": 0, "secret_kei": 0, "token": 0, "access": [0, 1, 2, 5], "secret": 0, "client": [0, 1, 3, 4, 6, 7], "url": [0, 3, 4, 5, 6, 7], "creat": [0, 1, 8, 11], "can": [0, 1, 3, 4, 5, 6, 7, 8, 11], "websit": 0, "handl": [0, 3, 4, 6, 7], "delete_access_request": 0, "model_id": [0, 1, 3, 6], "access_request_id": [0, 1, 3], "specif": [0, 1, 4, 6], "associ": 0, "model": [0, 1, 2, 3, 4, 5, 7, 11], "uniqu": [0, 1, 7], "id": [0, 1, 5], "return": [0, 1, 6, 7], "json": [0, 1, 6, 7], "respons": [0, 1], "delete_fil": 0, "file_id": 0, "delete_releas": 0, "release_vers": 0, "releas": [0, 1, 2, 4, 5, 11], "version": [0, 1, 4, 6, 11], "get_access_request": 0, "retriev": [0, 1], "given": [0, 1, 11], "its": 0, "all": [0, 1, 6, 11], "get_all_imag": 0, "imag": [0, 1, 4, 6], "A": [0, 1, 3, 4, 5, 6, 7, 11], "get_all_releas": 0, "get_all_schema": 0, "kind": [0, 1, 5, 7], "schemakind": [0, 1, 2, 5, 7], "none": [0, 1], "schema": [0, 1, 2, 4, 6], "enum": [0, 1], "defin": [0, 5], "e": [0, 1, 3, 4, 6, 7, 11], "g": [0, 1, 3, 4, 6, 7], "accessrequest": [0, 1, 2, 3], "get_all_team": 0, "team": [0, 1], "get_download_by_filenam": 0, "semver": [0, 1], "filenam": [0, 1, 6], "download": [0, 1, 11], "try": 0, "from": [0, 1, 3, 4, 7, 8, 11], "get_download_fil": 0, "": [0, 1], "get_fil": 0, "get_model": 0, "get_model_card": 0, "card": [0, 1, 4, 5], "get_model_rol": 0, "role": [0, 1, 2], "get_model_user_rol": 0, "current": [0, 1, 10], "user": [0, 1, 3, 8], "task": 0, "librari": [0, 6], "list": [0, 1, 6], "filter": 0, "search": 0, "find": [0, 7], "provid": [0, 1, 2, 5, 6], "term": 0, "classif": [0, 6], "tensorflow": 0, "custom": [0, 4, 6], "string": [0, 1, 7], "locat": [0, 1, 5], "get_releas": [0, 1, 6], "get_review": 0, "activ": 0, "bool": [0, 1, 9], "review": [0, 1], "within": [0, 1, 2, 3, 4, 5, 6, 7, 11], "boolean": 0, "repres": [0, 1, 6], "get_schema": 0, "schema_id": [0, 1, 3, 4, 5, 6, 7], "get_team": 0, "team_id": [0, 1, 3, 4, 5, 6, 11], "get_user_team": 0, "model_card_from_schema": 0, "patch_access_request": 0, "metadata": [0, 1, 3], "ani": [0, 1, 3, 4, 5, 6, 7], "updat": [0, 1, 3], "patch_model": 0, "name": [0, 1, 3, 4, 5, 6, 7, 11], "descript": [0, 1, 3, 4, 5, 6, 7, 11], "visibl": [0, 1, 4, 6], "public": [0, 1], "privat": [0, 1], "patch_team": 0, "post_access_request": 0, "post_model": 0, "modelvis": [0, 1, 2], "post_releas": 0, "note": [0, 1, 4, 5, 6, 7, 11], "model_card_vers": [0, 1, 6], "int": [0, 1, 9], "minor": [0, 1, 6], "fals": [0, 1, 7], "draft": [0, 1, 7], "new": [0, 1, 11], "signifi": 0, "post_review": 0, "decis": 0, "comment": 0, "semant": [0, 1], "make": [0, 1, 4, 6, 11], "either": [0, 1, 4, 6, 11], "approv": 0, "chang": [0, 1, 4, 6], "go": 0, "post_schema": 0, "json_schema": [0, 1, 5, 7], "dict": [0, 1], "post_team": 0, "put_model_card": 0, "latest": [0, 1, 4, 6], "put_releas": 0, "simple_upload": 0, "buffer": 0, "bytesio": [0, 1, 6], "simpl": [0, 11], "upload": [0, 1, 11], "valu": [0, 1], "whether": [0, 1], "publicli": 0, "model_senior_responsible_offic": 0, "msro": 0, "model_technical_review": 0, "mtr": 0, "owner": 0, "type": [0, 6, 7], "access_request": [0, 1, 3], "bailoexcept": [0, 1, 2], "gener": [0, 3, 4, 6, 7, 8, 11], "responseexcept": [0, 2], "gave": 0, "created_bi": 1, "being": 1, "made": 1, "thi": [1, 2, 3, 4, 5, 6, 7, 10, 11], "ha": [1, 4], "been": [1, 4, 5], "classmethod": [1, 3, 4, 6, 7, 9], "interact": [1, 2, 3, 4, 6, 7], "messag": [1, 6], "confirm": 1, "remov": 1, "from_id": 1, "exist": [1, 3], "state": 1, "experi": [1, 2], "local": [1, 3, 4, 5, 6, 7], "which": [1, 3, 4, 5, 6, 7, 8], "run": [1, 3, 4, 6, 7, 11], "raw": 1, "inform": [1, 3, 4, 6, 7], "about": 1, "create_experi": [1, 5], "x": [1, 5], "rang": [1, 5], "start_run": [1, 5], "log_param": [1, 5], "lr": [1, 5], "0": [1, 3, 4, 5, 6, 7, 11], "01": [1, 3, 5], "insert": [1, 3, 4, 5, 6, 7], "train": [1, 5], "here": [1, 11], "log_metr": [1, 5], "accuraci": [1, 5], "86": [1, 5], "log_artifact": [1, 5], "weight": [1, 5], "pth": [1, 6], "publish": [1, 10], "mc_loc": [1, 5], "perform": [1, 5, 8], "performancemetr": [1, 5], "run_id": [1, 5], "1": [1, 3, 4, 5, 6, 7, 11], "from_mlflow": [1, 5], "tracking_uri": [1, 5], "experiment_id": [1, 5], "import": [1, 3, 4, 6, 7, 11], "mlflow": [1, 2], "track": [1, 2], "server": [1, 5], "uri": [1, 5], "rais": 1, "importerror": 1, "instal": [1, 2, 4, 5, 6], "artifact": [1, 5], "log": [1, 5], "log_dataset": 1, "dataset": [1, 4], "arbitrari": [1, 5], "titl": [1, 7], "metric": [1, 5], "dictionari": 1, "param": [1, 5], "result": 1, "select": [1, 6], "present": 1, "next": [1, 4, 5, 6], "depend": [1, 5, 8], "is_mlflow": 1, "start": [1, 2], "mark": 1, "card_from_model": [], "copi": [], "differ": 6, "yet": 1, "implement": 1, "notimplementederror": 1, "Not": 1, "card_from_schema": [1, 4, 5, 6, 11], "card_from_templ": 1, "templat": 1, "build": [1, 8, 10], "create_releas": [1, 6, 11], "true": [1, 7], "call": [1, 3, 4, 6], "method": [1, 5], "get_card_latest": 1, "get_card_revis": 1, "revis": 1, "get_imag": 1, "refer": [1, 6], "get_latest_releas": [1, 6], "from_vers": 1, "get_rol": 1, "get_user_rol": 1, "summari": [1, 7], "update_model_card": [1, 5, 6], "model_card": [1, 5, 6], "If": [1, 4, 5, 6, 11], "attribut": [1, 3, 4, 6], "option": [1, 10], "ar": [1, 3, 4, 5, 6, 7, 8, 10, 11], "store": 1, "write": [1, 6], "give": [], "read": [], "determin": 1, "disk": [1, 6], "set": [1, 4, 6], "data": [0, 1, 4], "directori": [1, 6, 11], "load": 1, "zip": 1, "ecosystem": 2, "manag": 2, "lifecycl": [2, 5], "machin": [2, 5], "learn": [2, 4, 5, 6], "support": [1, 2, 3, 4, 5, 6, 7], "featur": 2, "develop": 2, "core": [2, 3, 4, 5, 6, 7], "resnet": 2, "50": [2, 9], "exampl": [2, 3, 4, 5, 7, 10], "pytorch": 2, "bailo": [3, 7], "enabl": [3, 4, 6, 7], "intuit": [3, 4, 6, 7], "servic": [3, 4, 5, 6, 7], "environ": [3, 4, 5, 6, 7], "notebook": [3, 4, 5, 6, 7], "through": [3, 4, 5, 6, 7], "follow": [3, 4, 5, 6, 7, 11], "concept": [3, 4, 5, 6, 7], "prerequisit": [3, 4, 5, 6, 7], "3": [3, 4, 5, 6, 7, 11], "8": [3, 4, 5, 6, 7, 9, 11], "higher": [3, 4, 5, 6, 7, 11], "includ": [1, 3, 4, 5, 6, 7, 8, 10], "demo": [3, 4, 5, 6, 7], "remot": [3, 4, 5, 6, 7], "see": [3, 4, 5, 6, 7], "http": [3, 4, 5, 6, 7, 9, 11], "github": [3, 4, 5, 6, 7], "com": [3, 4, 5, 6, 7], "gchq": [3, 4, 5, 6, 7], "split": [3, 4, 6, 7, 11], "two": [3, 4, 6, 7], "sub": [3, 4, 6, 7], "packag": [3, 4, 6, 7, 8, 10], "For": [3, 4, 6, 7], "direct": [3, 4, 6, 7], "more": [3, 4, 5, 6, 7], "oper": [3, 4, 6, 7], "In": [3, 4, 5, 6, 7, 8, 11], "order": [3, 4, 5, 6, 7, 11], "you": [3, 4, 5, 6, 7, 11], "first": [3, 4, 5, 6, 7], "need": [3, 4, 5, 6, 7], "instanti": [3, 4, 5, 6, 7], "By": [3, 4, 6, 7], "howev": [3, 4, 6, 7], "also": [3, 4, 5, 6, 7, 10], "pass": [3, 4, 6, 7], "when": [3, 4, 6, 7, 10], "necessari": [3, 4, 5, 6, 7], "statement": [1, 3, 4, 5, 6, 7], "127": [3, 4, 5, 6, 7], "8080": [3, 4, 5, 6, 7, 11], "host": [3, 4, 5, 6, 7], "section": [3, 4, 5, 6, 7, 11], "we": [3, 4, 5, 6, 7], "ll": [3, 4, 5, 6, 7], "On": [3, 4, 6, 7], "must": [3, 4, 5, 6, 7], "consist": [3, 4, 6, 7], "least": [3, 4, 6], "upon": [3, 4, 6, 7], "creation": [3, 4, 6, 7], "These": [3, 4, 6, 7, 8], "below": [3, 4, 6, 7], "befor": [3, 4, 5, 6, 7], "our": [3, 4, 5, 6, 7], "yolov5": [3, 5], "detect": [3, 5], "uncategoris": [3, 4, 5, 6, 11], "overview": [3, 4, 5, 6, 7], "entiti": 3, "test": [3, 7, 10], "enddat": 3, "1970": 3, "minim": [3, 4, 6, 11], "v10": [3, 4, 6, 11], "previou": [3, 4, 5, 6, 7], "your": [3, 4, 5, 6, 7], "edit": 3, "directli": [3, 5, 6], "demonstr": [3, 5, 6], "new_metadata": 3, "newnam": 3, "simpli": 3, "addit": [5, 6], "cover": 5, "offer": 5, "integr": [5, 6, 11], "might": 5, "wider": 5, "particular": 5, "complet": 5, "basic": [5, 9], "models_and_releases_demo_pytorch": 5, "ipynb": 5, "step": [5, 6], "have": [4, 5, 6], "thu": 5, "too": [4, 5, 6, 7], "how": [4, 5, 6], "do": [5, 6, 7], "time": [4, 5, 6], "later": [4, 5, 6], "pip": [4, 5, 6, 11], "random": [5, 7], "element": 5, "tutori": 5, "instanc": [4, 5, 6, 7], "sampl": 5, "actual": [4, 5], "onli": [5, 6, 8, 10, 11], "function": [5, 7], "ui": 5, "command": [5, 6], "line": 5, "typic": [5, 7], "localhost": [5, 11], "5000": [5, 7], "browser": 5, "design": [5, 9], "displai": [5, 6], "wai": 5, "therefor": 5, "extern": 5, "script": 5, "quit": 5, "larg": 5, "set_schema": 5, "py": [5, 9, 10], "assign": [1, 4, 5, 6], "randint": 5, "1000000": 5, "mandatori": 5, "field": 5, "new_card": [4, 5, 6], "tag": [5, 6, 7], "modelsummari": [5, 6], "work": [5, 11], "sequenti": 5, "so": 5, "re": [5, 6], "parallel": 5, "would": [5, 7], "better": 5, "anchor_t": 5, "4": [4, 5, 6], "scale": 5, "98": 5, "txt": [5, 6], "2": [4, 5, 6], "set_tracking_uri": 5, "set_experi": 5, "demonst": 5, "same": [5, 6], "set_tag": 5, "info": 5, "As": 5, "previous": 5, "mention": 5, "experiment_mlflow": 5, "BE": 5, "found": 5, "ON": 5, "THE": 5, "becaus": 5, "intend": 5, "success": [4, 5, 6], "specifi": 5, "well": 5, "case": [5, 6], "per": 5, "earlier": [5, 6], "should": [4, 5, 6], "now": [4, 5, 6], "under": 5, "tab": 5, "addition": 5, "relev": 6, "linux": 6, "cpu": 6, "torch": [6, 9], "torchvis": 6, "index": 6, "org": [6, 7], "whl": 6, "mac": 6, "window": [6, 11], "resnet50": 6, "resnet50_weight": 6, "other": [6, 7, 11], "like": [4, 6], "ad": 6, "backend": [4, 6, 11], "mai": [4, 6, 10, 11], "relai": [4, 6], "empti": [4, 6], "beta": 11, "out": [4, 6], "scope": [4, 6], "print": [4, 6], "f": [4, 6, 11], "abov": [4, 6], "want": [4, 6], "match": [4, 6], "otherwis": [4, 6], "thrown": [4, 6], "adjust": 6, "don": 6, "t": 6, "drastic": 6, "behaviour": 6, "separ": 6, "itself": 6, "release_on": 6, "save": 6, "them": 6, "take": 6, "allow": 6, "u": 6, "without": 6, "up": 6, "space": 6, "torch_model": 6, "state_dict": 6, "To": 6, "content": [6, 11], "last": 6, "s3": [4, 6], "large_fil": [], "open": 11, "rb": [], "altern": 6, "both": [6, 10], "release_latest": 6, "successfulli": 6, "ident": 6, "similarli": 6, "bailo_resnet50_weight": 6, "wb": [], "final": 6, "ve": 6, "load_state_dict": 6, "init": 6, "identifi": 7, "suffic": 7, "reserv": 7, "administr": 7, "def": 7, "random_gener": 7, "n": [7, 9], "10": 7, "join": 7, "choic": [7, 9], "ascii_uppercas": 7, "digit": 7, "k": [7, 9], "07": 7, "properti": [1, 7], "modeloverview": 7, "what": 7, "doe": 7, "minlength": 7, "maxlength": 7, "searchabl": 7, "help": [7, 8], "arrai": 7, "widget": 7, "tagselectorbeta": 7, "item": 7, "uniqueitem": 7, "requir": [7, 10, 11], "additionalproperti": 7, "git": [1, 8, 11], "hook": [8, 9], "scan": 8, "prior": 8, "checkin": 8, "configur": [8, 10], "focus": 8, "action": 8, "prevent": 8, "fail": 8, "dure": 8, "format": 8, "automat": 8, "auto": 8, "black": 8, "sort": 8, "isort": 8, "lint": [8, 10], "left": 8, "discret": 8, "master": 9, "pkg": 9, "whitelist": 9, "numpi": 9, "cv2": 9, "pyodbc": 9, "pydant": 9, "ciso8601": 9, "netcdf4": 9, "scipi": 9, "cv": 9, "conftest": 9, "setrecursionlimit": 9, "getrecursionlimit": 9, "job": 9, "100": 9, "persist": 9, "ye": 9, "rcfile": 9, "mode": 9, "unsaf": 9, "float": 9, "_": 9, "msg": 9, "max": 9, "exit": 9, "snake_cas": 9, "rgx": 9, "foo": 9, "bar": 9, "baz": 9, "toto": 9, "tutu": 9, "tata": 9, "pascalcas": 9, "upper_cas": 9, "min": 9, "j": 9, "ex": 9, "df": 9, "ax": 9, "group": 9, "long": 9, "after": 9, "paren": 9, "120": 9, "1000": 9, "stmt": 9, "miscellan": 9, "fixm": 9, "xxx": 9, "todo": 9, "9": 9, "jump": 9, "typecheck": 9, "np": 9, "pyspark": 9, "sql": 9, "collect_list": 9, "optpars": 9, "thread": 9, "_local": 9, "_thread": 9, "swagger_cli": 9, "mutat": 9, "dbutil": 9, "cb_": 9, "_cb": 9, "za": 9, "z0": 9, "9_": 9, "unused_": 9, "six": 9, "move": 9, "past": 9, "futur": [9, 10], "io": 9, "setup": [9, 10], "post_init": 9, "_asdict": 9, "_field": 9, "_replac": 9, "_sourc": 9, "_make": 9, "cl": 9, "7": 9, "expr": 9, "12": 9, "15": 9, "20": 9, "6": 9, "tkinter": 9, "tix": 9, "ext": 9, "known": 9, "azureiai": 9, "logist": 9, "inventoryplan": 9, "overgener": 9, "pyproject": 10, "main": 10, "project": 10, "replac": 10, "flit": 10, "poetri": 10, "consid": 10, "viabl": 10, "setuptool": 10, "cfg": 10, "still": 10, "wrapper": 11, "tabl": 11, "binari": 11, "yolo": 11, "yolov4": 11, "look": 11, "onc": 11, "my_releas": 11, "onnx": 11, "documen": 11, "render": 11, "sphinx": 11, "serv": 11, "doc": [1, 11], "html": 11, "bat": 11, "alreadi": 11, "prompt": 11, "overwrit": 11, "huski": 11, "instruct": 11, "cli": 11, "pre": 11, "commit": 11, "pytest": 11, "ran": 11, "accordingli": 11, "categori": 11, "autom": 11, "purpos": 11, "sure": 11, "m": 11, "datacard": [0, 1, 2], "entrykind": [0, 1, 2], "entri": [1, 2], "model_card_schema": 1, "download_al": [1, 6], "home": 1, "ubuntu": 1, "lib": 1, "exclud": [1, 6], "fnmatch": 1, "unix": 1, "shell": 1, "style": 1, "wildcard": 1, "datacard_id": [1, 4], "stage": 4, "imagenet": 4, "data_card_vers": [1, 4], "update_data_card": [1, 4], "storageloc": 4, "data_card": [1, 4], "destin": 6, "data_card_schema": 1}, "objects": {"": [[2, 0, 0, "-", "bailo"]], "bailo.core": [[0, 0, 0, "-", "agent"], [0, 0, 0, "-", "client"], [0, 0, 0, "-", "enums"], [0, 0, 0, "-", "exceptions"]], "bailo.core.agent": [[0, 1, 1, "", "Agent"], [0, 1, 1, "", "PkiAgent"], [0, 1, 1, "", "TokenAgent"]], "bailo.core.agent.Agent": [[0, 2, 1, "", "delete"], [0, 2, 1, "", "get"], [0, 2, 1, "", "patch"], [0, 2, 1, "", "post"], [0, 2, 1, "", "push"], [0, 2, 1, "", "put"]], "bailo.core.agent.PkiAgent": [[0, 2, 1, "", "__init__"], [0, 2, 1, "", "delete"], [0, 2, 1, "", "get"], [0, 2, 1, "", "patch"], [0, 2, 1, "", "post"], [0, 2, 1, "", "put"]], "bailo.core.agent.TokenAgent": [[0, 2, 1, "", "__init__"], [0, 2, 1, "", "delete"], [0, 2, 1, "", "get"], [0, 2, 1, "", "patch"], [0, 2, 1, "", "post"], [0, 2, 1, "", "put"]], "bailo.core.client": [[0, 1, 1, "", "Client"]], "bailo.core.client.Client": [[0, 2, 1, "", "delete_access_request"], [0, 2, 1, "", "delete_file"], [0, 2, 1, "", "delete_release"], [0, 2, 1, "", "get_access_request"], [0, 2, 1, "", "get_access_requests"], [0, 2, 1, "", "get_all_images"], [0, 2, 1, "", "get_all_releases"], [0, 2, 1, "", "get_all_schemas"], [0, 2, 1, "", "get_all_teams"], [0, 2, 1, "", "get_download_by_filename"], [0, 2, 1, "", "get_download_file"], [0, 2, 1, "", "get_files"], [0, 2, 1, "", "get_model"], [0, 2, 1, "", "get_model_card"], [0, 2, 1, "", "get_model_roles"], [0, 2, 1, "", "get_model_user_roles"], [0, 2, 1, "", "get_models"], [0, 2, 1, "", "get_release"], [0, 2, 1, "", "get_reviews"], [0, 2, 1, "", "get_schema"], [0, 2, 1, "", "get_team"], [0, 2, 1, "", "get_user_teams"], [0, 2, 1, "", "model_card_from_schema"], [0, 2, 1, "", "patch_access_request"], [0, 2, 1, "", "patch_model"], [0, 2, 1, "", "patch_team"], [0, 2, 1, "", "post_access_request"], [0, 2, 1, "", "post_model"], [0, 2, 1, "", "post_release"], [0, 2, 1, "", "post_review"], [0, 2, 1, "", "post_schema"], [0, 2, 1, "", "post_team"], [0, 2, 1, "", "put_model_card"], [0, 2, 1, "", "put_release"], [0, 2, 1, "", "simple_upload"]], "bailo.core.enums": [[0, 1, 1, "", "EntryKind"], [0, 1, 1, "", "ModelVisibility"], [0, 1, 1, "", "Role"], [0, 1, 1, "", "SchemaKind"]], "bailo.core.enums.EntryKind": [[0, 3, 1, "", "DATACARD"], [0, 3, 1, "", "MODEL"]], "bailo.core.enums.ModelVisibility": [[0, 3, 1, "", "PRIVATE"], [0, 3, 1, "", "PUBLIC"]], "bailo.core.enums.Role": [[0, 3, 1, "", "MODEL_SENIOR_RESPONSIBLE_OFFICER"], [0, 3, 1, "", "MODEL_TECHNICAL_REVIEWER"], [0, 3, 1, "", "OWNER"]], "bailo.core.enums.SchemaKind": [[0, 3, 1, "", "ACCESS_REQUEST"], [0, 3, 1, "", "MODEL"]], "bailo.core.exceptions": [[0, 4, 1, "", "BailoException"], [0, 4, 1, "", "ResponseException"]], "bailo.helper": [[1, 0, 0, "-", "access_request"], [1, 0, 0, "-", "datacard"], [1, 0, 0, "-", "entry"], [1, 0, 0, "-", "model"], [1, 0, 0, "-", "release"], [1, 0, 0, "-", "schema"]], "bailo.helper.access_request": [[1, 1, 1, "", "AccessRequest"]], "bailo.helper.access_request.AccessRequest": [[1, 2, 1, "", "create"], [1, 2, 1, "", "delete"], [1, 2, 1, "", "from_id"], [1, 2, 1, "", "update"]], "bailo.helper.datacard": [[1, 1, 1, "", "Datacard"]], "bailo.helper.datacard.Datacard": [[1, 2, 1, "", "create"], [1, 5, 1, "", "data_card"], [1, 5, 1, "", "data_card_schema"], [1, 5, 1, "", "data_card_version"], [1, 2, 1, "", "from_id"], [1, 2, 1, "", "update_data_card"]], "bailo.helper.entry": [[1, 1, 1, "", "Entry"]], "bailo.helper.entry.Entry": [[1, 2, 1, "", "card_from_schema"], [1, 2, 1, "", "card_from_template"], [1, 2, 1, "", "get_card_latest"], [1, 2, 1, "", "get_card_revision"], [1, 2, 1, "", "get_roles"], [1, 2, 1, "", "get_user_roles"], [1, 2, 1, "", "update"]], "bailo.helper.model": [[1, 1, 1, "", "Experiment"], [1, 1, 1, "", "Model"]], "bailo.helper.model.Experiment": [[1, 2, 1, "", "create"], [1, 2, 1, "", "from_mlflow"], [1, 2, 1, "", "log_artifacts"], [1, 2, 1, "", "log_dataset"], [1, 2, 1, "", "log_metrics"], [1, 2, 1, "", "log_params"], [1, 2, 1, "", "publish"], [1, 2, 1, "", "start_run"]], "bailo.helper.model.Model": [[1, 2, 1, "", "create"], [1, 2, 1, "", "create_experiment"], [1, 2, 1, "", "create_release"], [1, 2, 1, "", "from_id"], [1, 2, 1, "", "get_image"], [1, 2, 1, "", "get_images"], [1, 2, 1, "", "get_latest_release"], [1, 2, 1, "", "get_release"], [1, 2, 1, "", "get_releases"], [1, 5, 1, "", "model_card"], [1, 5, 1, "", "model_card_schema"], [1, 5, 1, "", "model_card_version"], [1, 2, 1, "", "update_model_card"]], "bailo.helper.release": [[1, 1, 1, "", "Release"]], "bailo.helper.release.Release": [[1, 2, 1, "", "__init__"], [1, 2, 1, "", "create"], [1, 2, 1, "", "delete"], [1, 2, 1, "", "download"], [1, 2, 1, "", "download_all"], [1, 2, 1, "", "from_version"], [1, 2, 1, "", "update"], [1, 2, 1, "", "upload"]], "bailo.helper.schema": [[1, 1, 1, "", "Schema"]], "bailo.helper.schema.Schema": [[1, 2, 1, "", "create"], [1, 2, 1, "", "from_id"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:method", "3": "py:attribute", "4": "py:exception", "5": "py:property"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "method", "Python method"], "3": ["py", "attribute", "Python attribute"], "4": ["py", "exception", "Python exception"], "5": ["py", "property", "Python property"]}, "titleterms": {"bailo": [0, 1, 2, 4, 5, 6, 11], "core": 0, "packag": [0, 1, 2, 9, 11], "helper": 1, "welcom": 2, "": [2, 9], "python": [2, 5, 9, 11], "client": [2, 5, 11], "document": [2, 11], "notebook": 2, "manag": [3, 4, 6, 7, 9], "access": [3, 9], "request": 3, "introduct": [3, 4, 5, 6, 7], "creat": [3, 4, 5, 6, 7, 9], "new": [3, 4, 5, 6, 7, 9], "retriev": [3, 4, 6, 7], "an": [3, 4, 5, 6, 7, 9], "us": [3, 4, 6, 7, 9], "from_id": [3, 4, 6, 7], "method": [3, 4, 6, 7, 9], "make": [3, 9], "chang": [3, 9], "delet": 3, "experi": 5, "track": 5, "mlflow": 5, "connect": 5, "set": [5, 9], "up": [5, 9], "prepar": [5, 6], "custom": 5, "schema": [5, 7], "conduct": 5, "run": [5, 9], "dummi": [5, 9], "import": [5, 9], "exist": [4, 5, 6, 7, 9], "from": [5, 6, 9], "publish": 5, "result": [5, 9], "model": 6, "releas": 6, "resnet": 6, "50": 6, "exampl": [6, 9], "pytorch": 6, "updat": [4, 6], "base": [4, 6, 9], "popul": [4, 6], "card": 6, "weight": 6, "upload": 6, "download": 6, "load": [6, 9], "pre": 8, "commit": 8, "config": 8, "yaml": 8, "A": 9, "comma": 9, "separ": 9, "list": 9, "modul": 9, "name": 9, "where": 9, "c": 9, "extens": 9, "mai": 9, "ar": 9, "activ": 9, "interpret": 9, "arbitrari": 9, "code": 9, "add": [9, 11], "file": 9, "directori": 9, "blacklist": 9, "thei": 9, "should": 9, "path": 9, "match": 9, "regex": 9, "pattern": 9, "The": 9, "against": 9, "execut": 9, "usual": 9, "sy": 9, "manipul": 9, "pygtk": 9, "requir": 9, "multipl": 9, "process": 9, "speed": 9, "pylint": 9, "specifi": 9, "0": 9, "auto": 9, "detect": 9, "number": 9, "processor": 9, "avail": 9, "control": 9, "amount": 9, "potenti": 9, "infer": 9, "valu": 9, "when": 9, "singl": 9, "object": 9, "thi": 9, "can": 9, "help": 9, "perform": 9, "deal": 9, "larg": 9, "function": 9, "complex": 9, "nest": 9, "condit": 9, "plugin": 9, "regist": 9, "addit": 9, "checker": 9, "pickl": 9, "collect": 9, "data": 9, "later": 9, "comparison": 9, "configur": 9, "enabl": 9, "would": 9, "attempt": 9, "guess": 9, "common": 9, "misconfigur": 9, "emit": 9, "user": 9, "friendli": 9, "hint": 9, "instead": 9, "fals": 9, "posit": 9, "error": 9, "messag": 9, "allow": 9, "onli": 9, "show": 9, "warn": 9, "confid": 9, "level": 9, "leav": 9, "empti": 9, "all": 9, "valid": 9, "high": 9, "inference_failur": 9, "undefin": 9, "disabl": 9, "report": 9, "categori": 9, "given": 9, "id": 9, "you": 9, "either": 9, "give": 9, "identifi": 9, "put": 9, "option": 9, "time": 9, "command": 9, "line": 9, "appear": 9, "onc": 9, "also": 9, "everyth": 9, "first": 9, "reenabl": 9, "specif": 9, "check": 9, "For": 9, "want": 9, "similar": 9, "If": 9, "class": 9, "have": 9, "displai": 9, "w": 9, "see": 9, "express": 9, "which": 9, "return": 9, "score": 9, "less": 9, "than": 9, "equal": 9, "10": 9, "variabl": 9, "refactor": 9, "convent": 9, "contain": 9, "each": 9, "well": 9, "statement": 9, "i": 9, "total": 9, "analyz": 9, "global": 9, "evalu": 9, "rp0004": 9, "templat": 9, "style": 9, "format": 9, "string": 9, "inform": 9, "doc": 9, "detail": 9, "output": 9, "text": 9, "parseabl": 9, "color": 9, "json": 9, "msv": 9, "visual": 9, "studio": 9, "e": 9, "g": 9, "mypackag": 9, "mymodul": 9, "myreporterclass": 9, "tell": 9, "whether": 9, "full": 9, "maximum": 9, "block": 9, "bodi": 9, "complet": 9, "never": 9, "inconsist": 9, "call": 9, "consid": 9, "explicit": 9, "print": 9, "correct": 9, "argument": 9, "regular": 9, "overrid": 9, "attribut": 9, "attr": 9, "bad": 9, "alwai": 9, "refus": 9, "constant": 9, "const": 9, "minimum": 9, "length": 9, "docstr": 9, "shorter": 9, "ones": 9, "exempt": 9, "good": 9, "accept": 9, "includ": 9, "invalid": 9, "inlin": 9, "iter": 9, "inlinevar": 9, "colon": 9, "delimit": 9, "determin": 9, "other": 9, "sever": 9, "do": 9, "decor": 9, "produc": 9, "properti": 9, "abc": 9, "abstractproperti": 9, "These": 9, "taken": 9, "consider": 9, "expect": 9, "end": 9, "ani": 9, "lf": 9, "crlf": 9, "regexp": 9, "longer": 9, "limit": 9, "space": 9, "indent": 9, "insid": 9, "hang": 9, "continu": 9, "unit": 9, "4": 9, "t": 9, "1": 9, "tab": 9, "charact": 9, "construct": 9, "whitespac": 9, "dict": 9, "tabul": 9, "etc": 9, "n222": 9, "2": 9, "trail": 9, "between": 9, "close": 9, "bracket": 9, "same": 9, "declar": 9, "test": [9, 11], "els": 9, "log": 9, "old": 9, "mean": 9, "fstr": 9, "f": 9, "paramet": 9, "note": 9, "tag": 9, "take": 9, "ignor": 9, "comment": 9, "comput": 9, "count": 9, "suggest": 9, "spell": 9, "mistak": 9, "dictionari": 9, "none": 9, "To": 9, "work": 9, "instal": [9, 11], "enchant": 9, "word": 9, "privat": 9, "one": 9, "per": 9, "store": 9, "unknown": 9, "rais": 9, "flag": 9, "implicit": 9, "str": 9, "concat": 9, "sequenc": 9, "gener": 9, "concaten": 9, "defin": 9, "over": 9, "context": 9, "contextlib": 9, "contextmanag": 9, "member": 9, "dynam": 9, "miss": 9, "system": 9, "so": 9, "shouldn": 9, "trigger": 9, "e1101": 9, "mixin": 9, "its": 9, "case": 9, "insensit": 9, "about": 9, "owner": 9, "whenev": 9, "opaqu": 9, "while": 9, "some": 9, "branch": 9, "might": 9, "partial": 9, "In": 9, "still": 9, "rest": 9, "support": 9, "qualifi": 9, "project": 9, "namespac": 9, "dure": 9, "runtim": 9, "thu": 9, "cannot": 9, "deduc": 9, "static": 9, "analysi": 9, "It": 9, "unix": 9, "possibl": 9, "wa": 9, "found": 9, "aspect": 9, "find": 9, "edit": 9, "distanc": 9, "order": 9, "signatur": 9, "suppos": 9, "builtin": 9, "rememb": 9, "avoid": 9, "unus": 9, "treat": 9, "violat": 9, "callback": 9, "must": 9, "start": [9, 11], "those": 9, "default": 9, "lead": 9, "underscor": 9, "we": 9, "init": 9, "redefin": 9, "assign": 9, "instanc": 9, "exclud": 9, "protect": 9, "metaclass": 9, "r0902": 9, "boolean": 9, "r0916": 9, "local": [9, 11], "parent": 9, "r0901": 9, "public": 9, "r0904": 9, "yield": 9, "r0903": 9, "just": 9, "top": 9, "wildcard": 9, "analys": 9, "fallback": 9, "both": 9, "3": 9, "compat": 9, "anoth": 9, "deprec": 9, "graph": 9, "extern": 9, "depend": 9, "rp0402": 9, "everi": 9, "intern": 9, "forc": 9, "recogn": 9, "part": 9, "standard": 9, "librari": 9, "third": 9, "parti": 9, "coupl": 9, "prefer": 9, "except": 9, "being": 9, "caught": 9, "baseexcept": 9, "pypyroject": 10, "toml": 10, "kei": 11, "featur": 11, "get": 11, "build": 11, "develop": 11, "precommit": 11, "datacard": 4}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.viewcode": 1, "nbsphinx": 4, "sphinx": 60}, "alltitles": {"Managing Access Requests": [[3, "Managing-Access-Requests"]], "Introduction": [[3, "Introduction"], [7, "Introduction"], [4, "Introduction"], [5, "Introduction"], [6, "Introduction"]], "Creating a new access request": [[3, "Creating-a-new-access-request"]], "Retrieving an access request": [[3, "Retrieving-an-access-request"]], "Using the .from_id() method": [[3, "Using-the-.from_id()-method"], [7, "Using-the-.from_id()-method"], [4, "Using-the-.from_id()-method"], [6, "Using-the-.from_id()-method"]], "Making changes to an access request": [[3, "Making-changes-to-an-access-request"]], "Deleting an access request": [[3, "Deleting-an-access-request"]], "Managing Schemas": [[7, "Managing-Schemas"]], "Creating a new schema": [[7, "Creating-a-new-schema"]], "Retrieving an existing schema": [[7, "Retrieving-an-existing-schema"]], "pre-commit-config.yaml": [[8, "pre-commit-config-yaml"]], "A comma-separated list of package or module names from where C extensions may": [[9, "a-comma-separated-list-of-package-or-module-names-from-where-c-extensions-may"]], "be loaded. Extensions are loading into the active Python interpreter and may": [[9, "be-loaded-extensions-are-loading-into-the-active-python-interpreter-and-may"]], "run arbitrary code.": [[9, "run-arbitrary-code"]], "Add files or directories to the blacklist. They should be base names, not": [[9, "add-files-or-directories-to-the-blacklist-they-should-be-base-names-not"]], "paths.": [[9, "paths"]], "Add files or directories matching the regex patterns to the blacklist. The": [[9, "add-files-or-directories-matching-the-regex-patterns-to-the-blacklist-the"]], "regex matches against base names, not paths.": [[9, "regex-matches-against-base-names-not-paths"]], "Python code to execute, usually for sys.path manipulation such as": [[9, "python-code-to-execute-usually-for-sys-path-manipulation-such-as"]], "pygtk.require().": [[9, "pygtk-require"]], "Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the": [[9, "use-multiple-processes-to-speed-up-pylint-specifying-0-will-auto-detect-the"]], "number of processors available to use.": [[9, "number-of-processors-available-to-use"]], "Control the amount of potential inferred values when inferring a single": [[9, "control-the-amount-of-potential-inferred-values-when-inferring-a-single"]], "object. This can help the performance when dealing with large functions or": [[9, "object-this-can-help-the-performance-when-dealing-with-large-functions-or"]], "complex, nested conditions.": [[9, "complex-nested-conditions"]], "List of plugins (as comma separated values of python module names) to load,": [[9, "list-of-plugins-as-comma-separated-values-of-python-module-names-to-load"]], "usually to register additional checkers.": [[9, "usually-to-register-additional-checkers"]], "Pickle collected data for later comparisons.": [[9, "pickle-collected-data-for-later-comparisons"]], "Specify a configuration file.": [[9, "specify-a-configuration-file"]], "When enabled, pylint would attempt to guess common misconfiguration and emit": [[9, "when-enabled-pylint-would-attempt-to-guess-common-misconfiguration-and-emit"]], "user-friendly hints instead of false-positive error messages.": [[9, "user-friendly-hints-instead-of-false-positive-error-messages"]], "Allow loading of arbitrary C extensions. Extensions are imported into the": [[9, "allow-loading-of-arbitrary-c-extensions-extensions-are-imported-into-the"]], "active Python interpreter and may run arbitrary code.": [[9, "active-python-interpreter-and-may-run-arbitrary-code"]], "Only show warnings with the listed confidence levels. Leave empty to show": [[9, "only-show-warnings-with-the-listed-confidence-levels-leave-empty-to-show"]], "all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.": [[9, "all-valid-levels-high-inference-inference-failure-undefined"]], "Disable the message, report, category or checker with the given id(s). You": [[9, "disable-the-message-report-category-or-checker-with-the-given-id-s-you"]], "can either give multiple identifiers separated by comma (,) or put this": [[9, "can-either-give-multiple-identifiers-separated-by-comma-or-put-this"]], "option multiple times (only on the command line, not in the configuration": [[9, "option-multiple-times-only-on-the-command-line-not-in-the-configuration"]], "file where it should appear only once). You can also use \u201c\u2013disable=all\u201d to": [[9, "file-where-it-should-appear-only-once-you-can-also-use-disable-all-to"]], "disable everything first and then reenable specific checks. For example, if": [[9, "disable-everything-first-and-then-reenable-specific-checks-for-example-if"]], "you want to run only the similarities checker, you can use \u201c\u2013disable=all": [[9, "you-want-to-run-only-the-similarities-checker-you-can-use-disable-all"]], "\u2013enable=similarities\u201d. If you want to run only the classes checker, but have": [[9, "enable-similarities-if-you-want-to-run-only-the-classes-checker-but-have"]], "no Warning level messages displayed, use \u201c\u2013disable=all \u2013enable=classes": [[9, "no-warning-level-messages-displayed-use-disable-all-enable-classes"]], "\u2013disable=W\u201d.": [[9, "disable-w"]], "Enable the message, report, category or checker with the given id(s). You can": [[9, "enable-the-message-report-category-or-checker-with-the-given-id-s-you-can"]], "either give multiple identifier separated by comma (,) or put this option": [[9, "either-give-multiple-identifier-separated-by-comma-or-put-this-option"]], "multiple time (only on the command line, not in the configuration file where": [[9, "multiple-time-only-on-the-command-line-not-in-the-configuration-file-where"]], "it should appear only once). See also the \u201c\u2013disable\u201d option for examples.": [[9, "it-should-appear-only-once-see-also-the-disable-option-for-examples"]], "Python expression which should return a score less than or equal to 10. You": [[9, "python-expression-which-should-return-a-score-less-than-or-equal-to-10-you"]], "have access to the variables \u2018error\u2019, \u2018warning\u2019, \u2018refactor\u2019, and \u2018convention\u2019": [[9, "have-access-to-the-variables-error-warning-refactor-and-convention"]], "which contain the number of messages in each category, as well as \u2018statement\u2019": [[9, "which-contain-the-number-of-messages-in-each-category-as-well-as-statement"]], "which is the total number of statements analyzed. This score is used by the": [[9, "which-is-the-total-number-of-statements-analyzed-this-score-is-used-by-the"]], "global evaluation report (RP0004).": [[9, "global-evaluation-report-rp0004"]], "Template used to display messages. This is a python new-style format string": [[9, "template-used-to-display-messages-this-is-a-python-new-style-format-string"]], "used to format the message information. See doc for all details.": [[9, "used-to-format-the-message-information-see-doc-for-all-details"]], "Set the output format. Available formats are text, parseable, colorized, json": [[9, "set-the-output-format-available-formats-are-text-parseable-colorized-json"]], "and msvs (visual studio). You can also give a reporter class, e.g.": [[9, "and-msvs-visual-studio-you-can-also-give-a-reporter-class-e-g"]], "mypackage.mymodule.MyReporterClass.": [[9, "mypackage-mymodule-myreporterclass"]], "Tells whether to display a full report or only the messages.": [[9, "tells-whether-to-display-a-full-report-or-only-the-messages"]], "Activate the evaluation score.": [[9, "activate-the-evaluation-score"]], "Maximum number of nested blocks for function / method body": [[9, "maximum-number-of-nested-blocks-for-function-method-body"]], "Complete name of functions that never returns. When checking for": [[9, "complete-name-of-functions-that-never-returns-when-checking-for"]], "inconsistent-return-statements if a never returning function is called then": [[9, "inconsistent-return-statements-if-a-never-returning-function-is-called-then"]], "it will be considered as an explicit return statement and no message will be": [[9, "it-will-be-considered-as-an-explicit-return-statement-and-no-message-will-be"]], "printed.": [[9, "printed"]], "Naming style matching correct argument names.": [[9, "naming-style-matching-correct-argument-names"]], "Regular expression matching correct argument names. Overrides argument-": [[9, "regular-expression-matching-correct-argument-names-overrides-argument"]], "naming-style.": [[9, "naming-style"], [9, "id3"], [9, "id6"]], "Naming style matching correct attribute names.": [[9, "naming-style-matching-correct-attribute-names"]], "Regular expression matching correct attribute names. Overrides attr-naming-": [[9, "regular-expression-matching-correct-attribute-names-overrides-attr-naming"]], "style.": [[9, "style"], [9, "id1"], [9, "id2"], [9, "id4"], [9, "id5"]], "Bad variable names which should always be refused, separated by a comma.": [[9, "bad-variable-names-which-should-always-be-refused-separated-by-a-comma"]], "Naming style matching correct class attribute names.": [[9, "naming-style-matching-correct-class-attribute-names"]], "Regular expression matching correct class attribute names. Overrides class-": [[9, "regular-expression-matching-correct-class-attribute-names-overrides-class"]], "attribute-naming-style.": [[9, "attribute-naming-style"]], "Naming style matching correct class names.": [[9, "naming-style-matching-correct-class-names"]], "Regular expression matching correct class names. Overrides class-naming-": [[9, "regular-expression-matching-correct-class-names-overrides-class-naming"]], "Naming style matching correct constant names.": [[9, "naming-style-matching-correct-constant-names"]], "Regular expression matching correct constant names. Overrides const-naming-": [[9, "regular-expression-matching-correct-constant-names-overrides-const-naming"]], "Minimum line length for functions/classes that require docstrings, shorter": [[9, "minimum-line-length-for-functions-classes-that-require-docstrings-shorter"]], "ones are exempt.": [[9, "ones-are-exempt"]], "Naming style matching correct function names.": [[9, "naming-style-matching-correct-function-names"]], "Regular expression matching correct function names. Overrides function-": [[9, "regular-expression-matching-correct-function-names-overrides-function"]], "Good variable names which should always be accepted, separated by a comma.": [[9, "good-variable-names-which-should-always-be-accepted-separated-by-a-comma"]], "Include a hint for the correct naming format with invalid-name.": [[9, "include-a-hint-for-the-correct-naming-format-with-invalid-name"]], "Naming style matching correct inline iteration names.": [[9, "naming-style-matching-correct-inline-iteration-names"]], "Regular expression matching correct inline iteration names. Overrides": [[9, "regular-expression-matching-correct-inline-iteration-names-overrides"]], "inlinevar-naming-style.": [[9, "inlinevar-naming-style"]], "Naming style matching correct method names.": [[9, "naming-style-matching-correct-method-names"]], "Regular expression matching correct method names. Overrides method-naming-": [[9, "regular-expression-matching-correct-method-names-overrides-method-naming"]], "Naming style matching correct module names.": [[9, "naming-style-matching-correct-module-names"]], "Regular expression matching correct module names. Overrides module-naming-": [[9, "regular-expression-matching-correct-module-names-overrides-module-naming"]], "Colon-delimited sets of names that determine each other\u2019s naming style when": [[9, "colon-delimited-sets-of-names-that-determine-each-other-s-naming-style-when"]], "the name regexes allow several styles.": [[9, "the-name-regexes-allow-several-styles"]], "Regular expression which should only match function or class names that do": [[9, "regular-expression-which-should-only-match-function-or-class-names-that-do"]], "not require a docstring.": [[9, "not-require-a-docstring"]], "List of decorators that produce properties, such as abc.abstractproperty. Add": [[9, "list-of-decorators-that-produce-properties-such-as-abc-abstractproperty-add"]], "to this list to register other decorators that produce valid properties.": [[9, "to-this-list-to-register-other-decorators-that-produce-valid-properties"]], "These decorators are taken in consideration only for invalid-name.": [[9, "these-decorators-are-taken-in-consideration-only-for-invalid-name"]], "Naming style matching correct variable names.": [[9, "naming-style-matching-correct-variable-names"]], "Regular expression matching correct variable names. Overrides variable-": [[9, "regular-expression-matching-correct-variable-names-overrides-variable"]], "Expected format of line ending, e.g. empty (any line ending), LF or CRLF.": [[9, "expected-format-of-line-ending-e-g-empty-any-line-ending-lf-or-crlf"]], "Regexp for a line that is allowed to be longer than the limit.": [[9, "regexp-for-a-line-that-is-allowed-to-be-longer-than-the-limit"]], "Number of spaces of indent required inside a hanging or continued line.": [[9, "number-of-spaces-of-indent-required-inside-a-hanging-or-continued-line"]], "String used as indentation unit. This is usually \u201c \u201c (4 spaces) or \u201c\\t\u201d (1": [[9, "string-used-as-indentation-unit-this-is-usually-4-spaces-or-t-1"]], "tab).": [[9, "tab"]], "Maximum number of characters on a single line.": [[9, "maximum-number-of-characters-on-a-single-line"]], "Maximum number of lines in a module.": [[9, "maximum-number-of-lines-in-a-module"]], "List of optional constructs for which whitespace checking is disabled. `dict-": [[9, "list-of-optional-constructs-for-which-whitespace-checking-is-disabled-dict"]], "separator` is used to allow tabulation in dicts, etc.: {1 : 1,\\n222: 2}.": [[9, "separator-is-used-to-allow-tabulation-in-dicts-etc-1-1-n222-2"]], "trailing-comma allows a space between comma and closing bracket: (a, ).": [[9, "trailing-comma-allows-a-space-between-comma-and-closing-bracket-a"]], "empty-line allows space-only lines.": [[9, "empty-line-allows-space-only-lines"]], "Allow the body of a class to be on the same line as the declaration if body": [[9, "allow-the-body-of-a-class-to-be-on-the-same-line-as-the-declaration-if-body"]], "contains single statement.": [[9, "contains-single-statement"]], "Allow the body of an if to be on the same line as the test if there is no": [[9, "allow-the-body-of-an-if-to-be-on-the-same-line-as-the-test-if-there-is-no"]], "else.": [[9, "else"]], "Format style used to check logging format string. old means using %": [[9, "format-style-used-to-check-logging-format-string-old-means-using"]], "formatting, new is for {} formatting,and fstr is for f-strings.": [[9, "formatting-new-is-for-formatting-and-fstr-is-for-f-strings"]], "Logging modules to check that the string format arguments are in logging": [[9, "logging-modules-to-check-that-the-string-format-arguments-are-in-logging"]], "function parameter format.": [[9, "function-parameter-format"]], "List of note tags to take in consideration, separated by a comma.": [[9, "list-of-note-tags-to-take-in-consideration-separated-by-a-comma"]], "Ignore comments when computing similarities.": [[9, "ignore-comments-when-computing-similarities"]], "Ignore docstrings when computing similarities.": [[9, "ignore-docstrings-when-computing-similarities"]], "Ignore imports when computing similarities.": [[9, "ignore-imports-when-computing-similarities"]], "Minimum lines number of a similarity.": [[9, "minimum-lines-number-of-a-similarity"]], "Limits count of emitted suggestions for spelling mistakes.": [[9, "limits-count-of-emitted-suggestions-for-spelling-mistakes"]], "Spelling dictionary name. Available dictionaries: none. To make it work,": [[9, "spelling-dictionary-name-available-dictionaries-none-to-make-it-work"]], "install the python-enchant package.": [[9, "install-the-python-enchant-package"]], "List of comma separated words that should not be checked.": [[9, "list-of-comma-separated-words-that-should-not-be-checked"]], "A path to a file that contains the private dictionary; one word per line.": [[9, "a-path-to-a-file-that-contains-the-private-dictionary-one-word-per-line"]], "Tells whether to store unknown words to the private dictionary (see the": [[9, "tells-whether-to-store-unknown-words-to-the-private-dictionary-see-the"]], "\u2013spelling-private-dict-file option) instead of raising a message.": [[9, "spelling-private-dict-file-option-instead-of-raising-a-message"]], "This flag controls whether the implicit-str-concat-in-sequence should": [[9, "this-flag-controls-whether-the-implicit-str-concat-in-sequence-should"]], "generate a warning on implicit string concatenation in sequences defined over": [[9, "generate-a-warning-on-implicit-string-concatenation-in-sequences-defined-over"]], "several lines.": [[9, "several-lines"]], "List of decorators that produce context managers, such as": [[9, "list-of-decorators-that-produce-context-managers-such-as"]], "contextlib.contextmanager. Add to this list to register other decorators that": [[9, "contextlib-contextmanager-add-to-this-list-to-register-other-decorators-that"]], "produce valid context managers.": [[9, "produce-valid-context-managers"]], "List of members which are set dynamically and missed by pylint inference": [[9, "list-of-members-which-are-set-dynamically-and-missed-by-pylint-inference"]], "system, and so shouldn\u2019t trigger E1101 when accessed. Python regular": [[9, "system-and-so-shouldn-t-trigger-e1101-when-accessed-python-regular"]], "expressions are accepted.": [[9, "expressions-are-accepted"]], "Tells whether missing members accessed in mixin class should be ignored. A": [[9, "tells-whether-missing-members-accessed-in-mixin-class-should-be-ignored-a"]], "mixin class is detected if its name ends with \u201cmixin\u201d (case insensitive).": [[9, "mixin-class-is-detected-if-its-name-ends-with-mixin-case-insensitive"]], "Tells whether to warn about missing members when the owner of the attribute": [[9, "tells-whether-to-warn-about-missing-members-when-the-owner-of-the-attribute"]], "is inferred to be None.": [[9, "is-inferred-to-be-none"]], "This flag controls whether pylint should warn about no-member and similar": [[9, "this-flag-controls-whether-pylint-should-warn-about-no-member-and-similar"]], "checks whenever an opaque object is returned when inferring. The inference": [[9, "checks-whenever-an-opaque-object-is-returned-when-inferring-the-inference"]], "can return multiple potential results while evaluating a Python object, but": [[9, "can-return-multiple-potential-results-while-evaluating-a-python-object-but"]], "some branches might not be evaluated, which results in partial inference. In": [[9, "some-branches-might-not-be-evaluated-which-results-in-partial-inference-in"]], "that case, it might be useful to still emit no-member and other checks for": [[9, "that-case-it-might-be-useful-to-still-emit-no-member-and-other-checks-for"]], "the rest of the inferred objects.": [[9, "the-rest-of-the-inferred-objects"]], "List of class names for which member attributes should not be checked (useful": [[9, "list-of-class-names-for-which-member-attributes-should-not-be-checked-useful"]], "for classes with dynamically set attributes). This supports the use of": [[9, "for-classes-with-dynamically-set-attributes-this-supports-the-use-of"]], "qualified names.": [[9, "qualified-names"]], "List of module names for which member attributes should not be checked": [[9, "list-of-module-names-for-which-member-attributes-should-not-be-checked"]], "(useful for modules/projects where namespaces are manipulated during runtime": [[9, "useful-for-modules-projects-where-namespaces-are-manipulated-during-runtime"]], "and thus existing member attributes cannot be deduced by static analysis). It": [[9, "and-thus-existing-member-attributes-cannot-be-deduced-by-static-analysis-it"]], "supports qualified module names, as well as Unix pattern matching.": [[9, "supports-qualified-module-names-as-well-as-unix-pattern-matching"]], "Show a hint with possible names when a member name was not found. The aspect": [[9, "show-a-hint-with-possible-names-when-a-member-name-was-not-found-the-aspect"]], "of finding the hint is based on edit distance.": [[9, "of-finding-the-hint-is-based-on-edit-distance"]], "The minimum edit distance a name should have in order to be considered a": [[9, "the-minimum-edit-distance-a-name-should-have-in-order-to-be-considered-a"]], "similar match for a missing member name.": [[9, "similar-match-for-a-missing-member-name"]], "The total number of similar names that should be taken in consideration when": [[9, "the-total-number-of-similar-names-that-should-be-taken-in-consideration-when"]], "showing a hint for a missing member.": [[9, "showing-a-hint-for-a-missing-member"]], "List of decorators that change the signature of a decorated function.": [[9, "list-of-decorators-that-change-the-signature-of-a-decorated-function"]], "List of additional names supposed to be defined in builtins. Remember that": [[9, "list-of-additional-names-supposed-to-be-defined-in-builtins-remember-that"]], "you should avoid defining new builtins when possible.": [[9, "you-should-avoid-defining-new-builtins-when-possible"]], "Tells whether unused global variables should be treated as a violation.": [[9, "tells-whether-unused-global-variables-should-be-treated-as-a-violation"]], "List of strings which can identify a callback function by name. A callback": [[9, "list-of-strings-which-can-identify-a-callback-function-by-name-a-callback"]], "name must start or end with one of those strings.": [[9, "name-must-start-or-end-with-one-of-those-strings"]], "A regular expression matching the name of dummy variables (i.e. expected to": [[9, "a-regular-expression-matching-the-name-of-dummy-variables-i-e-expected-to"]], "not be used).": [[9, "not-be-used"]], "Argument names that match this expression will be ignored. Default to name": [[9, "argument-names-that-match-this-expression-will-be-ignored-default-to-name"]], "with leading underscore.": [[9, "with-leading-underscore"]], "Tells whether we should check for unused import in init files.": [[9, "tells-whether-we-should-check-for-unused-import-in-init-files"]], "List of qualified module names which can have objects that can redefine": [[9, "list-of-qualified-module-names-which-can-have-objects-that-can-redefine"]], "builtins.": [[9, "builtins"]], "List of method names used to declare (i.e. assign) instance attributes.": [[9, "list-of-method-names-used-to-declare-i-e-assign-instance-attributes"]], "List of member names, which should be excluded from the protected access": [[9, "list-of-member-names-which-should-be-excluded-from-the-protected-access"]], "warning.": [[9, "warning"]], "List of valid names for the first argument in a class method.": [[9, "list-of-valid-names-for-the-first-argument-in-a-class-method"]], "List of valid names for the first argument in a metaclass class method.": [[9, "list-of-valid-names-for-the-first-argument-in-a-metaclass-class-method"]], "Maximum number of arguments for function / method.": [[9, "maximum-number-of-arguments-for-function-method"]], "Maximum number of attributes for a class (see R0902).": [[9, "maximum-number-of-attributes-for-a-class-see-r0902"]], "Maximum number of boolean expressions in an if statement (see R0916).": [[9, "maximum-number-of-boolean-expressions-in-an-if-statement-see-r0916"]], "Maximum number of branch for function / method body.": [[9, "maximum-number-of-branch-for-function-method-body"]], "Maximum number of locals for function / method body.": [[9, "maximum-number-of-locals-for-function-method-body"]], "Maximum number of parents for a class (see R0901).": [[9, "maximum-number-of-parents-for-a-class-see-r0901"]], "Maximum number of public methods for a class (see R0904).": [[9, "maximum-number-of-public-methods-for-a-class-see-r0904"]], "Maximum number of return / yield for function / method body.": [[9, "maximum-number-of-return-yield-for-function-method-body"]], "Maximum number of statements in function / method body.": [[9, "maximum-number-of-statements-in-function-method-body"]], "Minimum number of public methods for a class (see R0903).": [[9, "minimum-number-of-public-methods-for-a-class-see-r0903"]], "List of modules that can be imported at any level, not just the top level": [[9, "list-of-modules-that-can-be-imported-at-any-level-not-just-the-top-level"]], "one.": [[9, "one"]], "Allow wildcard imports from modules that define all.": [[9, "allow-wildcard-imports-from-modules-that-define-all"]], "Analyse import fallback blocks. This can be used to support both Python 2 and": [[9, "analyse-import-fallback-blocks-this-can-be-used-to-support-both-python-2-and"]], "3 compatible code, which means that the block might have code that exists": [[9, "compatible-code-which-means-that-the-block-might-have-code-that-exists"]], "only in one or another interpreter, leading to false positives when analysed.": [[9, "only-in-one-or-another-interpreter-leading-to-false-positives-when-analysed"]], "Deprecated modules which should not be used, separated by a comma.": [[9, "deprecated-modules-which-should-not-be-used-separated-by-a-comma"]], "Create a graph of external dependencies in the given file (report RP0402 must": [[9, "create-a-graph-of-external-dependencies-in-the-given-file-report-rp0402-must"]], "not be disabled).": [[9, "not-be-disabled"], [9, "id7"]], "Create a graph of every (i.e. internal and external) dependencies in the": [[9, "create-a-graph-of-every-i-e-internal-and-external-dependencies-in-the"]], "given file (report RP0402 must not be disabled).": [[9, "given-file-report-rp0402-must-not-be-disabled"]], "Create a graph of internal dependencies in the given file (report RP0402 must": [[9, "create-a-graph-of-internal-dependencies-in-the-given-file-report-rp0402-must"]], "Force import order to recognize a module as part of the standard": [[9, "force-import-order-to-recognize-a-module-as-part-of-the-standard"]], "compatibility libraries.": [[9, "compatibility-libraries"]], "Force import order to recognize a module as part of a third party library.": [[9, "force-import-order-to-recognize-a-module-as-part-of-a-third-party-library"]], "Couples of modules and preferred modules, separated by a comma.": [[9, "couples-of-modules-and-preferred-modules-separated-by-a-comma"]], "Exceptions that will emit a warning when being caught. Defaults to": [[9, "exceptions-that-will-emit-a-warning-when-being-caught-defaults-to"]], "\u201cBaseException, Exception\u201d.": [[9, "baseexception-exception"]], "pypyroject.toml": [[10, "pypyroject-toml"]], "Bailo Python Client": [[11, "bailo-python-client"], [2, "bailo-python-client"]], "Key Features": [[11, "key-features"]], "Installing": [[11, "installing"]], "Getting Started": [[11, "getting-started"]], "Documentation": [[11, "documentation"]], "Building locally": [[11, "building-locally"]], "Development": [[11, "development"]], "Install and add precommit": [[11, "install-and-add-precommit"]], "Install the package locally": [[11, "install-the-package-locally"]], "Testing": [[11, "testing"]], "bailo.core package": [[0, "bailo-core-package"]], "Welcome to Bailo\u2019s Python Client documentation!": [[2, "module-bailo"]], "Packages:": [[2, null]], "Notebooks:": [[2, null]], "Managing Datacards": [[4, "Managing-Datacards"]], "Creating a new datacard in Bailo": [[4, "Creating-a-new-datacard-in-Bailo"]], "Creating and updating the base datacard": [[4, "Creating-and-updating-the-base-datacard"]], "Populating the datacard": [[4, "Populating-the-datacard"]], "Retrieving an existing datacard": [[4, "Retrieving-an-existing-datacard"]], "Experiment Tracking with Bailo & MLFlow": [[5, "Experiment-Tracking-with-Bailo-&-MLFlow"]], "Connecting with Bailo": [[5, "Connecting-with-Bailo"]], "Setting up MLFlow Tracking": [[5, "Setting-up-MLFlow-Tracking"]], "Preparing a custom schema for tracking": [[5, "Preparing-a-custom-schema-for-tracking"]], "Creating a new experiment": [[5, "Creating-a-new-experiment"]], "Conducting experiment runs": [[5, "Conducting-experiment-runs"]], "Running an experiment with the Bailo python client": [[5, "Running-an-experiment-with-the-Bailo-python-client"]], "Creating a dummy MLFlow experiment run": [[5, "Creating-a-dummy-MLFlow-experiment-run"]], "Importing existing experiments from MLFlow into Bailo": [[5, "Importing-existing-experiments-from-MLFlow-into-Bailo"]], "Publishing results to Bailo": [[5, "Publishing-results-to-Bailo"]], "Managing Models & Releases (ResNet-50 Example with PyTorch)": [[6, "Managing-Models-&-Releases-(ResNet-50-Example-with-PyTorch)"]], "Creating a new ResNet-50 model in Bailo": [[6, "Creating-a-new-ResNet-50-model-in-Bailo"]], "Creating and updating the base model": [[6, "Creating-and-updating-the-base-model"]], "Creating and populating a model card": [[6, "Creating-and-populating-a-model-card"]], "Retrieving an existing model": [[6, "Retrieving-an-existing-model"]], "Creating and managing releases for models": [[6, "Creating-and-managing-releases-for-models"]], "Creating a release": [[6, "Creating-a-release"]], "Preparing the model weights using PyTorch": [[6, "Preparing-the-model-weights-using-PyTorch"]], "Uploading weights to the release": [[6, "Uploading-weights-to-the-release"]], "Retrieving a release": [[6, "Retrieving-a-release"]], "Downloading weights from the release": [[6, "Downloading-weights-from-the-release"]], "Loading the model using PyTorch": [[6, "Loading-the-model-using-PyTorch"]], "bailo.helper package": [[1, "module-bailo.helper.access_request"]]}, "indexentries": {"accessrequest (class in bailo.helper.access_request)": [[1, "bailo.helper.access_request.AccessRequest"]], "datacard (class in bailo.helper.datacard)": [[1, "bailo.helper.datacard.Datacard"]], "entry (class in bailo.helper.entry)": [[1, "bailo.helper.entry.Entry"]], "experiment (class in bailo.helper.model)": [[1, "bailo.helper.model.Experiment"]], "model (class in bailo.helper.model)": [[1, "bailo.helper.model.Model"]], "release (class in bailo.helper.release)": [[1, "bailo.helper.release.Release"]], "schema (class in bailo.helper.schema)": [[1, "bailo.helper.schema.Schema"]], "__init__() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.__init__"]], "bailo.helper.access_request": [[1, "module-bailo.helper.access_request"]], "bailo.helper.datacard": [[1, "module-bailo.helper.datacard"]], "bailo.helper.entry": [[1, "module-bailo.helper.entry"]], "bailo.helper.model": [[1, "module-bailo.helper.model"]], "bailo.helper.release": [[1, "module-bailo.helper.release"]], "bailo.helper.schema": [[1, "module-bailo.helper.schema"]], "card_from_schema() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.card_from_schema"]], "card_from_template() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.card_from_template"]], "create() (bailo.helper.access_request.accessrequest class method)": [[1, "bailo.helper.access_request.AccessRequest.create"]], "create() (bailo.helper.datacard.datacard class method)": [[1, "bailo.helper.datacard.Datacard.create"]], "create() (bailo.helper.model.experiment class method)": [[1, "bailo.helper.model.Experiment.create"]], "create() (bailo.helper.model.model class method)": [[1, "bailo.helper.model.Model.create"]], "create() (bailo.helper.release.release class method)": [[1, "bailo.helper.release.Release.create"]], "create() (bailo.helper.schema.schema class method)": [[1, "bailo.helper.schema.Schema.create"]], "create_experiment() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.create_experiment"]], "create_release() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.create_release"]], "data_card (bailo.helper.datacard.datacard property)": [[1, "bailo.helper.datacard.Datacard.data_card"]], "data_card_schema (bailo.helper.datacard.datacard property)": [[1, "bailo.helper.datacard.Datacard.data_card_schema"]], "data_card_version (bailo.helper.datacard.datacard property)": [[1, "bailo.helper.datacard.Datacard.data_card_version"]], "delete() (bailo.helper.access_request.accessrequest method)": [[1, "bailo.helper.access_request.AccessRequest.delete"]], "delete() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.delete"]], "download() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.download"]], "download_all() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.download_all"]], "from_id() (bailo.helper.access_request.accessrequest class method)": [[1, "bailo.helper.access_request.AccessRequest.from_id"]], "from_id() (bailo.helper.datacard.datacard class method)": [[1, "bailo.helper.datacard.Datacard.from_id"]], "from_id() (bailo.helper.model.model class method)": [[1, "bailo.helper.model.Model.from_id"]], "from_id() (bailo.helper.schema.schema class method)": [[1, "bailo.helper.schema.Schema.from_id"]], "from_mlflow() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.from_mlflow"]], "from_version() (bailo.helper.release.release class method)": [[1, "bailo.helper.release.Release.from_version"]], "get_card_latest() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.get_card_latest"]], "get_card_revision() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.get_card_revision"]], "get_image() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_image"]], "get_images() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_images"]], "get_latest_release() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_latest_release"]], "get_release() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_release"]], "get_releases() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_releases"]], "get_roles() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.get_roles"]], "get_user_roles() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.get_user_roles"]], "log_artifacts() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.log_artifacts"]], "log_dataset() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.log_dataset"]], "log_metrics() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.log_metrics"]], "log_params() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.log_params"]], "model_card (bailo.helper.model.model property)": [[1, "bailo.helper.model.Model.model_card"]], "model_card_schema (bailo.helper.model.model property)": [[1, "bailo.helper.model.Model.model_card_schema"]], "model_card_version (bailo.helper.model.model property)": [[1, "bailo.helper.model.Model.model_card_version"]], "module": [[1, "module-bailo.helper.access_request"], [1, "module-bailo.helper.datacard"], [1, "module-bailo.helper.entry"], [1, "module-bailo.helper.model"], [1, "module-bailo.helper.release"], [1, "module-bailo.helper.schema"], [2, "module-bailo"]], "publish() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.publish"]], "start_run() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.start_run"]], "update() (bailo.helper.access_request.accessrequest method)": [[1, "bailo.helper.access_request.AccessRequest.update"]], "update() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.update"]], "update() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.update"]], "update_data_card() (bailo.helper.datacard.datacard method)": [[1, "bailo.helper.datacard.Datacard.update_data_card"]], "update_model_card() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.update_model_card"]], "upload() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.upload"]], "bailo": [[2, "module-bailo"]]}}) \ No newline at end of file +Search.setIndex({"docnames": ["bailo.core", "bailo.helper", "index", "notebooks/access_requests_demo", "notebooks/datacards_demo", "notebooks/experiment_tracking_demo", "notebooks/models_and_releases_demo_pytorch", "notebooks/schemas_demo", "pre-commit-config", "pylint", "pyproject", "readme_link"], "filenames": ["bailo.core.rst", "bailo.helper.rst", "index.rst", "notebooks/access_requests_demo.ipynb", "notebooks/datacards_demo.ipynb", "notebooks/experiment_tracking_demo.ipynb", "notebooks/models_and_releases_demo_pytorch.ipynb", "notebooks/schemas_demo.ipynb", "pre-commit-config.md", "pylint.md", "pyproject.md", "readme_link.md"], "titles": ["bailo.core package", "bailo.helper package", "Welcome to Bailo\u2019s Python Client documentation!", "Managing Access Requests", "Managing Datacards", "Experiment Tracking with Bailo & MLFlow", "Managing Models & Releases (ResNet-50 Example with PyTorch)", "Managing Schemas", "pre-commit-config.yaml", "A comma-separated list of package or module names from where C extensions may", "pypyroject.toml", "Bailo Python Client"], "terms": {"The": [0, 1, 3, 4, 5, 6, 7, 8, 10, 11], "contain": [0, 5, 6, 10], "suppport": 0, "one": [0, 5, 6], "endpoint": [0, 3, 4, 6, 7], "It": [0, 10], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11], "recommend": 0, "us": [0, 1, 5, 8, 10, 11], "helper": [0, 2, 3, 4, 6, 7], "most": [0, 5], "class": [0, 1, 3, 4, 5, 6, 7], "agent": [0, 2, 3, 4, 6, 7], "sourc": [0, 1], "base": [0, 1], "object": [0, 1, 3, 4, 5, 6, 7], "api": [0, 11], "talk": 0, "wrap": 0, "each": [0, 4, 6], "request": [0, 1, 2], "an": [0, 1], "except": 0, "handler": 0, "map": 0, "error": [0, 1, 4, 6], "python": [0, 1, 3, 4, 6, 7, 8, 10], "among": 0, "statu": 0, "code": [0, 1, 6, 8], "less": 0, "than": 0, "400": 0, "default": [0, 1, 3, 4, 6, 7, 11], "timeout": [], "5": [1, 5, 7, 9], "second": [], "delet": [0, 1], "arg": [0, 9], "kwarg": 0, "get": [0, 1, 2], "patch": 0, "post": [0, 1], "push": 0, "put": 0, "pkiagent": [0, 2, 3, 4, 6, 7], "cert": [0, 3, 4, 6, 7], "str": [0, 1, 5], "kei": [0, 2, 3, 4, 6, 7], "auth": [0, 3, 4, 6, 7], "__init__": [0, 1], "initi": [0, 6], "pki": [0, 3, 4, 6, 7], "authent": [0, 3, 4, 6, 7], "paramet": [0, 1, 3, 4, 5, 6, 7], "path": [0, 1, 6], "file": [0, 1, 6, 10, 11], "certif": 0, "author": 0, "tokenag": [0, 2], "access_kei": 0, "secret_kei": 0, "token": 0, "access": [0, 1, 2, 5], "secret": 0, "client": [0, 1, 3, 4, 6, 7], "url": [0, 3, 4, 5, 6, 7], "creat": [0, 1, 8, 11], "can": [0, 1, 3, 4, 5, 6, 7, 8, 11], "websit": 0, "handl": [0, 3, 4, 6, 7], "delete_access_request": 0, "model_id": [0, 1, 3, 6], "access_request_id": [0, 1, 3], "specif": [0, 1, 4, 6], "associ": 0, "model": [0, 1, 2, 3, 4, 5, 7, 11], "uniqu": [0, 1, 7], "id": [0, 1, 5], "return": [0, 1, 6, 7], "json": [0, 1, 6, 7], "respons": [0, 1], "delete_fil": 0, "file_id": 0, "delete_releas": 0, "release_vers": 0, "releas": [0, 1, 2, 4, 5, 11], "version": [0, 1, 4, 6, 11], "get_access_request": 0, "retriev": [0, 1], "given": [0, 1, 11], "its": 0, "all": [0, 1, 6, 11], "get_all_imag": 0, "imag": [0, 1, 4, 6], "A": [0, 1, 3, 4, 5, 6, 7, 11], "get_all_releas": 0, "get_all_schema": 0, "kind": [0, 1, 5, 7], "schemakind": [0, 1, 2, 5, 7], "none": [0, 1], "schema": [0, 1, 2, 4, 6], "enum": [0, 1], "defin": [0, 1, 5], "e": [0, 1, 3, 4, 5, 6, 7, 11], "g": [0, 1, 3, 4, 5, 6, 7], "accessrequest": [0, 1, 2, 3], "get_all_team": 0, "team": [0, 1], "get_download_by_filenam": 0, "semver": [0, 1], "filenam": [0, 1, 6], "download": [0, 1, 11], "try": 0, "from": [0, 1, 3, 4, 7, 8, 11], "get_download_fil": 0, "": [0, 1], "get_fil": 0, "get_model": 0, "get_model_card": 0, "card": [0, 1, 4, 5], "get_model_rol": 0, "role": [0, 1, 2], "get_model_user_rol": 0, "current": [0, 1, 10], "user": [0, 1, 3, 8], "task": [0, 1, 6], "librari": [0, 1, 6], "list": [0, 1, 6], "filter": [0, 1, 6], "search": [0, 1], "find": [0, 7], "provid": [0, 1, 2, 5, 6], "term": 0, "classif": [0, 1, 6], "tensorflow": [0, 1], "custom": [0, 1, 4, 6], "string": [0, 1, 5, 6, 7], "locat": [0, 1, 5], "get_releas": [0, 1, 6], "get_review": 0, "activ": 0, "bool": [0, 1, 9], "review": [0, 1], "within": [0, 1, 2, 3, 4, 5, 6, 7, 11], "boolean": 0, "repres": [0, 1, 6], "get_schema": 0, "schema_id": [0, 1, 3, 4, 5, 6, 7], "get_team": 0, "team_id": [0, 1, 3, 4, 5, 6, 11], "get_user_team": 0, "model_card_from_schema": 0, "patch_access_request": 0, "metadata": [0, 1, 3], "ani": [0, 1, 3, 4, 5, 6, 7], "updat": [0, 1, 3], "patch_model": 0, "name": [0, 1, 3, 4, 5, 6, 7, 11], "descript": [0, 1, 3, 4, 5, 6, 7, 11], "visibl": [0, 1, 4, 6], "public": [0, 1], "privat": [0, 1], "patch_team": 0, "post_access_request": 0, "post_model": 0, "modelvis": [0, 1, 2], "post_releas": 0, "note": [0, 1, 4, 5, 6, 7, 11], "model_card_vers": [0, 1, 6], "int": [0, 1, 9], "minor": [0, 1, 6], "fals": [0, 1, 7], "draft": [0, 1, 7], "new": [0, 1, 11], "signifi": 0, "post_review": 0, "decis": 0, "comment": 0, "semant": [0, 1], "make": [0, 1, 4, 6, 11], "either": [0, 1, 4, 6, 11], "approv": 0, "chang": [0, 1, 4, 6], "go": 0, "post_schema": 0, "json_schema": [0, 1, 5, 7], "dict": [0, 1], "post_team": 0, "put_model_card": 0, "latest": [0, 1, 4, 6], "put_releas": 0, "simple_upload": 0, "buffer": 0, "bytesio": [0, 1, 6], "simpl": [0, 11], "upload": [0, 1, 11], "valu": [0, 1], "whether": [0, 1], "publicli": 0, "model_senior_responsible_offic": 0, "msro": 0, "model_technical_review": 0, "mtr": 0, "owner": 0, "type": [0, 1, 6, 7], "access_request": [0, 1, 3], "bailoexcept": [0, 1, 2], "gener": [0, 1, 3, 4, 6, 7, 8, 11], "responseexcept": [0, 2], "gave": 0, "created_bi": 1, "being": 1, "made": 1, "thi": [1, 2, 3, 4, 5, 6, 7, 10, 11], "ha": [1, 4], "been": [1, 4, 5], "classmethod": [1, 3, 4, 6, 7, 9], "interact": [1, 2, 3, 4, 6, 7], "messag": [1, 6], "confirm": 1, "remov": 1, "from_id": 1, "exist": [1, 3], "state": 1, "experi": [1, 2], "local": [1, 3, 4, 5, 6, 7], "which": [1, 3, 4, 5, 6, 7, 8], "run": [1, 3, 4, 6, 7, 11], "raw": 1, "inform": [1, 3, 4, 6, 7], "about": 1, "create_experi": [1, 5], "x": [1, 5], "rang": [1, 5], "start_run": [1, 5], "log_param": [1, 5], "lr": [1, 5], "0": [1, 3, 4, 5, 6, 7, 11], "01": [1, 3, 5], "insert": [1, 3, 4, 5, 6, 7], "train": [1, 5], "here": [1, 11], "log_metr": [1, 5], "accuraci": [1, 5], "86": [1, 5], "log_artifact": [1, 5], "weight": [1, 5], "pth": [1, 6], "publish": [1, 10], "mc_loc": [1, 5], "perform": [1, 5, 8], "performancemetr": [1, 5], "run_id": [1, 5], "1": [1, 3, 4, 5, 6, 7, 11], "from_mlflow": [1, 5], "tracking_uri": [1, 5], "experiment_id": [1, 5], "import": [1, 3, 4, 6, 7, 11], "mlflow": [1, 2], "track": [1, 2], "server": [1, 5], "uri": [1, 5], "rais": 1, "importerror": 1, "instal": [1, 2, 5, 6], "artifact": [1, 5], "log": [1, 5], "log_dataset": 1, "dataset": [1, 4], "arbitrari": [1, 5], "titl": [1, 7], "metric": [1, 5], "dictionari": 1, "param": [1, 5], "result": 1, "select": [1, 5, 6], "present": 1, "next": [1, 4, 5, 6], "depend": [1, 5, 8], "is_mlflow": 1, "start": [1, 2], "mark": 1, "card_from_model": [], "copi": [], "differ": 6, "yet": 1, "implement": 1, "notimplementederror": 1, "Not": 1, "card_from_schema": [1, 4, 5, 6, 11], "card_from_templ": 1, "templat": 1, "build": [1, 8, 10], "create_releas": [1, 6, 11], "true": [0, 1, 7], "call": [1, 3, 4, 6], "method": [1, 5], "get_card_latest": 1, "get_card_revis": 1, "revis": 1, "get_imag": 1, "refer": [1, 6], "get_latest_releas": [1, 6], "from_vers": 1, "get_rol": 1, "get_user_rol": 1, "summari": [1, 7], "update_model_card": [1, 5, 6], "model_card": [1, 5, 6], "If": [1, 4, 5, 6, 11], "attribut": [1, 3, 4, 6], "option": [1, 10], "ar": [1, 3, 4, 5, 6, 7, 8, 10, 11], "store": 1, "write": [1, 6], "give": [], "read": [], "determin": 1, "disk": [1, 6], "set": [1, 4, 6], "data": [0, 1, 4], "directori": [1, 6, 11], "load": 1, "zip": 1, "ecosystem": 2, "manag": 2, "lifecycl": [2, 5], "machin": [2, 5], "learn": [2, 4, 5, 6], "support": [1, 2, 3, 4, 5, 6, 7], "featur": 2, "develop": 2, "core": [2, 3, 4, 5, 6, 7], "resnet": 2, "50": [2, 9], "exampl": [2, 3, 4, 5, 7, 10], "pytorch": 2, "bailo": [3, 7], "enabl": [3, 4, 6, 7], "intuit": [3, 4, 6, 7], "servic": [3, 4, 5, 6, 7], "environ": [3, 4, 5, 6, 7], "notebook": [3, 4, 5, 6, 7], "through": [3, 4, 5, 6, 7], "follow": [3, 4, 5, 6, 7, 11], "concept": [3, 4, 5, 6, 7], "prerequisit": [3, 4, 5, 6, 7], "3": [3, 4, 5, 6, 7, 11], "8": [3, 4, 5, 6, 7, 9, 11], "higher": [3, 4, 5, 6, 7, 11], "includ": [1, 3, 4, 5, 6, 7, 8, 10], "demo": [3, 4, 5, 6, 7], "remot": [3, 4, 5, 6, 7], "see": [3, 4, 5, 6, 7], "http": [3, 4, 5, 6, 7, 9, 11], "github": [3, 4, 5, 6, 7], "com": [3, 4, 5, 6, 7], "gchq": [3, 4, 5, 6, 7], "split": [3, 4, 6, 7, 11], "two": [3, 4, 6, 7], "sub": [3, 4, 6, 7], "packag": [3, 4, 6, 7, 8, 10], "For": [3, 4, 6, 7], "direct": [3, 4, 6, 7], "more": [3, 4, 5, 6, 7], "oper": [3, 4, 6, 7], "In": [3, 4, 5, 6, 7, 8, 11], "order": [3, 4, 5, 6, 7, 11], "you": [3, 4, 5, 6, 7, 11], "first": [3, 4, 5, 6, 7], "need": [3, 4, 5, 6, 7], "instanti": [3, 4, 5, 6, 7], "By": [3, 4, 6, 7], "howev": [3, 4, 6, 7], "also": [3, 4, 5, 6, 7, 10], "pass": [3, 4, 5, 6, 7], "when": [1, 3, 4, 6, 7, 10], "necessari": [3, 4, 5, 6, 7], "statement": [1, 3, 4, 5, 6, 7], "127": [3, 4, 5, 6, 7], "8080": [3, 4, 5, 6, 7, 11], "host": [3, 4, 5, 6, 7], "section": [3, 4, 5, 6, 7, 11], "we": [3, 4, 5, 6, 7], "ll": [3, 4, 5, 6, 7], "On": [3, 4, 6, 7], "must": [1, 3, 4, 5, 6, 7], "consist": [3, 4, 6, 7], "least": [3, 4, 6], "upon": [3, 4, 6, 7], "creation": [3, 4, 6, 7], "These": [3, 4, 6, 7, 8], "below": [3, 4, 5, 6, 7], "befor": [3, 4, 5, 6, 7], "our": [3, 4, 5, 6, 7], "yolov5": [3, 5], "detect": [3, 5], "uncategoris": [3, 4, 5, 6, 11], "overview": [3, 4, 5, 6, 7], "entiti": 3, "test": [3, 7, 10], "enddat": 3, "1970": 3, "minim": [0, 1, 3, 4, 6, 11], "v10": [0, 1, 3, 4, 6, 11], "previou": [3, 4, 5, 6, 7], "your": [3, 4, 5, 6, 7], "edit": 3, "directli": [3, 5, 6], "demonstr": [3, 5, 6], "new_metadata": 3, "newnam": 3, "simpli": 3, "addit": [5, 6], "cover": 5, "offer": 5, "integr": [5, 6, 11], "might": 5, "wider": 5, "particular": 5, "complet": 5, "basic": [5, 9], "models_and_releases_demo_pytorch": 5, "ipynb": 5, "step": [5, 6], "have": [4, 5, 6], "thu": 5, "too": [4, 5, 6, 7], "how": [4, 5, 6], "do": [5, 6, 7], "time": [4, 5, 6], "later": [4, 5, 6], "pip": [5, 6, 11], "random": [5, 7], "element": 5, "tutori": 5, "instanc": [4, 5, 6, 7], "sampl": 5, "actual": [4, 5], "onli": [1, 5, 6, 8, 10, 11], "function": [5, 7], "ui": 5, "command": [5, 6], "line": 5, "typic": [5, 7], "localhost": [5, 11], "5000": [5, 7], "browser": 5, "design": [5, 9], "displai": [5, 6], "wai": 5, "therefor": 5, "extern": 5, "script": 5, "quit": 5, "larg": 5, "set_schema": 5, "py": [5, 9, 10], "assign": [1, 4, 5, 6], "randint": 5, "1000000": 5, "mandatori": 5, "field": 5, "new_card": [4, 5, 6], "tag": [5, 6, 7], "modelsummari": [5, 6], "work": [5, 11], "sequenti": 5, "so": 5, "re": [5, 6], "parallel": 5, "would": [5, 7], "better": 5, "anchor_t": 5, "4": [4, 5, 6], "scale": 5, "98": 5, "txt": [5, 6], "2": [4, 5, 6], "set_tracking_uri": 5, "set_experi": 5, "demonst": 5, "same": [1, 5, 6], "set_tag": 5, "info": 5, "As": 5, "previous": 5, "mention": 5, "experiment_mlflow": 5, "BE": 5, "found": [5, 6], "ON": 5, "THE": 5, "becaus": 5, "intend": 5, "success": [4, 5, 6], "specifi": [1, 5], "well": 5, "case": [5, 6], "per": 5, "earlier": [5, 6], "should": [4, 5, 6], "now": [4, 5, 6], "under": 5, "tab": 5, "addition": 5, "relev": 6, "linux": 6, "cpu": 6, "torch": [6, 9], "torchvis": 6, "index": 6, "org": [6, 7], "whl": 6, "mac": 6, "window": [6, 11], "resnet50": 6, "resnet50_weight": 6, "other": [6, 7, 11], "like": [4, 6], "ad": 6, "backend": [4, 6, 11], "mai": [4, 6, 10, 11], "relai": [4, 6], "empti": [4, 6], "beta": 11, "out": [4, 6], "scope": [4, 6], "print": [4, 6], "f": [4, 6, 11], "abov": [4, 5, 6], "want": [4, 6], "match": [4, 6], "otherwis": [1, 4, 6], "thrown": [4, 6], "adjust": 6, "don": 6, "t": 6, "drastic": 6, "behaviour": 6, "separ": 6, "itself": 6, "release_on": 6, "save": 6, "them": 6, "take": 6, "allow": 6, "u": 6, "without": 6, "up": 6, "space": 6, "torch_model": 6, "state_dict": 6, "To": [5, 6], "content": [6, 11], "last": 6, "s3": [4, 6], "large_fil": [], "open": 11, "rb": [], "altern": 6, "both": [5, 6, 10], "release_latest": 6, "successfulli": 6, "ident": 6, "similarli": 6, "bailo_resnet50_weight": 6, "wb": [], "final": 6, "ve": 6, "load_state_dict": 6, "init": 6, "identifi": 7, "suffic": 7, "reserv": 7, "administr": 7, "def": 7, "random_gener": 7, "n": [7, 9], "10": 7, "join": 7, "choic": [7, 9], "ascii_uppercas": 7, "digit": 7, "k": [7, 9], "07": 7, "properti": [1, 7], "modeloverview": 7, "what": [5, 7], "doe": 7, "minlength": 7, "maxlength": 7, "searchabl": 7, "help": [7, 8], "arrai": 7, "widget": 7, "tagselectorbeta": 7, "item": 7, "uniqueitem": 7, "requir": [1, 5, 7, 10, 11], "additionalproperti": 7, "git": [1, 8, 11], "hook": [8, 9], "scan": 8, "prior": 8, "checkin": 8, "configur": [8, 10], "focus": 8, "action": 8, "prevent": 8, "fail": 8, "dure": 8, "format": 8, "automat": 8, "auto": 8, "black": 8, "sort": 8, "isort": 8, "lint": [8, 10], "left": 8, "discret": 8, "master": 9, "pkg": 9, "whitelist": 9, "numpi": 9, "cv2": 9, "pyodbc": 9, "pydant": 9, "ciso8601": 9, "netcdf4": 9, "scipi": 9, "cv": 9, "conftest": 9, "setrecursionlimit": 9, "getrecursionlimit": 9, "job": 9, "100": 9, "persist": 9, "ye": 9, "rcfile": 9, "mode": 9, "unsaf": 9, "float": 9, "_": 9, "msg": 9, "max": [1, 5, 9], "exit": 9, "snake_cas": 9, "rgx": 9, "foo": 9, "bar": 9, "baz": 9, "toto": 9, "tutu": 9, "tata": 9, "pascalcas": 9, "upper_cas": 9, "min": [1, 5, 9], "j": 9, "ex": 9, "df": 9, "ax": 9, "group": 9, "long": 9, "after": 9, "paren": 9, "120": 9, "1000": 9, "stmt": 9, "miscellan": 9, "fixm": 9, "xxx": 9, "todo": 9, "9": 9, "jump": 9, "typecheck": 9, "np": 9, "pyspark": 9, "sql": 9, "collect_list": 9, "optpars": 9, "thread": 9, "_local": 9, "_thread": 9, "swagger_cli": 9, "mutat": 9, "dbutil": 9, "cb_": 9, "_cb": 9, "za": 9, "z0": 9, "9_": 9, "unused_": 9, "six": 9, "move": 9, "past": 9, "futur": [9, 10], "io": 9, "setup": [9, 10], "post_init": 9, "_asdict": 9, "_field": 9, "_replac": 9, "_sourc": 9, "_make": 9, "cl": 9, "7": 9, "expr": 9, "12": 9, "15": 9, "20": 9, "6": 9, "tkinter": 9, "tix": 9, "ext": 9, "known": 9, "azureiai": 9, "logist": 9, "inventoryplan": 9, "overgener": 9, "pyproject": 10, "main": 10, "project": 10, "replac": 10, "flit": 10, "poetri": 10, "consid": 10, "viabl": 10, "setuptool": 10, "cfg": 10, "still": 10, "wrapper": 11, "tabl": 11, "binari": 11, "yolo": 11, "yolov4": 11, "look": 11, "onc": 11, "my_releas": 11, "onnx": 11, "documen": 11, "render": 11, "sphinx": 11, "serv": 11, "doc": [1, 11], "html": 11, "bat": 11, "alreadi": 11, "prompt": 11, "overwrit": 11, "huski": 11, "instruct": 11, "cli": 11, "pre": 11, "commit": 11, "pytest": 11, "ran": [5, 11], "accordingli": 11, "categori": 11, "autom": 11, "purpos": 11, "sure": 11, "m": 11, "datacard": [0, 1, 2], "entrykind": [0, 1, 2], "entri": [1, 2], "model_card_schema": 1, "download_al": [1, 6], "home": 1, "ubuntu": 1, "lib": 1, "exclud": [1, 6], "fnmatch": 1, "unix": 1, "shell": 1, "style": 1, "wildcard": 1, "datacard_id": [1, 4], "stage": 4, "imagenet": 4, "data_card_vers": [1, 4], "update_data_card": [1, 4], "storageloc": 4, "data_card": [1, 4], "destin": 6, "data_card_schema": 1, "verifi": 0, "standard": 0, "ssl": 0, "verif": 0, "minimalschema": [0, 1, 2], "select_bi": [1, 5], "describ": 1, "warn": 1, "mlflow_uri": 1, "static": 1, "get_all_schema_id": 1, "scenario": 5, "seen": 5, "done": 5, "could": 5, "highest": 5, "twice": 5, "fetch": 6, "just": 6}, "objects": {"": [[2, 0, 0, "-", "bailo"]], "bailo.core": [[0, 0, 0, "-", "agent"], [0, 0, 0, "-", "client"], [0, 0, 0, "-", "enums"], [0, 0, 0, "-", "exceptions"]], "bailo.core.agent": [[0, 1, 1, "", "Agent"], [0, 1, 1, "", "PkiAgent"], [0, 1, 1, "", "TokenAgent"]], "bailo.core.agent.Agent": [[0, 2, 1, "", "__init__"], [0, 2, 1, "", "delete"], [0, 2, 1, "", "get"], [0, 2, 1, "", "patch"], [0, 2, 1, "", "post"], [0, 2, 1, "", "push"], [0, 2, 1, "", "put"]], "bailo.core.agent.PkiAgent": [[0, 2, 1, "", "__init__"], [0, 2, 1, "", "delete"], [0, 2, 1, "", "get"], [0, 2, 1, "", "patch"], [0, 2, 1, "", "post"], [0, 2, 1, "", "put"]], "bailo.core.agent.TokenAgent": [[0, 2, 1, "", "__init__"], [0, 2, 1, "", "delete"], [0, 2, 1, "", "get"], [0, 2, 1, "", "patch"], [0, 2, 1, "", "post"], [0, 2, 1, "", "put"]], "bailo.core.client": [[0, 1, 1, "", "Client"]], "bailo.core.client.Client": [[0, 2, 1, "", "delete_access_request"], [0, 2, 1, "", "delete_file"], [0, 2, 1, "", "delete_release"], [0, 2, 1, "", "get_access_request"], [0, 2, 1, "", "get_access_requests"], [0, 2, 1, "", "get_all_images"], [0, 2, 1, "", "get_all_releases"], [0, 2, 1, "", "get_all_schemas"], [0, 2, 1, "", "get_all_teams"], [0, 2, 1, "", "get_download_by_filename"], [0, 2, 1, "", "get_download_file"], [0, 2, 1, "", "get_files"], [0, 2, 1, "", "get_model"], [0, 2, 1, "", "get_model_card"], [0, 2, 1, "", "get_model_roles"], [0, 2, 1, "", "get_model_user_roles"], [0, 2, 1, "", "get_models"], [0, 2, 1, "", "get_release"], [0, 2, 1, "", "get_reviews"], [0, 2, 1, "", "get_schema"], [0, 2, 1, "", "get_team"], [0, 2, 1, "", "get_user_teams"], [0, 2, 1, "", "model_card_from_schema"], [0, 2, 1, "", "patch_access_request"], [0, 2, 1, "", "patch_model"], [0, 2, 1, "", "patch_team"], [0, 2, 1, "", "post_access_request"], [0, 2, 1, "", "post_model"], [0, 2, 1, "", "post_release"], [0, 2, 1, "", "post_review"], [0, 2, 1, "", "post_schema"], [0, 2, 1, "", "post_team"], [0, 2, 1, "", "put_model_card"], [0, 2, 1, "", "put_release"], [0, 2, 1, "", "simple_upload"]], "bailo.core.enums": [[0, 1, 1, "", "EntryKind"], [0, 1, 1, "", "MinimalSchema"], [0, 1, 1, "", "ModelVisibility"], [0, 1, 1, "", "Role"], [0, 1, 1, "", "SchemaKind"]], "bailo.core.enums.EntryKind": [[0, 3, 1, "", "DATACARD"], [0, 3, 1, "", "MODEL"]], "bailo.core.enums.MinimalSchema": [[0, 3, 1, "", "ACCESS_REQUEST"], [0, 3, 1, "", "DATACARD"], [0, 3, 1, "", "MODEL"]], "bailo.core.enums.ModelVisibility": [[0, 3, 1, "", "PRIVATE"], [0, 3, 1, "", "PUBLIC"]], "bailo.core.enums.Role": [[0, 3, 1, "", "MODEL_SENIOR_RESPONSIBLE_OFFICER"], [0, 3, 1, "", "MODEL_TECHNICAL_REVIEWER"], [0, 3, 1, "", "OWNER"]], "bailo.core.enums.SchemaKind": [[0, 3, 1, "", "ACCESS_REQUEST"], [0, 3, 1, "", "MODEL"]], "bailo.core.exceptions": [[0, 4, 1, "", "BailoException"], [0, 4, 1, "", "ResponseException"]], "bailo.helper": [[1, 0, 0, "-", "access_request"], [1, 0, 0, "-", "datacard"], [1, 0, 0, "-", "entry"], [1, 0, 0, "-", "model"], [1, 0, 0, "-", "release"], [1, 0, 0, "-", "schema"]], "bailo.helper.access_request": [[1, 1, 1, "", "AccessRequest"]], "bailo.helper.access_request.AccessRequest": [[1, 2, 1, "", "create"], [1, 2, 1, "", "delete"], [1, 2, 1, "", "from_id"], [1, 2, 1, "", "update"]], "bailo.helper.datacard": [[1, 1, 1, "", "Datacard"]], "bailo.helper.datacard.Datacard": [[1, 2, 1, "", "create"], [1, 5, 1, "", "data_card"], [1, 5, 1, "", "data_card_schema"], [1, 5, 1, "", "data_card_version"], [1, 2, 1, "", "from_id"], [1, 2, 1, "", "update_data_card"]], "bailo.helper.entry": [[1, 1, 1, "", "Entry"]], "bailo.helper.entry.Entry": [[1, 2, 1, "", "card_from_schema"], [1, 2, 1, "", "card_from_template"], [1, 2, 1, "", "get_card_latest"], [1, 2, 1, "", "get_card_revision"], [1, 2, 1, "", "get_roles"], [1, 2, 1, "", "get_user_roles"], [1, 2, 1, "", "update"]], "bailo.helper.model": [[1, 1, 1, "", "Experiment"], [1, 1, 1, "", "Model"]], "bailo.helper.model.Experiment": [[1, 2, 1, "", "create"], [1, 2, 1, "", "from_mlflow"], [1, 2, 1, "", "log_artifacts"], [1, 2, 1, "", "log_dataset"], [1, 2, 1, "", "log_metrics"], [1, 2, 1, "", "log_params"], [1, 2, 1, "", "publish"], [1, 2, 1, "", "start_run"]], "bailo.helper.model.Model": [[1, 2, 1, "", "create"], [1, 2, 1, "", "create_experiment"], [1, 2, 1, "", "create_release"], [1, 2, 1, "", "from_id"], [1, 2, 1, "", "from_mlflow"], [1, 2, 1, "", "get_image"], [1, 2, 1, "", "get_images"], [1, 2, 1, "", "get_latest_release"], [1, 2, 1, "", "get_release"], [1, 2, 1, "", "get_releases"], [1, 5, 1, "", "model_card"], [1, 5, 1, "", "model_card_schema"], [1, 5, 1, "", "model_card_version"], [1, 2, 1, "", "search"], [1, 2, 1, "", "update_model_card"]], "bailo.helper.release": [[1, 1, 1, "", "Release"]], "bailo.helper.release.Release": [[1, 2, 1, "", "__init__"], [1, 2, 1, "", "create"], [1, 2, 1, "", "delete"], [1, 2, 1, "", "download"], [1, 2, 1, "", "download_all"], [1, 2, 1, "", "from_version"], [1, 2, 1, "", "update"], [1, 2, 1, "", "upload"], [1, 5, 1, "", "version"]], "bailo.helper.schema": [[1, 1, 1, "", "Schema"]], "bailo.helper.schema.Schema": [[1, 2, 1, "", "create"], [1, 2, 1, "", "from_id"], [1, 2, 1, "", "get_all_schema_ids"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:method", "3": "py:attribute", "4": "py:exception", "5": "py:property"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "method", "Python method"], "3": ["py", "attribute", "Python attribute"], "4": ["py", "exception", "Python exception"], "5": ["py", "property", "Python property"]}, "titleterms": {"bailo": [0, 1, 2, 4, 5, 6, 11], "core": 0, "packag": [0, 1, 2, 9, 11], "helper": 1, "welcom": 2, "": [2, 9], "python": [2, 5, 9, 11], "client": [2, 5, 11], "document": [2, 11], "notebook": 2, "manag": [3, 4, 6, 7, 9], "access": [3, 9], "request": 3, "introduct": [3, 4, 5, 6, 7], "creat": [3, 4, 5, 6, 7, 9], "new": [3, 4, 5, 6, 7, 9], "retriev": [3, 4, 6, 7], "an": [3, 4, 5, 6, 7, 9], "us": [3, 4, 6, 7, 9], "from_id": [3, 4, 6, 7], "method": [3, 4, 6, 7, 9], "make": [3, 9], "chang": [3, 9], "delet": 3, "experi": 5, "track": 5, "mlflow": 5, "connect": 5, "set": [5, 9], "up": [5, 9], "prepar": [5, 6], "custom": 5, "schema": [5, 7], "conduct": 5, "run": [5, 9], "dummi": [5, 9], "import": [5, 9], "exist": [4, 5, 6, 7, 9], "from": [5, 6, 9], "publish": 5, "result": [5, 9], "model": 6, "releas": 6, "resnet": 6, "50": 6, "exampl": [6, 9], "pytorch": 6, "updat": [4, 6], "base": [4, 6, 9], "popul": [4, 6], "card": 6, "weight": 6, "upload": 6, "download": 6, "load": [6, 9], "pre": 8, "commit": 8, "config": 8, "yaml": 8, "A": 9, "comma": 9, "separ": 9, "list": 9, "modul": 9, "name": 9, "where": 9, "c": 9, "extens": 9, "mai": 9, "ar": 9, "activ": 9, "interpret": 9, "arbitrari": 9, "code": 9, "add": [9, 11], "file": 9, "directori": 9, "blacklist": 9, "thei": 9, "should": 9, "path": 9, "match": 9, "regex": 9, "pattern": 9, "The": 9, "against": 9, "execut": 9, "usual": 9, "sy": 9, "manipul": 9, "pygtk": 9, "requir": 9, "multipl": 9, "process": 9, "speed": 9, "pylint": 9, "specifi": 9, "0": 9, "auto": 9, "detect": 9, "number": 9, "processor": 9, "avail": 9, "control": 9, "amount": 9, "potenti": 9, "infer": 9, "valu": 9, "when": 9, "singl": 9, "object": 9, "thi": 9, "can": 9, "help": 9, "perform": 9, "deal": 9, "larg": 9, "function": 9, "complex": 9, "nest": 9, "condit": 9, "plugin": 9, "regist": 9, "addit": 9, "checker": 9, "pickl": 9, "collect": 9, "data": 9, "later": 9, "comparison": 9, "configur": 9, "enabl": 9, "would": 9, "attempt": 9, "guess": 9, "common": 9, "misconfigur": 9, "emit": 9, "user": 9, "friendli": 9, "hint": 9, "instead": 9, "fals": 9, "posit": 9, "error": 9, "messag": 9, "allow": 9, "onli": 9, "show": 9, "warn": 9, "confid": 9, "level": 9, "leav": 9, "empti": 9, "all": 9, "valid": 9, "high": 9, "inference_failur": 9, "undefin": 9, "disabl": 9, "report": 9, "categori": 9, "given": 9, "id": 9, "you": 9, "either": 9, "give": 9, "identifi": 9, "put": 9, "option": 9, "time": 9, "command": 9, "line": 9, "appear": 9, "onc": 9, "also": 9, "everyth": 9, "first": 9, "reenabl": 9, "specif": [5, 9], "check": 9, "For": 9, "want": 9, "similar": 9, "If": 9, "class": 9, "have": 9, "displai": 9, "w": 9, "see": 9, "express": 9, "which": 9, "return": 9, "score": 9, "less": 9, "than": 9, "equal": 9, "10": 9, "variabl": 9, "refactor": 9, "convent": 9, "contain": 9, "each": 9, "well": 9, "statement": 9, "i": 9, "total": 9, "analyz": 9, "global": 9, "evalu": 9, "rp0004": 9, "templat": 9, "style": 9, "format": 9, "string": 9, "inform": 9, "doc": 9, "detail": 9, "output": 9, "text": 9, "parseabl": 9, "color": 9, "json": 9, "msv": 9, "visual": 9, "studio": 9, "e": 9, "g": 9, "mypackag": 9, "mymodul": 9, "myreporterclass": 9, "tell": 9, "whether": 9, "full": 9, "maximum": 9, "block": 9, "bodi": 9, "complet": 9, "never": 9, "inconsist": 9, "call": 9, "consid": 9, "explicit": 9, "print": 9, "correct": 9, "argument": 9, "regular": 9, "overrid": 9, "attribut": 9, "attr": 9, "bad": 9, "alwai": 9, "refus": 9, "constant": 9, "const": 9, "minimum": 9, "length": 9, "docstr": 9, "shorter": 9, "ones": 9, "exempt": 9, "good": 9, "accept": 9, "includ": 9, "invalid": 9, "inlin": 9, "iter": 9, "inlinevar": 9, "colon": 9, "delimit": 9, "determin": 9, "other": 9, "sever": 9, "do": 9, "decor": 9, "produc": 9, "properti": 9, "abc": 9, "abstractproperti": 9, "These": 9, "taken": 9, "consider": 9, "expect": 9, "end": 9, "ani": 9, "lf": 9, "crlf": 9, "regexp": 9, "longer": 9, "limit": 9, "space": 9, "indent": 9, "insid": 9, "hang": 9, "continu": 9, "unit": 9, "4": 9, "t": 9, "1": 9, "tab": 9, "charact": 9, "construct": 9, "whitespac": 9, "dict": 9, "tabul": 9, "etc": 9, "n222": 9, "2": 9, "trail": 9, "between": 9, "close": 9, "bracket": 9, "same": 9, "declar": 9, "test": [9, 11], "els": 9, "log": 9, "old": 9, "mean": 9, "fstr": 9, "f": 9, "paramet": 9, "note": 9, "tag": 9, "take": 9, "ignor": 9, "comment": 9, "comput": 9, "count": 9, "suggest": 9, "spell": 9, "mistak": 9, "dictionari": 9, "none": 9, "To": 9, "work": 9, "instal": [9, 11], "enchant": 9, "word": 9, "privat": 9, "one": 9, "per": 9, "store": 9, "unknown": 9, "rais": 9, "flag": 9, "implicit": 9, "str": 9, "concat": 9, "sequenc": 9, "gener": 9, "concaten": 9, "defin": 9, "over": 9, "context": 9, "contextlib": 9, "contextmanag": 9, "member": 9, "dynam": 9, "miss": 9, "system": 9, "so": 9, "shouldn": 9, "trigger": 9, "e1101": 9, "mixin": 9, "its": 9, "case": 9, "insensit": 9, "about": 9, "owner": 9, "whenev": 9, "opaqu": 9, "while": 9, "some": 9, "branch": 9, "might": 9, "partial": 9, "In": 9, "still": 9, "rest": 9, "support": 9, "qualifi": 9, "project": 9, "namespac": 9, "dure": 9, "runtim": 9, "thu": 9, "cannot": 9, "deduc": 9, "static": 9, "analysi": 9, "It": 9, "unix": 9, "possibl": 9, "wa": 9, "found": 9, "aspect": 9, "find": 9, "edit": 9, "distanc": 9, "order": 9, "signatur": 9, "suppos": 9, "builtin": 9, "rememb": 9, "avoid": 9, "unus": 9, "treat": 9, "violat": 9, "callback": 9, "must": 9, "start": [9, 11], "those": 9, "default": 9, "lead": 9, "underscor": 9, "we": 9, "init": 9, "redefin": 9, "assign": 9, "instanc": 9, "exclud": 9, "protect": 9, "metaclass": 9, "r0902": 9, "boolean": 9, "r0916": 9, "local": [9, 11], "parent": 9, "r0901": 9, "public": 9, "r0904": 9, "yield": 9, "r0903": 9, "just": 9, "top": 9, "wildcard": 9, "analys": 9, "fallback": 9, "both": 9, "3": 9, "compat": 9, "anoth": 9, "deprec": 9, "graph": 9, "extern": 9, "depend": 9, "rp0402": 9, "everi": 9, "intern": 9, "forc": 9, "recogn": 9, "part": 9, "standard": 9, "librari": 9, "third": 9, "parti": 9, "coupl": 9, "prefer": 9, "except": 9, "being": 9, "caught": 9, "baseexcept": 9, "pypyroject": 10, "toml": 10, "kei": 11, "featur": 11, "get": 11, "build": 11, "develop": 11, "precommit": 11, "datacard": 4, "best": 5, "search": 6}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.viewcode": 1, "nbsphinx": 4, "sphinx": 60}, "alltitles": {"Introduction": [[7, "Introduction"], [3, "Introduction"], [4, "Introduction"], [5, "Introduction"], [6, "Introduction"]], "Using the .from_id() method": [[7, "Using-the-.from_id()-method"], [3, "Using-the-.from_id()-method"], [4, "Using-the-.from_id()-method"], [6, "Using-the-.from_id()-method"]], "Managing Schemas": [[7, "Managing-Schemas"]], "Creating a new schema": [[7, "Creating-a-new-schema"]], "Retrieving an existing schema": [[7, "Retrieving-an-existing-schema"]], "pre-commit-config.yaml": [[8, "pre-commit-config-yaml"]], "A comma-separated list of package or module names from where C extensions may": [[9, "a-comma-separated-list-of-package-or-module-names-from-where-c-extensions-may"]], "be loaded. Extensions are loading into the active Python interpreter and may": [[9, "be-loaded-extensions-are-loading-into-the-active-python-interpreter-and-may"]], "run arbitrary code.": [[9, "run-arbitrary-code"]], "Add files or directories to the blacklist. They should be base names, not": [[9, "add-files-or-directories-to-the-blacklist-they-should-be-base-names-not"]], "paths.": [[9, "paths"]], "Add files or directories matching the regex patterns to the blacklist. The": [[9, "add-files-or-directories-matching-the-regex-patterns-to-the-blacklist-the"]], "regex matches against base names, not paths.": [[9, "regex-matches-against-base-names-not-paths"]], "Python code to execute, usually for sys.path manipulation such as": [[9, "python-code-to-execute-usually-for-sys-path-manipulation-such-as"]], "pygtk.require().": [[9, "pygtk-require"]], "Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the": [[9, "use-multiple-processes-to-speed-up-pylint-specifying-0-will-auto-detect-the"]], "number of processors available to use.": [[9, "number-of-processors-available-to-use"]], "Control the amount of potential inferred values when inferring a single": [[9, "control-the-amount-of-potential-inferred-values-when-inferring-a-single"]], "object. This can help the performance when dealing with large functions or": [[9, "object-this-can-help-the-performance-when-dealing-with-large-functions-or"]], "complex, nested conditions.": [[9, "complex-nested-conditions"]], "List of plugins (as comma separated values of python module names) to load,": [[9, "list-of-plugins-as-comma-separated-values-of-python-module-names-to-load"]], "usually to register additional checkers.": [[9, "usually-to-register-additional-checkers"]], "Pickle collected data for later comparisons.": [[9, "pickle-collected-data-for-later-comparisons"]], "Specify a configuration file.": [[9, "specify-a-configuration-file"]], "When enabled, pylint would attempt to guess common misconfiguration and emit": [[9, "when-enabled-pylint-would-attempt-to-guess-common-misconfiguration-and-emit"]], "user-friendly hints instead of false-positive error messages.": [[9, "user-friendly-hints-instead-of-false-positive-error-messages"]], "Allow loading of arbitrary C extensions. Extensions are imported into the": [[9, "allow-loading-of-arbitrary-c-extensions-extensions-are-imported-into-the"]], "active Python interpreter and may run arbitrary code.": [[9, "active-python-interpreter-and-may-run-arbitrary-code"]], "Only show warnings with the listed confidence levels. Leave empty to show": [[9, "only-show-warnings-with-the-listed-confidence-levels-leave-empty-to-show"]], "all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.": [[9, "all-valid-levels-high-inference-inference-failure-undefined"]], "Disable the message, report, category or checker with the given id(s). You": [[9, "disable-the-message-report-category-or-checker-with-the-given-id-s-you"]], "can either give multiple identifiers separated by comma (,) or put this": [[9, "can-either-give-multiple-identifiers-separated-by-comma-or-put-this"]], "option multiple times (only on the command line, not in the configuration": [[9, "option-multiple-times-only-on-the-command-line-not-in-the-configuration"]], "file where it should appear only once). You can also use \u201c\u2013disable=all\u201d to": [[9, "file-where-it-should-appear-only-once-you-can-also-use-disable-all-to"]], "disable everything first and then reenable specific checks. For example, if": [[9, "disable-everything-first-and-then-reenable-specific-checks-for-example-if"]], "you want to run only the similarities checker, you can use \u201c\u2013disable=all": [[9, "you-want-to-run-only-the-similarities-checker-you-can-use-disable-all"]], "\u2013enable=similarities\u201d. If you want to run only the classes checker, but have": [[9, "enable-similarities-if-you-want-to-run-only-the-classes-checker-but-have"]], "no Warning level messages displayed, use \u201c\u2013disable=all \u2013enable=classes": [[9, "no-warning-level-messages-displayed-use-disable-all-enable-classes"]], "\u2013disable=W\u201d.": [[9, "disable-w"]], "Enable the message, report, category or checker with the given id(s). You can": [[9, "enable-the-message-report-category-or-checker-with-the-given-id-s-you-can"]], "either give multiple identifier separated by comma (,) or put this option": [[9, "either-give-multiple-identifier-separated-by-comma-or-put-this-option"]], "multiple time (only on the command line, not in the configuration file where": [[9, "multiple-time-only-on-the-command-line-not-in-the-configuration-file-where"]], "it should appear only once). See also the \u201c\u2013disable\u201d option for examples.": [[9, "it-should-appear-only-once-see-also-the-disable-option-for-examples"]], "Python expression which should return a score less than or equal to 10. You": [[9, "python-expression-which-should-return-a-score-less-than-or-equal-to-10-you"]], "have access to the variables \u2018error\u2019, \u2018warning\u2019, \u2018refactor\u2019, and \u2018convention\u2019": [[9, "have-access-to-the-variables-error-warning-refactor-and-convention"]], "which contain the number of messages in each category, as well as \u2018statement\u2019": [[9, "which-contain-the-number-of-messages-in-each-category-as-well-as-statement"]], "which is the total number of statements analyzed. This score is used by the": [[9, "which-is-the-total-number-of-statements-analyzed-this-score-is-used-by-the"]], "global evaluation report (RP0004).": [[9, "global-evaluation-report-rp0004"]], "Template used to display messages. This is a python new-style format string": [[9, "template-used-to-display-messages-this-is-a-python-new-style-format-string"]], "used to format the message information. See doc for all details.": [[9, "used-to-format-the-message-information-see-doc-for-all-details"]], "Set the output format. Available formats are text, parseable, colorized, json": [[9, "set-the-output-format-available-formats-are-text-parseable-colorized-json"]], "and msvs (visual studio). You can also give a reporter class, e.g.": [[9, "and-msvs-visual-studio-you-can-also-give-a-reporter-class-e-g"]], "mypackage.mymodule.MyReporterClass.": [[9, "mypackage-mymodule-myreporterclass"]], "Tells whether to display a full report or only the messages.": [[9, "tells-whether-to-display-a-full-report-or-only-the-messages"]], "Activate the evaluation score.": [[9, "activate-the-evaluation-score"]], "Maximum number of nested blocks for function / method body": [[9, "maximum-number-of-nested-blocks-for-function-method-body"]], "Complete name of functions that never returns. When checking for": [[9, "complete-name-of-functions-that-never-returns-when-checking-for"]], "inconsistent-return-statements if a never returning function is called then": [[9, "inconsistent-return-statements-if-a-never-returning-function-is-called-then"]], "it will be considered as an explicit return statement and no message will be": [[9, "it-will-be-considered-as-an-explicit-return-statement-and-no-message-will-be"]], "printed.": [[9, "printed"]], "Naming style matching correct argument names.": [[9, "naming-style-matching-correct-argument-names"]], "Regular expression matching correct argument names. Overrides argument-": [[9, "regular-expression-matching-correct-argument-names-overrides-argument"]], "naming-style.": [[9, "naming-style"], [9, "id3"], [9, "id6"]], "Naming style matching correct attribute names.": [[9, "naming-style-matching-correct-attribute-names"]], "Regular expression matching correct attribute names. Overrides attr-naming-": [[9, "regular-expression-matching-correct-attribute-names-overrides-attr-naming"]], "style.": [[9, "style"], [9, "id1"], [9, "id2"], [9, "id4"], [9, "id5"]], "Bad variable names which should always be refused, separated by a comma.": [[9, "bad-variable-names-which-should-always-be-refused-separated-by-a-comma"]], "Naming style matching correct class attribute names.": [[9, "naming-style-matching-correct-class-attribute-names"]], "Regular expression matching correct class attribute names. Overrides class-": [[9, "regular-expression-matching-correct-class-attribute-names-overrides-class"]], "attribute-naming-style.": [[9, "attribute-naming-style"]], "Naming style matching correct class names.": [[9, "naming-style-matching-correct-class-names"]], "Regular expression matching correct class names. Overrides class-naming-": [[9, "regular-expression-matching-correct-class-names-overrides-class-naming"]], "Naming style matching correct constant names.": [[9, "naming-style-matching-correct-constant-names"]], "Regular expression matching correct constant names. Overrides const-naming-": [[9, "regular-expression-matching-correct-constant-names-overrides-const-naming"]], "Minimum line length for functions/classes that require docstrings, shorter": [[9, "minimum-line-length-for-functions-classes-that-require-docstrings-shorter"]], "ones are exempt.": [[9, "ones-are-exempt"]], "Naming style matching correct function names.": [[9, "naming-style-matching-correct-function-names"]], "Regular expression matching correct function names. Overrides function-": [[9, "regular-expression-matching-correct-function-names-overrides-function"]], "Good variable names which should always be accepted, separated by a comma.": [[9, "good-variable-names-which-should-always-be-accepted-separated-by-a-comma"]], "Include a hint for the correct naming format with invalid-name.": [[9, "include-a-hint-for-the-correct-naming-format-with-invalid-name"]], "Naming style matching correct inline iteration names.": [[9, "naming-style-matching-correct-inline-iteration-names"]], "Regular expression matching correct inline iteration names. Overrides": [[9, "regular-expression-matching-correct-inline-iteration-names-overrides"]], "inlinevar-naming-style.": [[9, "inlinevar-naming-style"]], "Naming style matching correct method names.": [[9, "naming-style-matching-correct-method-names"]], "Regular expression matching correct method names. Overrides method-naming-": [[9, "regular-expression-matching-correct-method-names-overrides-method-naming"]], "Naming style matching correct module names.": [[9, "naming-style-matching-correct-module-names"]], "Regular expression matching correct module names. Overrides module-naming-": [[9, "regular-expression-matching-correct-module-names-overrides-module-naming"]], "Colon-delimited sets of names that determine each other\u2019s naming style when": [[9, "colon-delimited-sets-of-names-that-determine-each-other-s-naming-style-when"]], "the name regexes allow several styles.": [[9, "the-name-regexes-allow-several-styles"]], "Regular expression which should only match function or class names that do": [[9, "regular-expression-which-should-only-match-function-or-class-names-that-do"]], "not require a docstring.": [[9, "not-require-a-docstring"]], "List of decorators that produce properties, such as abc.abstractproperty. Add": [[9, "list-of-decorators-that-produce-properties-such-as-abc-abstractproperty-add"]], "to this list to register other decorators that produce valid properties.": [[9, "to-this-list-to-register-other-decorators-that-produce-valid-properties"]], "These decorators are taken in consideration only for invalid-name.": [[9, "these-decorators-are-taken-in-consideration-only-for-invalid-name"]], "Naming style matching correct variable names.": [[9, "naming-style-matching-correct-variable-names"]], "Regular expression matching correct variable names. Overrides variable-": [[9, "regular-expression-matching-correct-variable-names-overrides-variable"]], "Expected format of line ending, e.g. empty (any line ending), LF or CRLF.": [[9, "expected-format-of-line-ending-e-g-empty-any-line-ending-lf-or-crlf"]], "Regexp for a line that is allowed to be longer than the limit.": [[9, "regexp-for-a-line-that-is-allowed-to-be-longer-than-the-limit"]], "Number of spaces of indent required inside a hanging or continued line.": [[9, "number-of-spaces-of-indent-required-inside-a-hanging-or-continued-line"]], "String used as indentation unit. This is usually \u201c \u201c (4 spaces) or \u201c\\t\u201d (1": [[9, "string-used-as-indentation-unit-this-is-usually-4-spaces-or-t-1"]], "tab).": [[9, "tab"]], "Maximum number of characters on a single line.": [[9, "maximum-number-of-characters-on-a-single-line"]], "Maximum number of lines in a module.": [[9, "maximum-number-of-lines-in-a-module"]], "List of optional constructs for which whitespace checking is disabled. `dict-": [[9, "list-of-optional-constructs-for-which-whitespace-checking-is-disabled-dict"]], "separator` is used to allow tabulation in dicts, etc.: {1 : 1,\\n222: 2}.": [[9, "separator-is-used-to-allow-tabulation-in-dicts-etc-1-1-n222-2"]], "trailing-comma allows a space between comma and closing bracket: (a, ).": [[9, "trailing-comma-allows-a-space-between-comma-and-closing-bracket-a"]], "empty-line allows space-only lines.": [[9, "empty-line-allows-space-only-lines"]], "Allow the body of a class to be on the same line as the declaration if body": [[9, "allow-the-body-of-a-class-to-be-on-the-same-line-as-the-declaration-if-body"]], "contains single statement.": [[9, "contains-single-statement"]], "Allow the body of an if to be on the same line as the test if there is no": [[9, "allow-the-body-of-an-if-to-be-on-the-same-line-as-the-test-if-there-is-no"]], "else.": [[9, "else"]], "Format style used to check logging format string. old means using %": [[9, "format-style-used-to-check-logging-format-string-old-means-using"]], "formatting, new is for {} formatting,and fstr is for f-strings.": [[9, "formatting-new-is-for-formatting-and-fstr-is-for-f-strings"]], "Logging modules to check that the string format arguments are in logging": [[9, "logging-modules-to-check-that-the-string-format-arguments-are-in-logging"]], "function parameter format.": [[9, "function-parameter-format"]], "List of note tags to take in consideration, separated by a comma.": [[9, "list-of-note-tags-to-take-in-consideration-separated-by-a-comma"]], "Ignore comments when computing similarities.": [[9, "ignore-comments-when-computing-similarities"]], "Ignore docstrings when computing similarities.": [[9, "ignore-docstrings-when-computing-similarities"]], "Ignore imports when computing similarities.": [[9, "ignore-imports-when-computing-similarities"]], "Minimum lines number of a similarity.": [[9, "minimum-lines-number-of-a-similarity"]], "Limits count of emitted suggestions for spelling mistakes.": [[9, "limits-count-of-emitted-suggestions-for-spelling-mistakes"]], "Spelling dictionary name. Available dictionaries: none. To make it work,": [[9, "spelling-dictionary-name-available-dictionaries-none-to-make-it-work"]], "install the python-enchant package.": [[9, "install-the-python-enchant-package"]], "List of comma separated words that should not be checked.": [[9, "list-of-comma-separated-words-that-should-not-be-checked"]], "A path to a file that contains the private dictionary; one word per line.": [[9, "a-path-to-a-file-that-contains-the-private-dictionary-one-word-per-line"]], "Tells whether to store unknown words to the private dictionary (see the": [[9, "tells-whether-to-store-unknown-words-to-the-private-dictionary-see-the"]], "\u2013spelling-private-dict-file option) instead of raising a message.": [[9, "spelling-private-dict-file-option-instead-of-raising-a-message"]], "This flag controls whether the implicit-str-concat-in-sequence should": [[9, "this-flag-controls-whether-the-implicit-str-concat-in-sequence-should"]], "generate a warning on implicit string concatenation in sequences defined over": [[9, "generate-a-warning-on-implicit-string-concatenation-in-sequences-defined-over"]], "several lines.": [[9, "several-lines"]], "List of decorators that produce context managers, such as": [[9, "list-of-decorators-that-produce-context-managers-such-as"]], "contextlib.contextmanager. Add to this list to register other decorators that": [[9, "contextlib-contextmanager-add-to-this-list-to-register-other-decorators-that"]], "produce valid context managers.": [[9, "produce-valid-context-managers"]], "List of members which are set dynamically and missed by pylint inference": [[9, "list-of-members-which-are-set-dynamically-and-missed-by-pylint-inference"]], "system, and so shouldn\u2019t trigger E1101 when accessed. Python regular": [[9, "system-and-so-shouldn-t-trigger-e1101-when-accessed-python-regular"]], "expressions are accepted.": [[9, "expressions-are-accepted"]], "Tells whether missing members accessed in mixin class should be ignored. A": [[9, "tells-whether-missing-members-accessed-in-mixin-class-should-be-ignored-a"]], "mixin class is detected if its name ends with \u201cmixin\u201d (case insensitive).": [[9, "mixin-class-is-detected-if-its-name-ends-with-mixin-case-insensitive"]], "Tells whether to warn about missing members when the owner of the attribute": [[9, "tells-whether-to-warn-about-missing-members-when-the-owner-of-the-attribute"]], "is inferred to be None.": [[9, "is-inferred-to-be-none"]], "This flag controls whether pylint should warn about no-member and similar": [[9, "this-flag-controls-whether-pylint-should-warn-about-no-member-and-similar"]], "checks whenever an opaque object is returned when inferring. The inference": [[9, "checks-whenever-an-opaque-object-is-returned-when-inferring-the-inference"]], "can return multiple potential results while evaluating a Python object, but": [[9, "can-return-multiple-potential-results-while-evaluating-a-python-object-but"]], "some branches might not be evaluated, which results in partial inference. In": [[9, "some-branches-might-not-be-evaluated-which-results-in-partial-inference-in"]], "that case, it might be useful to still emit no-member and other checks for": [[9, "that-case-it-might-be-useful-to-still-emit-no-member-and-other-checks-for"]], "the rest of the inferred objects.": [[9, "the-rest-of-the-inferred-objects"]], "List of class names for which member attributes should not be checked (useful": [[9, "list-of-class-names-for-which-member-attributes-should-not-be-checked-useful"]], "for classes with dynamically set attributes). This supports the use of": [[9, "for-classes-with-dynamically-set-attributes-this-supports-the-use-of"]], "qualified names.": [[9, "qualified-names"]], "List of module names for which member attributes should not be checked": [[9, "list-of-module-names-for-which-member-attributes-should-not-be-checked"]], "(useful for modules/projects where namespaces are manipulated during runtime": [[9, "useful-for-modules-projects-where-namespaces-are-manipulated-during-runtime"]], "and thus existing member attributes cannot be deduced by static analysis). It": [[9, "and-thus-existing-member-attributes-cannot-be-deduced-by-static-analysis-it"]], "supports qualified module names, as well as Unix pattern matching.": [[9, "supports-qualified-module-names-as-well-as-unix-pattern-matching"]], "Show a hint with possible names when a member name was not found. The aspect": [[9, "show-a-hint-with-possible-names-when-a-member-name-was-not-found-the-aspect"]], "of finding the hint is based on edit distance.": [[9, "of-finding-the-hint-is-based-on-edit-distance"]], "The minimum edit distance a name should have in order to be considered a": [[9, "the-minimum-edit-distance-a-name-should-have-in-order-to-be-considered-a"]], "similar match for a missing member name.": [[9, "similar-match-for-a-missing-member-name"]], "The total number of similar names that should be taken in consideration when": [[9, "the-total-number-of-similar-names-that-should-be-taken-in-consideration-when"]], "showing a hint for a missing member.": [[9, "showing-a-hint-for-a-missing-member"]], "List of decorators that change the signature of a decorated function.": [[9, "list-of-decorators-that-change-the-signature-of-a-decorated-function"]], "List of additional names supposed to be defined in builtins. Remember that": [[9, "list-of-additional-names-supposed-to-be-defined-in-builtins-remember-that"]], "you should avoid defining new builtins when possible.": [[9, "you-should-avoid-defining-new-builtins-when-possible"]], "Tells whether unused global variables should be treated as a violation.": [[9, "tells-whether-unused-global-variables-should-be-treated-as-a-violation"]], "List of strings which can identify a callback function by name. A callback": [[9, "list-of-strings-which-can-identify-a-callback-function-by-name-a-callback"]], "name must start or end with one of those strings.": [[9, "name-must-start-or-end-with-one-of-those-strings"]], "A regular expression matching the name of dummy variables (i.e. expected to": [[9, "a-regular-expression-matching-the-name-of-dummy-variables-i-e-expected-to"]], "not be used).": [[9, "not-be-used"]], "Argument names that match this expression will be ignored. Default to name": [[9, "argument-names-that-match-this-expression-will-be-ignored-default-to-name"]], "with leading underscore.": [[9, "with-leading-underscore"]], "Tells whether we should check for unused import in init files.": [[9, "tells-whether-we-should-check-for-unused-import-in-init-files"]], "List of qualified module names which can have objects that can redefine": [[9, "list-of-qualified-module-names-which-can-have-objects-that-can-redefine"]], "builtins.": [[9, "builtins"]], "List of method names used to declare (i.e. assign) instance attributes.": [[9, "list-of-method-names-used-to-declare-i-e-assign-instance-attributes"]], "List of member names, which should be excluded from the protected access": [[9, "list-of-member-names-which-should-be-excluded-from-the-protected-access"]], "warning.": [[9, "warning"]], "List of valid names for the first argument in a class method.": [[9, "list-of-valid-names-for-the-first-argument-in-a-class-method"]], "List of valid names for the first argument in a metaclass class method.": [[9, "list-of-valid-names-for-the-first-argument-in-a-metaclass-class-method"]], "Maximum number of arguments for function / method.": [[9, "maximum-number-of-arguments-for-function-method"]], "Maximum number of attributes for a class (see R0902).": [[9, "maximum-number-of-attributes-for-a-class-see-r0902"]], "Maximum number of boolean expressions in an if statement (see R0916).": [[9, "maximum-number-of-boolean-expressions-in-an-if-statement-see-r0916"]], "Maximum number of branch for function / method body.": [[9, "maximum-number-of-branch-for-function-method-body"]], "Maximum number of locals for function / method body.": [[9, "maximum-number-of-locals-for-function-method-body"]], "Maximum number of parents for a class (see R0901).": [[9, "maximum-number-of-parents-for-a-class-see-r0901"]], "Maximum number of public methods for a class (see R0904).": [[9, "maximum-number-of-public-methods-for-a-class-see-r0904"]], "Maximum number of return / yield for function / method body.": [[9, "maximum-number-of-return-yield-for-function-method-body"]], "Maximum number of statements in function / method body.": [[9, "maximum-number-of-statements-in-function-method-body"]], "Minimum number of public methods for a class (see R0903).": [[9, "minimum-number-of-public-methods-for-a-class-see-r0903"]], "List of modules that can be imported at any level, not just the top level": [[9, "list-of-modules-that-can-be-imported-at-any-level-not-just-the-top-level"]], "one.": [[9, "one"]], "Allow wildcard imports from modules that define all.": [[9, "allow-wildcard-imports-from-modules-that-define-all"]], "Analyse import fallback blocks. This can be used to support both Python 2 and": [[9, "analyse-import-fallback-blocks-this-can-be-used-to-support-both-python-2-and"]], "3 compatible code, which means that the block might have code that exists": [[9, "compatible-code-which-means-that-the-block-might-have-code-that-exists"]], "only in one or another interpreter, leading to false positives when analysed.": [[9, "only-in-one-or-another-interpreter-leading-to-false-positives-when-analysed"]], "Deprecated modules which should not be used, separated by a comma.": [[9, "deprecated-modules-which-should-not-be-used-separated-by-a-comma"]], "Create a graph of external dependencies in the given file (report RP0402 must": [[9, "create-a-graph-of-external-dependencies-in-the-given-file-report-rp0402-must"]], "not be disabled).": [[9, "not-be-disabled"], [9, "id7"]], "Create a graph of every (i.e. internal and external) dependencies in the": [[9, "create-a-graph-of-every-i-e-internal-and-external-dependencies-in-the"]], "given file (report RP0402 must not be disabled).": [[9, "given-file-report-rp0402-must-not-be-disabled"]], "Create a graph of internal dependencies in the given file (report RP0402 must": [[9, "create-a-graph-of-internal-dependencies-in-the-given-file-report-rp0402-must"]], "Force import order to recognize a module as part of the standard": [[9, "force-import-order-to-recognize-a-module-as-part-of-the-standard"]], "compatibility libraries.": [[9, "compatibility-libraries"]], "Force import order to recognize a module as part of a third party library.": [[9, "force-import-order-to-recognize-a-module-as-part-of-a-third-party-library"]], "Couples of modules and preferred modules, separated by a comma.": [[9, "couples-of-modules-and-preferred-modules-separated-by-a-comma"]], "Exceptions that will emit a warning when being caught. Defaults to": [[9, "exceptions-that-will-emit-a-warning-when-being-caught-defaults-to"]], "\u201cBaseException, Exception\u201d.": [[9, "baseexception-exception"]], "pypyroject.toml": [[10, "pypyroject-toml"]], "Bailo Python Client": [[11, "bailo-python-client"], [2, "bailo-python-client"]], "Key Features": [[11, "key-features"]], "Installing": [[11, "installing"]], "Getting Started": [[11, "getting-started"]], "Documentation": [[11, "documentation"]], "Building locally": [[11, "building-locally"]], "Development": [[11, "development"]], "Install and add precommit": [[11, "install-and-add-precommit"]], "Install the package locally": [[11, "install-the-package-locally"]], "Testing": [[11, "testing"]], "bailo.core package": [[0, "bailo-core-package"]], "bailo.helper package": [[1, "module-bailo.helper.access_request"]], "Welcome to Bailo\u2019s Python Client documentation!": [[2, "module-bailo"]], "Packages:": [[2, null]], "Notebooks:": [[2, null]], "Managing Access Requests": [[3, "Managing-Access-Requests"]], "Creating a new access request": [[3, "Creating-a-new-access-request"]], "Retrieving an access request": [[3, "Retrieving-an-access-request"]], "Making changes to an access request": [[3, "Making-changes-to-an-access-request"]], "Deleting an access request": [[3, "Deleting-an-access-request"]], "Managing Datacards": [[4, "Managing-Datacards"]], "Creating a new datacard in Bailo": [[4, "Creating-a-new-datacard-in-Bailo"]], "Creating and updating the base datacard": [[4, "Creating-and-updating-the-base-datacard"]], "Populating the datacard": [[4, "Populating-the-datacard"]], "Retrieving an existing datacard": [[4, "Retrieving-an-existing-datacard"]], "Experiment Tracking with Bailo & MLFlow": [[5, "Experiment-Tracking-with-Bailo-&-MLFlow"]], "Connecting with Bailo": [[5, "Connecting-with-Bailo"]], "Setting up MLFlow Tracking": [[5, "Setting-up-MLFlow-Tracking"]], "Preparing a custom schema for tracking": [[5, "Preparing-a-custom-schema-for-tracking"]], "Creating a new experiment": [[5, "Creating-a-new-experiment"]], "Conducting experiment runs": [[5, "Conducting-experiment-runs"]], "Running an experiment with the Bailo python client": [[5, "Running-an-experiment-with-the-Bailo-python-client"]], "Creating a dummy MLFlow experiment run": [[5, "Creating-a-dummy-MLFlow-experiment-run"]], "Importing existing experiments from MLFlow into Bailo": [[5, "Importing-existing-experiments-from-MLFlow-into-Bailo"]], "Publishing results to Bailo": [[5, "Publishing-results-to-Bailo"]], "Publishing a specific run": [[5, "Publishing-a-specific-run"]], "Publishing the best run": [[5, "Publishing-the-best-run"]], "Managing Models & Releases (ResNet-50 Example with PyTorch)": [[6, "Managing-Models-&-Releases-(ResNet-50-Example-with-PyTorch)"]], "Creating a new ResNet-50 model in Bailo": [[6, "Creating-a-new-ResNet-50-model-in-Bailo"]], "Creating and updating the base model": [[6, "Creating-and-updating-the-base-model"]], "Creating and populating a model card": [[6, "Creating-and-populating-a-model-card"]], "Retrieving an existing model": [[6, "Retrieving-an-existing-model"]], "Creating and managing releases for models": [[6, "Creating-and-managing-releases-for-models"]], "Creating a release": [[6, "Creating-a-release"]], "Preparing the model weights using PyTorch": [[6, "Preparing-the-model-weights-using-PyTorch"]], "Uploading weights to the release": [[6, "Uploading-weights-to-the-release"]], "Retrieving a release": [[6, "Retrieving-a-release"]], "Downloading weights from the release": [[6, "Downloading-weights-from-the-release"]], "Loading the model using PyTorch": [[6, "Loading-the-model-using-PyTorch"]], "Searching for models": [[6, "Searching-for-models"]]}, "indexentries": {"access_request (bailo.core.enums.minimalschema attribute)": [[0, "bailo.core.enums.MinimalSchema.ACCESS_REQUEST"]], "access_request (bailo.core.enums.schemakind attribute)": [[0, "bailo.core.enums.SchemaKind.ACCESS_REQUEST"]], "agent (class in bailo.core.agent)": [[0, "bailo.core.agent.Agent"]], "bailoexception": [[0, "bailo.core.exceptions.BailoException"]], "client (class in bailo.core.client)": [[0, "bailo.core.client.Client"]], "datacard (bailo.core.enums.entrykind attribute)": [[0, "bailo.core.enums.EntryKind.DATACARD"]], "datacard (bailo.core.enums.minimalschema attribute)": [[0, "bailo.core.enums.MinimalSchema.DATACARD"]], "entrykind (class in bailo.core.enums)": [[0, "bailo.core.enums.EntryKind"]], "model (bailo.core.enums.entrykind attribute)": [[0, "bailo.core.enums.EntryKind.MODEL"]], "model (bailo.core.enums.minimalschema attribute)": [[0, "bailo.core.enums.MinimalSchema.MODEL"]], "model (bailo.core.enums.schemakind attribute)": [[0, "bailo.core.enums.SchemaKind.MODEL"]], "model_senior_responsible_officer (bailo.core.enums.role attribute)": [[0, "bailo.core.enums.Role.MODEL_SENIOR_RESPONSIBLE_OFFICER"]], "model_technical_reviewer (bailo.core.enums.role attribute)": [[0, "bailo.core.enums.Role.MODEL_TECHNICAL_REVIEWER"]], "minimalschema (class in bailo.core.enums)": [[0, "bailo.core.enums.MinimalSchema"]], "modelvisibility (class in bailo.core.enums)": [[0, "bailo.core.enums.ModelVisibility"]], "owner (bailo.core.enums.role attribute)": [[0, "bailo.core.enums.Role.OWNER"]], "private (bailo.core.enums.modelvisibility attribute)": [[0, "bailo.core.enums.ModelVisibility.PRIVATE"]], "public (bailo.core.enums.modelvisibility attribute)": [[0, "bailo.core.enums.ModelVisibility.PUBLIC"]], "pkiagent (class in bailo.core.agent)": [[0, "bailo.core.agent.PkiAgent"]], "responseexception": [[0, "bailo.core.exceptions.ResponseException"]], "role (class in bailo.core.enums)": [[0, "bailo.core.enums.Role"]], "schemakind (class in bailo.core.enums)": [[0, "bailo.core.enums.SchemaKind"]], "tokenagent (class in bailo.core.agent)": [[0, "bailo.core.agent.TokenAgent"]], "__init__() (bailo.core.agent.agent method)": [[0, "bailo.core.agent.Agent.__init__"]], "__init__() (bailo.core.agent.pkiagent method)": [[0, "bailo.core.agent.PkiAgent.__init__"]], "__init__() (bailo.core.agent.tokenagent method)": [[0, "bailo.core.agent.TokenAgent.__init__"]], "bailo.core.agent": [[0, "module-bailo.core.agent"]], "bailo.core.client": [[0, "module-bailo.core.client"]], "bailo.core.enums": [[0, "module-bailo.core.enums"]], "bailo.core.exceptions": [[0, "module-bailo.core.exceptions"]], "delete() (bailo.core.agent.agent method)": [[0, "bailo.core.agent.Agent.delete"]], "delete() (bailo.core.agent.pkiagent method)": [[0, "bailo.core.agent.PkiAgent.delete"]], "delete() (bailo.core.agent.tokenagent method)": [[0, "bailo.core.agent.TokenAgent.delete"]], "delete_access_request() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.delete_access_request"]], "delete_file() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.delete_file"]], "delete_release() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.delete_release"]], "get() (bailo.core.agent.agent method)": [[0, "bailo.core.agent.Agent.get"]], "get() (bailo.core.agent.pkiagent method)": [[0, "bailo.core.agent.PkiAgent.get"]], "get() (bailo.core.agent.tokenagent method)": [[0, "bailo.core.agent.TokenAgent.get"]], "get_access_request() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_access_request"]], "get_access_requests() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_access_requests"]], "get_all_images() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_all_images"]], "get_all_releases() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_all_releases"]], "get_all_schemas() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_all_schemas"]], "get_all_teams() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_all_teams"]], "get_download_by_filename() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_download_by_filename"]], "get_download_file() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_download_file"]], "get_files() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_files"]], "get_model() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_model"]], "get_model_card() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_model_card"]], "get_model_roles() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_model_roles"]], "get_model_user_roles() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_model_user_roles"]], "get_models() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_models"]], "get_release() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_release"]], "get_reviews() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_reviews"]], "get_schema() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_schema"]], "get_team() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_team"]], "get_user_teams() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.get_user_teams"]], "model_card_from_schema() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.model_card_from_schema"]], "module": [[0, "module-bailo.core.agent"], [0, "module-bailo.core.client"], [0, "module-bailo.core.enums"], [0, "module-bailo.core.exceptions"], [1, "module-bailo.helper.access_request"], [1, "module-bailo.helper.datacard"], [1, "module-bailo.helper.entry"], [1, "module-bailo.helper.model"], [1, "module-bailo.helper.release"], [1, "module-bailo.helper.schema"], [2, "module-bailo"]], "patch() (bailo.core.agent.agent method)": [[0, "bailo.core.agent.Agent.patch"]], "patch() (bailo.core.agent.pkiagent method)": [[0, "bailo.core.agent.PkiAgent.patch"]], "patch() (bailo.core.agent.tokenagent method)": [[0, "bailo.core.agent.TokenAgent.patch"]], "patch_access_request() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.patch_access_request"]], "patch_model() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.patch_model"]], "patch_team() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.patch_team"]], "post() (bailo.core.agent.agent method)": [[0, "bailo.core.agent.Agent.post"]], "post() (bailo.core.agent.pkiagent method)": [[0, "bailo.core.agent.PkiAgent.post"]], "post() (bailo.core.agent.tokenagent method)": [[0, "bailo.core.agent.TokenAgent.post"]], "post_access_request() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.post_access_request"]], "post_model() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.post_model"]], "post_release() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.post_release"]], "post_review() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.post_review"]], "post_schema() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.post_schema"]], "post_team() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.post_team"]], "push() (bailo.core.agent.agent method)": [[0, "bailo.core.agent.Agent.push"]], "put() (bailo.core.agent.agent method)": [[0, "bailo.core.agent.Agent.put"]], "put() (bailo.core.agent.pkiagent method)": [[0, "bailo.core.agent.PkiAgent.put"]], "put() (bailo.core.agent.tokenagent method)": [[0, "bailo.core.agent.TokenAgent.put"]], "put_model_card() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.put_model_card"]], "put_release() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.put_release"]], "simple_upload() (bailo.core.client.client method)": [[0, "bailo.core.client.Client.simple_upload"]], "accessrequest (class in bailo.helper.access_request)": [[1, "bailo.helper.access_request.AccessRequest"]], "datacard (class in bailo.helper.datacard)": [[1, "bailo.helper.datacard.Datacard"]], "entry (class in bailo.helper.entry)": [[1, "bailo.helper.entry.Entry"]], "experiment (class in bailo.helper.model)": [[1, "bailo.helper.model.Experiment"]], "model (class in bailo.helper.model)": [[1, "bailo.helper.model.Model"]], "release (class in bailo.helper.release)": [[1, "bailo.helper.release.Release"]], "schema (class in bailo.helper.schema)": [[1, "bailo.helper.schema.Schema"]], "__init__() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.__init__"]], "bailo.helper.access_request": [[1, "module-bailo.helper.access_request"]], "bailo.helper.datacard": [[1, "module-bailo.helper.datacard"]], "bailo.helper.entry": [[1, "module-bailo.helper.entry"]], "bailo.helper.model": [[1, "module-bailo.helper.model"]], "bailo.helper.release": [[1, "module-bailo.helper.release"]], "bailo.helper.schema": [[1, "module-bailo.helper.schema"]], "card_from_schema() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.card_from_schema"]], "card_from_template() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.card_from_template"]], "create() (bailo.helper.access_request.accessrequest class method)": [[1, "bailo.helper.access_request.AccessRequest.create"]], "create() (bailo.helper.datacard.datacard class method)": [[1, "bailo.helper.datacard.Datacard.create"]], "create() (bailo.helper.model.experiment class method)": [[1, "bailo.helper.model.Experiment.create"]], "create() (bailo.helper.model.model class method)": [[1, "bailo.helper.model.Model.create"]], "create() (bailo.helper.release.release class method)": [[1, "bailo.helper.release.Release.create"]], "create() (bailo.helper.schema.schema class method)": [[1, "bailo.helper.schema.Schema.create"]], "create_experiment() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.create_experiment"]], "create_release() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.create_release"]], "data_card (bailo.helper.datacard.datacard property)": [[1, "bailo.helper.datacard.Datacard.data_card"]], "data_card_schema (bailo.helper.datacard.datacard property)": [[1, "bailo.helper.datacard.Datacard.data_card_schema"]], "data_card_version (bailo.helper.datacard.datacard property)": [[1, "bailo.helper.datacard.Datacard.data_card_version"]], "delete() (bailo.helper.access_request.accessrequest method)": [[1, "bailo.helper.access_request.AccessRequest.delete"]], "delete() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.delete"]], "download() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.download"]], "download_all() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.download_all"]], "from_id() (bailo.helper.access_request.accessrequest class method)": [[1, "bailo.helper.access_request.AccessRequest.from_id"]], "from_id() (bailo.helper.datacard.datacard class method)": [[1, "bailo.helper.datacard.Datacard.from_id"]], "from_id() (bailo.helper.model.model class method)": [[1, "bailo.helper.model.Model.from_id"]], "from_id() (bailo.helper.schema.schema class method)": [[1, "bailo.helper.schema.Schema.from_id"]], "from_mlflow() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.from_mlflow"]], "from_mlflow() (bailo.helper.model.model class method)": [[1, "bailo.helper.model.Model.from_mlflow"]], "from_version() (bailo.helper.release.release class method)": [[1, "bailo.helper.release.Release.from_version"]], "get_all_schema_ids() (bailo.helper.schema.schema static method)": [[1, "bailo.helper.schema.Schema.get_all_schema_ids"]], "get_card_latest() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.get_card_latest"]], "get_card_revision() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.get_card_revision"]], "get_image() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_image"]], "get_images() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_images"]], "get_latest_release() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_latest_release"]], "get_release() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_release"]], "get_releases() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.get_releases"]], "get_roles() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.get_roles"]], "get_user_roles() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.get_user_roles"]], "log_artifacts() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.log_artifacts"]], "log_dataset() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.log_dataset"]], "log_metrics() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.log_metrics"]], "log_params() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.log_params"]], "model_card (bailo.helper.model.model property)": [[1, "bailo.helper.model.Model.model_card"]], "model_card_schema (bailo.helper.model.model property)": [[1, "bailo.helper.model.Model.model_card_schema"]], "model_card_version (bailo.helper.model.model property)": [[1, "bailo.helper.model.Model.model_card_version"]], "publish() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.publish"]], "search() (bailo.helper.model.model class method)": [[1, "bailo.helper.model.Model.search"]], "start_run() (bailo.helper.model.experiment method)": [[1, "bailo.helper.model.Experiment.start_run"]], "update() (bailo.helper.access_request.accessrequest method)": [[1, "bailo.helper.access_request.AccessRequest.update"]], "update() (bailo.helper.entry.entry method)": [[1, "bailo.helper.entry.Entry.update"]], "update() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.update"]], "update_data_card() (bailo.helper.datacard.datacard method)": [[1, "bailo.helper.datacard.Datacard.update_data_card"]], "update_model_card() (bailo.helper.model.model method)": [[1, "bailo.helper.model.Model.update_model_card"]], "upload() (bailo.helper.release.release method)": [[1, "bailo.helper.release.Release.upload"]], "version (bailo.helper.release.release property)": [[1, "bailo.helper.release.Release.version"]], "bailo": [[2, "module-bailo"]]}}) \ No newline at end of file diff --git a/backend/python-docs/_build/html/_modules/bailo/core/agent.html b/backend/python-docs/_build/html/_modules/bailo/core/agent.html index 7f0eee259..2dee79847 100644 --- a/backend/python-docs/_build/html/_modules/bailo/core/agent.html +++ b/backend/python-docs/_build/html/_modules/bailo/core/agent.html @@ -91,9 +91,14 @@

    Source code for bailo.core.agent

     from json import JSONDecodeError
     
     import requests
    +import os
    +import getpass
    +import logging
     from requests.auth import HTTPBasicAuth
     from bailo.core.exceptions import BailoException, ResponseException
     
    +logger = logging.getLogger(__name__)
    +
     
     
    [docs] @@ -103,9 +108,21 @@

    Source code for bailo.core.agent

         Wraps each request in an exception handler that maps API errors to Python Bailo errors, among status codes less than 400.
         """
     
    +
    +[docs] + def __init__( + self, + verify: str | bool = True, + ): + """Initiate a standard agent. + + :param verify: Path to certificate authority file, or bool for SSL verification. + """ + self.verify = verify
    + + def __request(self, method, *args, **kwargs): - if "verify" not in kwargs: - kwargs["verify"] = True + kwargs["verify"] = self.verify res = requests.request(method, *args, **kwargs) @@ -175,39 +192,40 @@

    Source code for bailo.core.agent

             :param key: Path to key file
             :param auth: Path to certificate authority file
             """
    +        super().__init__(verify=auth)
    +
             self.cert = cert
    -        self.key = key
    -        self.auth = auth
    + self.key = key
    [docs] def get(self, *args, **kwargs): - return super().get(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
    + return super().get(*args, cert=(self.cert, self.key), **kwargs)
    [docs] def post(self, *args, **kwargs): - return super().post(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
    + return super().post(*args, cert=(self.cert, self.key), **kwargs)
    [docs] def put(self, *args, **kwargs): - return super().put(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
    + return super().put(*args, cert=(self.cert, self.key), **kwargs)

    [docs] def patch(self, *args, **kwargs): - return super().patch(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
    + return super().patch(*args, cert=(self.cert, self.key), **kwargs)
    [docs] def delete(self, *args, **kwargs): - return super().delete(*args, cert=(self.cert, self.key), verify=self.auth, **kwargs)
    + return super().delete(*args, cert=(self.cert, self.key), **kwargs)
    @@ -219,14 +237,36 @@

    Source code for bailo.core.agent

     [docs]
         def __init__(
             self,
    -        access_key: str,
    -        secret_key: str,
    +        access_key: str | None = None,
    +        secret_key: str | None = None,
         ):
             """Initiate an agent for API token authentication.
     
             :param access_key: Access key
             :param secret_key: Secret key
             """
    +        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
             self.basic = HTTPBasicAuth(access_key, secret_key)
    diff --git a/backend/python-docs/_build/html/_modules/bailo/core/client.html b/backend/python-docs/_build/html/_modules/bailo/core/client.html index c3befcad7..ba71314c0 100644 --- a/backend/python-docs/_build/html/_modules/bailo/core/client.html +++ b/backend/python-docs/_build/html/_modules/bailo/core/client.html @@ -150,6 +150,7 @@

    Source code for bailo.core.client

     [docs]
         def get_models(
             self,
    +        kind: EntryKind = EntryKind.MODEL,
             task: str | None = None,
             libraries: list[str] | None = None,
             filters: list[str] | None = None,
    @@ -157,9 +158,10 @@ 

    Source code for bailo.core.client

         ):
             """Find and returns a list of models based on provided search terms.
     
    +        :param kind: Either a Model or a Datacard
             :param task: Model task (e.g. image classification), defaults to None
    -        :param libraries: Model library (e.g. TensorFlow), defaults to []
    -        :param filters: Custom filters, defaults to []
    +        :param libraries: Model library (e.g. TensorFlow), defaults to None
    +        :param filters: Custom filters, defaults to None
             :param search: String to be located in model cards, defaults to ""
             :return: JSON response object
             """
    diff --git a/backend/python-docs/_build/html/_modules/bailo/core/enums.html b/backend/python-docs/_build/html/_modules/bailo/core/enums.html
    index 54a519b80..dbe12b7db 100644
    --- a/backend/python-docs/_build/html/_modules/bailo/core/enums.html
    +++ b/backend/python-docs/_build/html/_modules/bailo/core/enums.html
    @@ -135,6 +135,17 @@ 

    Source code for bailo.core.enums

         MODEL = "model"
         DATACARD = "data-card"
    + + +
    +[docs] +class MinimalSchema(ValuedEnum): + """A minimal schema.""" + + MODEL = "minimal-general-v10" + DATACARD = "minimal-data-card-v10" + ACCESS_REQUEST = "minimal-access-request-general-v10"
    +
    diff --git a/backend/python-docs/_build/html/_modules/bailo/helper/access_request.html b/backend/python-docs/_build/html/_modules/bailo/helper/access_request.html index 00b9bd875..1dbe84fbd 100644 --- a/backend/python-docs/_build/html/_modules/bailo/helper/access_request.html +++ b/backend/python-docs/_build/html/_modules/bailo/helper/access_request.html @@ -55,6 +55,7 @@

    Notebooks:

    • Managing Access Requests
    • +
    • Managing Datacards
    • Experiment Tracking with Bailo & MLFlow
    • Managing Models & Releases (ResNet-50 Example with PyTorch)
    • Managing Schemas
    • @@ -88,8 +89,12 @@

      Source code for bailo.helper.access_request

       from __future__ import annotations
       
       from typing import Any
      +import logging
       
       from bailo.core.client import Client
      +from bailo.core.enums import MinimalSchema
      +
      +logger = logging.getLogger(__name__)
       
       
       
      @@ -144,6 +149,8 @@

      Source code for bailo.helper.access_request

       
               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,
      @@ -158,7 +165,9 @@ 

      Source code for bailo.helper.access_request

       
      [docs] @classmethod - def create(cls, client: Client, model_id: str, schema_id: str, metadata: Any) -> AccessRequest: + def create( + cls, client: Client, model_id: str, metadata: Any, schema_id: str = MinimalSchema.ACCESS_REQUEST + ) -> AccessRequest: """Make an access request for the model. Posts an access request to Bailo to be reviewed @@ -166,7 +175,7 @@

      Source code for bailo.helper.access_request

               :param client: A client object used to interact with Bailo
               :param name: The name of the access request
               :param model_id: A unique model ID within Bailo
      -        :param schema_id: A unique schema ID
      +        :param schema_id: A unique schema ID, defaults to minimal-access-request-general-v10
               :return: JSON response object
               """
               access_request_json = client.post_access_request(model_id, metadata, schema_id)["accessRequest"]
      @@ -176,6 +185,10 @@ 

      Source code for bailo.helper.access_request

               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,
      @@ -195,6 +208,9 @@ 

      Source code for bailo.helper.access_request

               :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
      @@ -202,7 +218,9 @@

      Source code for bailo.helper.access_request

       [docs]
           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)
      + 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: diff --git a/backend/python-docs/_build/html/_modules/bailo/helper/datacard.html b/backend/python-docs/_build/html/_modules/bailo/helper/datacard.html index 3f662e7f3..dded0c30c 100644 --- a/backend/python-docs/_build/html/_modules/bailo/helper/datacard.html +++ b/backend/python-docs/_build/html/_modules/bailo/helper/datacard.html @@ -89,12 +89,15 @@

      Source code for bailo.helper.datacard

       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__)
      +
       
       
      [docs] @@ -150,9 +153,12 @@

      Source code for bailo.helper.datacard

               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,
      @@ -179,6 +185,8 @@ 

      Source code for bailo.helper.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,
      diff --git a/backend/python-docs/_build/html/_modules/bailo/helper/entry.html b/backend/python-docs/_build/html/_modules/bailo/helper/entry.html
      index 63ab383e8..3d242e5c1 100644
      --- a/backend/python-docs/_build/html/_modules/bailo/helper/entry.html
      +++ b/backend/python-docs/_build/html/_modules/bailo/helper/entry.html
      @@ -89,11 +89,15 @@ 

      Source code for bailo.helper.entry

       from __future__ import annotations
       
       from typing import Any
      +import logging
      +import warnings
       
       from bailo.core.client import Client
      -from bailo.core.enums import EntryKind, ModelVisibility
      +from bailo.core.enums import EntryKind, ModelVisibility, MinimalSchema
       from bailo.core.exceptions import BailoException
       
      +logger = logging.getLogger(__name__)
      +
       
       
      [docs] @@ -130,18 +134,28 @@

      Source code for bailo.helper.entry

                   description=self.description,
                   visibility=self.visibility,
               )
      -        self._unpack(res["model"])
      + self._unpack(res["model"]) + + logger.info(f"ID %s updated locally and on server.", self.id)
      [docs] - def card_from_schema(self, schema_id: str) -> None: + def card_from_schema(self, schema_id: str | None = None) -> None: """Create a card using a schema on Bailo. - :param schema_id: A unique schema ID + :param schema_id: A unique schema ID, defaults to None. If None, either minimal-general-v10 or minimal-data-card-v10 is used """ + if schema_id is None: + if self.kind == EntryKind.MODEL: + schema_id = MinimalSchema.MODEL + if self.kind == EntryKind.DATACARD: + schema_id = MinimalSchema.DATACARD + res = self.client.model_card_from_schema(model_id=self.id, schema_id=schema_id) - self.__unpack_card(res["card"])
      + self.__unpack_card(res["card"]) + + logger.info(f"Card for ID %s successfully created using schema ID %s.", self.id, schema_id)
      @@ -161,8 +175,11 @@

      Source code for bailo.helper.entry

               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}")
      + warnings.warn( + f"ID {self.id} does not have any associated cards. If needed, create a card with the .card_from_schema() method." + )
      @@ -173,7 +190,9 @@

      Source code for bailo.helper.entry

               :param version: Entry card version
               """
               res = self.client.get_model_card(model_id=self.id, version=version)
      -        self.__unpack_card(res["modelCard"])
      + self.__unpack_card(res["modelCard"]) + + logger.info(f"Card version %s for ID %s successfully retrieved.", version, self.id)
      @@ -207,6 +226,8 @@

      Source code for bailo.helper.entry

               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"]
      @@ -217,6 +238,8 @@ 

      Source code for bailo.helper.entry

               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"]
      @@ -224,7 +247,9 @@ 

      Source code for bailo.helper.entry

               try:
                   self._card = res["metadata"]
               except KeyError:
      -            self._card = None
      + self._card = None + + logger.info(f"Card attributes for ID %s successfully unpacked.", self.id)
      diff --git a/backend/python-docs/_build/html/_modules/bailo/helper/model.html b/backend/python-docs/_build/html/_modules/bailo/helper/model.html index 56d39feb0..f107ce826 100644 --- a/backend/python-docs/_build/html/_modules/bailo/helper/model.html +++ b/backend/python-docs/_build/html/_modules/bailo/helper/model.html @@ -92,9 +92,11 @@

      Source code for bailo.helper.model

       import shutil
       import tempfile
       from typing import Any
      +import logging
      +import warnings
       
       from bailo.core.client import Client
      -from bailo.core.enums import EntryKind, ModelVisibility
      +from bailo.core.enums import EntryKind, ModelVisibility, MinimalSchema
       from bailo.core.exceptions import BailoException
       from bailo.core.utils import NestedDict
       from bailo.helper.entry import Entry
      @@ -108,6 +110,8 @@ 

      Source code for bailo.helper.model

       except ImportError:
           ml_flow = False
       
      +logger = logging.getLogger(__name__)
      +
       
       
      [docs] @@ -158,9 +162,12 @@

      Source code for bailo.helper.model

               res = client.post_model(
                   name=name, kind=EntryKind.MODEL, description=description, team_id=team_id, visibility=visibility
               )
      +        model_id = res["model"]["id"]
      +        logger.info(f"Model successfully created on server with ID %s.", model_id)
      +
               model = cls(
                   client=client,
      -            model_id=res["model"]["id"],
      +            model_id=model_id,
                   name=name,
                   description=description,
                   visibility=visibility,
      @@ -185,6 +192,8 @@ 

      Source code for bailo.helper.model

               if res["kind"] != "model":
                   raise BailoException(f"ID {model_id} does not belong to a model. Did you mean to use Datacard.from_id()?")
       
      +        logger.info(f"Model %s successfully retrieved from server.", model_id)
      +
               model = cls(
                   client=client,
                   model_id=model_id,
      @@ -198,6 +207,126 @@ 

      Source code for bailo.helper.model

               return model
      +
      +[docs] + @classmethod + def search( + cls, + client: Client, + task: str | None = None, + libraries: list[str] | None = None, + filters: list[str] | None = None, + search: str = "", + ) -> list[Model]: + """Return a list of model objects from Bailo, based on search parameters. + + :param client: A client object used to interact with Bailo + :param task: Model task (e.g. image classification), defaults to None + :param libraries: Model library (e.g. TensorFlow), defaults to None + :param filters: Custom filters, defaults to None + :param search: String to be located in model cards, defaults to "" + :return: List of model objects + """ + res = client.get_models(kind=EntryKind.MODEL, task=task, libraries=libraries, filters=filters, search=search) + models = [] + + for model in res["models"]: + res_model = client.get_model(model_id=model["id"])["model"] + model_obj = cls(client=client, model_id=model["id"], name=model["name"], description=model["description"]) + model_obj._unpack(res_model) + model_obj.get_card_latest() + models.append(model_obj) + + return models
      + + +
      +[docs] + @classmethod + def from_mlflow( + cls, + client: Client, + mlflow_uri: str, + team_id: str, + name: str, + schema_id: str = MinimalSchema.MODEL, + version: str | None = None, + files: bool = True, + visibility: ModelVisibility | None = None, + ) -> Model: + """Import an MLFlow Model into Bailo. + + :param client: A client object used to interact with Bailo + :param mlflow_uri: MLFlow server URI + :param team_id: A unique team ID + :param name: Name of model (on MLFlow). Same name will be used on Bailo + :param schema_id: A unique schema ID, only required when files is True, defaults to minimal-general-v10 + :param version: Specific MLFlow model version to import, defaults to None + :param files: Import files?, defaults to True + :param visibility: Visibility of model on Bailo, using ModelVisibility enum (e.g Public or Private), defaults to None + :return: A model object + """ + if not ml_flow: + raise ImportError("Optional MLFlow dependencies (needed for this method) are not installed.") + + mlflow_client = mlflow.tracking.MlflowClient(tracking_uri=mlflow_uri) + mlflow.set_tracking_uri(mlflow_uri) + filter_string = f"name = '{name}'" + + res = mlflow_client.search_model_versions(filter_string=filter_string, order_by=["version_number DESC"]) + if not len(res): + raise BailoException("No MLFlow models found. Are you sure the name/alias/version provided is correct?") + + sel_model = None + if version: + for model in res: + if model.version == version: + sel_model = model + else: + sel_model = res[0] + + if sel_model is None: + raise BailoException("No MLFlow model found. Are you sure the name/alias/version provided is correct?") + + name = sel_model.name + description = sel_model.description + " Imported from MLFlow." + bailo_res = client.post_model( + name=name, kind=EntryKind.MODEL, description=description, team_id=team_id, visibility=visibility + ) + model_id = bailo_res["model"]["id"] + logger.info(f"MLFlow model successfully imported to Bailo with ID %s.", model_id) + + model = cls( + client=client, + model_id=model_id, + name=name, + description=description, + visibility=visibility, + ) + model._unpack(bailo_res["model"]) + + if files: + model.card_from_schema(schema_id=schema_id) + release = model.create_release(version=Version.coerce(str(sel_model.version)), notes=" ") + run_id = sel_model.run_id + if run_id is None: + raise BailoException( + "MLFlow model does not have an assosciated run_id, therefore artifacts cannot be transfered." + ) + + mlflow_run = mlflow_client.get_run(run_id) + artifact_uri = mlflow_run.info.artifact_uri + if artifact_uri is None: + raise BailoException("Artifact URI could not be found, therefore artifacts cannot be transfered.") + + if len(mlflow.artifacts.list_artifacts(artifact_uri=artifact_uri)): + temp_dir = os.path.join(tempfile.gettempdir(), "mlflow_model") + mlflow_dir = os.path.join(temp_dir, f"mlflow_{run_id}") + mlflow.artifacts.download_artifacts(artifact_uri=artifact_uri, dst_path=mlflow_dir) + release.upload(mlflow_dir) + return model
      + +
      [docs] def update_model_card(self, model_card: dict[str, Any] | None = None) -> None: @@ -271,6 +400,8 @@

      Source code for bailo.helper.model

               for release in res["releases"]:
                   releases.append(self.get_release(version=release["semver"]))
       
      +        logger.info(f"Successfully retrieved all releases for model %s.", self.model_id)
      +
               return releases
      @@ -295,6 +426,10 @@

      Source code for bailo.helper.model

               releases = self.get_releases()
               if releases == []:
                   raise BailoException("This model has no releases.")
      +
      +        latest_release = max(releases)
      +        logger.info(f"latest_release (%s) for %s retrieved successfully.", str(latest_release.version), self.model_id)
      +
               return max(releases)
      @@ -307,6 +442,8 @@

      Source code for bailo.helper.model

               """
               res = self.client.get_all_images(model_id=self.model_id)
       
      +        logger.info(f"Images for %s retreived successfully.", self.model_id)
      +
               return res["images"]
      @@ -342,7 +479,13 @@

      Source code for bailo.helper.model

       
           @model_card_schema.setter
           def model_card_schema(self, value):
      -        self._card_schema = value
      + self._card_schema = value + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({str(self)})" + + def __str__(self) -> str: + return f"{self.model_id}"
      @@ -407,7 +550,7 @@

      Source code for bailo.helper.model

               self.raw.append(self.run_data)
       
               if not is_mlflow:
      -            print(f"Bailo tracking run {self.run}.")
      + logger.info(f"Bailo tracking run %d.", self.run)
      @@ -459,53 +602,77 @@

      Source code for bailo.helper.model

               :param experiment_id: MLFlow Tracking experiment ID
               :raises ImportError: Import error if MLFlow not installed
               """
      -        if ml_flow:
      -            client = mlflow.tracking.MlflowClient(tracking_uri=tracking_uri)
      -            runs = client.search_runs(experiment_id)
      -
      -            for run in runs:
      -                data = run.data
      -                info = run.info
      -                inputs = run.inputs
      -
      -                artifact_uri = info.artifact_uri
      -                run_id = info.run_id
      -                status = info.status
      -                datasets = inputs.dataset_inputs
      -                datasets_str = [dataset.name for dataset in datasets]
      -
      -                artifacts = []
      -
      -                # MLFlow run must be status FINISHED
      -                if status != "FINISHED":
      -                    continue
      -
      -                if len(mlflow.artifacts.list_artifacts(artifact_uri=artifact_uri)) > 0:
      -                    mlflow_dir = os.path.join(self.temp_dir, f"mlflow_{run_id}")
      -                    mlflow.artifacts.download_artifacts(artifact_uri=artifact_uri, dst_path=mlflow_dir)
      -                    artifacts.append(mlflow_dir)
      -
      -                self.start_run(is_mlflow=True)
      -                self.log_params(data.params)
      -                self.log_metrics(data.metrics)
      -                self.log_artifacts(artifacts)
      -                self.log_dataset("".join(datasets_str))
      -                self.run_data["run"] = info.run_id
      +        if not ml_flow:
      +            raise ImportError("Optional MLFlow dependencies (needed for this method) are not installed.")
      +
      +        client = mlflow.tracking.MlflowClient(tracking_uri=tracking_uri)
      +        runs = client.search_runs(experiment_id)
      +        if len(runs):
      +            logger.info(
      +                f"Successfully retrieved MLFlow experiment %s from tracking server. %d were found.",
      +                experiment_id,
      +                len(runs),
      +            )
               else:
      -            raise ImportError("Optional MLFlow dependencies (needed for this method) are not installed.")
      + warnings.warn( + f"MLFlow experiment {experiment_id} does not have any runs and publishing requires at least one valid run. Are you sure the ID is correct?" + ) + + for run in runs: + data = run.data + info = run.info + inputs = run.inputs + + artifact_uri = info.artifact_uri + run_id = info.run_id + status = info.status + datasets = inputs.dataset_inputs + datasets_str = [dataset.name for dataset in datasets] + + artifacts = [] + + # MLFlow run must be status FINISHED + if status != "FINISHED": + continue + + if len(mlflow.artifacts.list_artifacts(artifact_uri=artifact_uri)): + mlflow_dir = os.path.join(self.temp_dir, f"mlflow_{run_id}") + mlflow.artifacts.download_artifacts(artifact_uri=artifact_uri, dst_path=mlflow_dir) + artifacts.append(mlflow_dir) + logger.info( + f"Successfully downloaded artifacts for MLFlow experiment %s to %s.", experiment_id, mlflow_dir + ) + + self.start_run(is_mlflow=True) + self.log_params(data.params) + self.log_metrics(data.metrics) + self.log_artifacts(artifacts) + self.log_dataset("".join(datasets_str)) + self.run_data["run"] = info.run_id + + logger.info(f"Successfully imported MLFlow experiment %s.", experiment_id)
      [docs] - def publish(self, mc_loc: str, run_id: str, semver: str = "0.1.0", notes: str = ""): + def publish( + self, + mc_loc: str, + semver: str = "0.1.0", + notes: str = "", + run_id: str | None = None, + select_by: str | None = None, + ): """Publishes a given experiments results to the model card. :param mc_loc: Location of metrics in the model card (e.g. performance.performanceMetrics) - :param run_id: Local experiment run ID to be selected :param semver: Semantic version of release to create (if artifacts present), defaults to 0.1.0 or next :param notes: Notes for release, defaults to "" + :param run_id: Local experiment run ID to be selected, defaults to None + :param select_by: String describing experiment to be selected (e.g. "accuracy MIN|MAX"), defaults to None ..note:: mc_loc is dependent on the model card schema being used + ..warning:: User must specify either run_id or select_by, otherwise the code will error """ mc = self.model.model_card if mc is None: @@ -513,15 +680,23 @@

      Source code for bailo.helper.model

       
               mc = NestedDict(mc)
       
      -        if len(self.raw) > 0:
      +        if len(self.raw) == 0:
      +            raise BailoException(f"This experiment has no runs to publish.")
      +        if (select_by is None) and (run_id is None):
      +            raise BailoException(
      +                "Either select_by (e.g. 'accuracy MIN|MAX') or run_id is required to publish an experiment run."
      +            )
      +
      +        if (select_by is not None) and (run_id is None):
      +            sel_run = self.__select_run(select_by=select_by)
      +
      +        if run_id is not None:
                   for run in self.raw:
                       if run["run"] == run_id:
                           sel_run = run
                           break
                   else:
                       raise NameError(f"Run {run_id} does not exist.")
      -        else:
      -            raise BailoException(f"This experiment has no runs to publish.")
       
               values = []
       
      @@ -536,7 +711,7 @@ 

      Source code for bailo.helper.model

       
               # Creating a release and uploading artifacts (if artifacts present)
               artifacts = sel_run["artifacts"]
      -        if len(artifacts) > 0:
      +        if len(artifacts):
                   # Create new release
                   try:
                       release_latest_version = self.model.get_latest_release().version
      @@ -548,12 +723,52 @@ 

      Source code for bailo.helper.model

                   notes = f"{notes} (Run ID: {run_id})"
                   release_new = self.model.create_release(version=release_new_version, minor=True, notes=notes)
       
      +            logger.info(
      +                f"Uploading %d artifacts to version %s of model %s.",
      +                len(artifacts),
      +                str(release_new_version),
      +                self.model.model_id,
      +            )
      +
                   for artifact in artifacts:
                       release_new.upload(path=artifact)
       
                   if os.path.exists(self.temp_dir) and os.path.isdir(self.temp_dir):
      -                shutil.rmtree(self.temp_dir)
      -
      + shutil.rmtree(self.temp_dir) + + logger.info(f"Successfully published experiment run %s to model %s.", str(run_id), self.model.model_id)
      + + + def __select_run(self, select_by: str): + # Parse target and order from select_by string + select_by_split = select_by.split(" ") + if len(select_by_split) != 2: + raise BailoException("Invalid select_by string. Expected format is 'metric_name MIN|MAX'.") + order_str = select_by_split[1].upper() + order_opt = ["MIN", "MAX"] + if order_str not in order_opt: + raise BailoException(f"Runs can only be ordered by MIN or MAX, not {order_str}.") + target_str = select_by_split[0] + + # Extract target value for each run + runs = self.raw + for run in runs: + metrics = run["metrics"] + for metric in metrics: + target_value = metric.get(target_str, None) + if target_value is not None: + run["target"] = target_value + else: + raise BailoException( + f"Target '{target_str}' could not be found in at least one experiment run, or is not an integer. Therefore ordering cannot take place." + ) + + # Sort experiment runs by target value into ascending order, and select first or last depending on order_str + ordered_runs = sorted(runs, key=lambda run: run["target"]) + if order_str == "MIN": + return ordered_runs[0] + if order_str == "MAX": + return ordered_runs[-1]
      diff --git a/backend/python-docs/_build/html/_modules/bailo/helper/release.html b/backend/python-docs/_build/html/_modules/bailo/helper/release.html index 7672b0c2e..f8d67f2cc 100644 --- a/backend/python-docs/_build/html/_modules/bailo/helper/release.html +++ b/backend/python-docs/_build/html/_modules/bailo/helper/release.html @@ -92,7 +92,9 @@

      Source code for bailo.helper.release

       import fnmatch
       import shutil
       from io import BytesIO
      -from typing import Any, Union
      +from typing import Any
      +import logging
      +import warnings
       from tqdm import tqdm
       from tqdm.utils import CallbackIOWrapper
       
      @@ -102,6 +104,7 @@ 

      Source code for bailo.helper.release

       from semantic_version import Version
       
       BLOCK_SIZE = 1024
      +logger = logging.getLogger(__name__)
       
       
       
      @@ -144,8 +147,6 @@

      Source code for bailo.helper.release

               if images is None:
                   images = []
       
      -        if isinstance(version, str):
      -            version = Version(version)
               self.version = version
       
               self.model_card_version = model_card_version
      @@ -194,6 +195,7 @@ 

      Source code for bailo.helper.release

                   minor,
                   draft,
               )
      +        logger.info(f"Release %s successfully created on server for model with ID %s.", str(version), model_id)
       
               return cls(
                   client,
      @@ -227,6 +229,8 @@ 

      Source code for bailo.helper.release

               minor = res["minor"]
               draft = res["draft"]
       
      +        logger.info(f"Release %s of model ID %s successfully retrieved from server.", str(version), model_id)
      +
               return cls(
                   client,
                   model_id,
      @@ -252,6 +256,7 @@ 

      Source code for bailo.helper.release

               :return: A JSON response object
               """
               res = self.client.get_download_by_filename(self.model_id, str(self.version), filename)
      +        logger.info(f"Downloading file %s from version %s of %s...", filename, str(self.version), self.model_id)
       
               if write:
                   if path is None:
      @@ -276,6 +281,12 @@ 

      Source code for bailo.helper.release

                               t.update(len(data))
                               f.write(data)
       
      +            logger.info(f"File written to %s", path)
      +
      +        logger.info(
      +            f"Downloading of file %s from version %s of %s completed.", filename, str(self.version), self.model_id
      +        )
      +
               return res
      @@ -294,6 +305,7 @@

      Source code for bailo.helper.release

               if files_metadata == []:
                   raise BailoException("Release has no associated files.")
               file_names = [file_metadata["name"] for file_metadata in files_metadata]
      +        orig_file_names = file_names
       
               if isinstance(include, str):
                   include = [include]
      @@ -308,6 +320,13 @@ 

      Source code for bailo.helper.release

                       file for file in file_names if not any([fnmatch.fnmatch(file, pattern) for pattern in exclude])
                   ]
       
      +        logger.info(
      +            f"Downloading %d of %%d files for version %s of %s...",
      +            len(file_names),
      +            len(orig_file_names),
      +            str(self.version),
      +            {self.model_id},
      +        )
               os.makedirs(path, exist_ok=True)
               for file in file_names:
                   file_path = os.path.join(path, file)
      @@ -320,15 +339,17 @@ 

      Source code for bailo.helper.release

               """Upload a file to the release.
       
               :param path: The path, or name of file or directory to be uploaded
      -        :param data: A BytesIO object if not loading from disk
      +        :param data: A BytesIO object if not loading from disk, defaults to None
       
               :return: The unique file ID of the file uploaded
               ..note:: If path provided is a directory, it will be uploaded as a zip
               """
      +        logger.info(f"Uploading file(s) to version %s of %s...", str(self.version), self.model_id)
               name = os.path.split(path)[-1]
       
               if data is None:
                   if is_zip := os.path.isdir(path):
      +                logger.info(f"Given path (%s) is a directory. This will be converted to a zip file for upload.", path)
                       shutil.make_archive(name, "zip", path)
                       path = f"{name}.zip"
                       name = path
      @@ -358,6 +379,8 @@ 

      Source code for bailo.helper.release

               self.update()
               if not isinstance(data, BytesIO):
                   data.close()
      +        logger.info(f"Upload of file %s to version %s of %s complete.", name, str(self.version), self.model_id)
      +
               return res["file"]["id"]
      @@ -370,7 +393,7 @@

      Source code for bailo.helper.release

               """
               return self.client.put_release(
                   self.model_id,
      -            str(self.version),
      +            str(self.__version_raw),
                   self.notes,
                   self.draft,
                   self.files,
      @@ -386,19 +409,44 @@ 

      Source code for bailo.helper.release

               :return: JSON Response object
               """
               self.client.delete_release(self.model_id, str(self.version))
      +        logger.info(f"Release %s of %s successfully deleted.", str(self.version), self.model_id)
      +
               return True
      + @property + def version(self): + return self.__version_obj + + @version.setter + def version(self, value): + if ("_Release__version_obj" not in self.__dict__) and ("_Release__version_raw" not in self.__dict__): + if isinstance(value, str): + if value.startswith("v"): + value = value[1:] + version_obj = Version.coerce(value) + elif isinstance(value, Version): + version_obj = value + else: + raise TypeError("Provided version not of a supported type.") + + self.__version_obj = version_obj + self.__version_raw = value + else: + raise BailoException( + "Version attribute has already been set once. You must create a new Release object to create a new version, or use Model.create_release()." + ) + def __repr__(self) -> str: return f"{self.__class__.__name__}({str(self)})" def __str__(self) -> str: - return f"{self.model_id} v{self.version}" + return f"{self.model_id} v{self.__version_obj}" def __eq__(self, other) -> bool: if not isinstance(other, self.__class__): return NotImplemented - return self.version == other.version + return self.__version_obj == other.__version_obj def __ne__(self, other): if not isinstance(other, self.__class__): @@ -408,25 +456,25 @@

      Source code for bailo.helper.release

           def __lt__(self, other):
               if not isinstance(other, self.__class__):
                   return NotImplemented
      -        return self.version < other.version
      +        return self.__version_obj < other.__version_obj
       
           def __le__(self, other):
               if not isinstance(other, self.__class__):
                   return NotImplemented
      -        return self.version <= other.version
      +        return self.__version_obj <= other.__version_obj
       
           def __gt__(self, other):
               if not isinstance(other, self.__class__):
                   return NotImplemented
      -        return self.version > other.version
      +        return self.__version_obj > other.__version_obj
       
           def __ge__(self, other):
               if not isinstance(other, self.__class__):
                   return NotImplemented
      -        return self.version >= other.version
      +        return self.__version_obj >= other.__version_obj
       
           def __hash__(self) -> int:
      -        return hash((self.model_id, self.version))
      + return hash((self.model_id, self.__version_obj))
      diff --git a/backend/python-docs/_build/html/_modules/bailo/helper/schema.html b/backend/python-docs/_build/html/_modules/bailo/helper/schema.html index 135fce1e1..1aaa25a91 100644 --- a/backend/python-docs/_build/html/_modules/bailo/helper/schema.html +++ b/backend/python-docs/_build/html/_modules/bailo/helper/schema.html @@ -55,6 +55,7 @@

      Notebooks:

      • Managing Access Requests
      • +
      • Managing Datacards
      • Experiment Tracking with Bailo & MLFlow
      • Managing Models & Releases (ResNet-50 Example with PyTorch)
      • Managing Schemas
      • @@ -87,11 +88,14 @@

        Source code for bailo.helper.schema

         from __future__ import annotations
         
        -from typing import Any
        +import logging
        +from typing import Any, List
         
         from bailo.core.client import Client
         from bailo.core.enums import SchemaKind
         
        +logger = logging.getLogger(__name__)
        +
         
         
        [docs] @@ -155,6 +159,7 @@

        Source code for bailo.helper.schema

                 res = client.post_schema(
                     schema_id=schema_id, name=name, description=description, kind=kind, json_schema=json_schema
                 )
        +        logger.info(f"Schema successfully created on server with ID %s.", schema_id)
                 schema.__unpack(res["schema"])
         
                 return schema
        @@ -179,11 +184,26 @@

        Source code for bailo.helper.schema

                     json_schema={"temp": "temp"},
                 )
                 res = client.get_schema(schema_id=schema_id)
        +        logger.info(f"Schema %s successfully retrieved from server.", schema_id)
                 schema.__unpack(res["schema"])
         
                 return schema
        +
        +[docs] + @staticmethod + def get_all_schema_ids(client: Client, kind: SchemaKind | None = None) -> list[str]: + """Return all schema ids for a given type. + + :param client: A client object used to interact with Bailo + :param kind: Enum to define schema kind (e.g. Model or AccessRequest), defaults to None + :return: List of schema IDs + """ + all_schemas = client.get_all_schemas(kind=kind) + return [schema["id"] for schema in all_schemas["schemas"]]
        + + def __unpack(self, res) -> None: self.schema_id = res["id"] self.name = res["name"] @@ -194,7 +214,9 @@

        Source code for bailo.helper.schema

                 if kind == "model":
                     self.kind = SchemaKind.MODEL
                 if kind == "accessRequest":
        -            self.kind = SchemaKind.ACCESS_REQUEST
        + self.kind = SchemaKind.ACCESS_REQUEST + + logger.info(f"Attributes for Schema ID %s successfully unpacked.", self.schema_id)
        diff --git a/backend/python-docs/_build/html/_sources/notebooks/access_requests_demo.ipynb.txt b/backend/python-docs/_build/html/_sources/notebooks/access_requests_demo.ipynb.txt index 334f257fc..8ba5b485f 100644 --- a/backend/python-docs/_build/html/_sources/notebooks/access_requests_demo.ipynb.txt +++ b/backend/python-docs/_build/html/_sources/notebooks/access_requests_demo.ipynb.txt @@ -190,9 +190,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": ".venv", "language": "python", - "name": "python" + "name": "python3" }, "language_info": { "codemirror_mode": { diff --git a/backend/python-docs/_build/html/_sources/notebooks/datacards_demo.ipynb.txt b/backend/python-docs/_build/html/_sources/notebooks/datacards_demo.ipynb.txt index 7fa8bf248..d84816d45 100644 --- a/backend/python-docs/_build/html/_sources/notebooks/datacards_demo.ipynb.txt +++ b/backend/python-docs/_build/html/_sources/notebooks/datacards_demo.ipynb.txt @@ -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, diff --git a/backend/python-docs/_build/html/_sources/notebooks/experiment_tracking_demo.ipynb.txt b/backend/python-docs/_build/html/_sources/notebooks/experiment_tracking_demo.ipynb.txt index ed17d944f..d0ed12cf4 100644 --- a/backend/python-docs/_build/html/_sources/notebooks/experiment_tracking_demo.ipynb.txt +++ b/backend/python-docs/_build/html/_sources/notebooks/experiment_tracking_demo.ipynb.txt @@ -249,7 +249,19 @@ "## Publishing results to Bailo\n", "\n", "Experiment runs can be published to the model card using the `Experiment.publish()` method, **one at a time**. This is because the intended use is only to publish the most successful run.\n", - "Therefore, you must specify the **run_id** to publish, as well as specify the location of the metrics in your schema (in this case *performance.performanceMetrics* as per the schema we defined earlier)." + "Therefore, you must specify the **run_id** to publish, or specify an order so the client can select the best result. As well as this, you must specify the location of the metrics in your schema (in this case *performance.performanceMetrics* as per the schema we defined earlier).\n", + "\n", + "Examples for both scenarios can be seen below." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Publishing a specific run\n", + "\n", + "To publish a specific run, you must pass the `run_id` into the method. In this example, use one of the IDs we created in the previous steps." ] }, { @@ -266,7 +278,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "If successful, our metrics should now be under the **Performance** tab of your model card on the UI! Additionally, our artifact will have been published as a new release." + "### Publishing the best run\n", + "\n", + "To publish the best run, you must define what the best is for your use case. This can be done using the `select_by` parameter with a string e.g. `accuracy MIN|MAX`. Depending on the requirements, `accuracy` could be any metric you have defined in your experiment.\n", + "\n", + "In the below example, we will use `accuracy MAX` to publish the experiment run with the highest accuracy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "experiment_mlflow.publish(mc_loc=\"performance.performanceMetrics\", select_by=\"accuracy MAX\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If successful, our metrics should now be under the **Performance** tab of your model card on the UI! Additionally, our artifact will have been published as a new release (*this will have been done twice if you ran both the above steps*)." ] } ], diff --git a/backend/python-docs/_build/html/_sources/notebooks/models_and_releases_demo_pytorch.ipynb.txt b/backend/python-docs/_build/html/_sources/notebooks/models_and_releases_demo_pytorch.ipynb.txt index 8eacdfee8..040b49f50 100644 --- a/backend/python-docs/_build/html/_sources/notebooks/models_and_releases_demo_pytorch.ipynb.txt +++ b/backend/python-docs/_build/html/_sources/notebooks/models_and_releases_demo_pytorch.ipynb.txt @@ -79,7 +79,7 @@ "\n", "# Instantiating the Bailo client\n", "\n", - "client = Client(\"http://127.0.0.1:8080\") # <- INSERT BAILO URL (if not hosting locally)\n" + "client = Client(\"http://127.0.0.1:8080\") # <- INSERT BAILO URL (if not hosting locally)" ] }, { @@ -336,7 +336,7 @@ "metadata": {}, "outputs": [], "source": [ - "weights = torch.load(\"bailo_resnet50_weights.pth\")\n", + "weights = torch.load(\"downloads/resnet50_weights.pth\")\n", "torch_model = resnet50()\n", "torch_model.load_state_dict(weights)" ] @@ -348,6 +348,47 @@ "source": [ "If the message \"**All keys matched successfully**\" is displayed, we have successfully initated our model." ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Searching for models" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to fetching specific models, you can also use the `Model.search()` method to return a list of `Model()` objects that match your parameters. These parameters can be:\n", + "\n", + "* Task of the model (e.g. image classification).\n", + "* Libraries used for the model (e.g. PyTorch).\n", + "* Model card search (string to be found in model cards).\n", + "\n", + "In the below example, we'll just search for all models with no filters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "models = Model.search(client=client)\n", + "\n", + "print(models)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We should now have a list of `Model()` objects." + ] } ], "metadata": { diff --git a/backend/python-docs/_build/html/bailo.helper.html b/backend/python-docs/_build/html/bailo.helper.html index 39ff7ce8e..146c59239 100644 --- a/backend/python-docs/_build/html/bailo.helper.html +++ b/backend/python-docs/_build/html/bailo.helper.html @@ -96,6 +96,7 @@
      • Model.create_experiment()
      • Model.create_release()
      • Model.from_id()
      • +
      • Model.from_mlflow()
      • Model.get_image()
      • Model.get_images()
      • Model.get_latest_release()
      • @@ -104,6 +105,7 @@
      • Model.model_card
      • Model.model_card_schema
      • Model.model_card_version
      • +
      • Model.search()
      • Model.update_model_card()
      @@ -116,11 +118,13 @@
    • Release.from_version()
    • Release.update()
    • Release.upload()
    • +
    • Release.version
  • Schema
  • @@ -182,7 +186,7 @@
    -classmethod create(client: Client, model_id: str, schema_id: str, metadata: Any) AccessRequest[source]
    +classmethod create(client: Client, model_id: str, metadata: Any, schema_id: str = MinimalSchema.ACCESS_REQUEST) AccessRequest[source]

    Make an access request for the model.

    Posts an access request to Bailo to be reviewed

    @@ -191,7 +195,7 @@
  • client – A client object used to interact with Bailo

  • name – The name of the access request

  • model_id – A unique model ID within Bailo

  • -
  • schema_id – A unique schema ID

  • +
  • schema_id – A unique schema ID, defaults to minimal-access-request-general-v10

  • Returns:
    @@ -322,11 +326,11 @@

    Bases: object

    -card_from_schema(schema_id: str) None[source]
    +card_from_schema(schema_id: str | None = None) None[source]

    Create a card using a schema on Bailo.

    Parameters:
    -

    schema_id – A unique schema ID

    +

    schema_id – A unique schema ID, defaults to None. If None, either minimal-general-v10 or minimal-data-card-v10 is used

    @@ -490,19 +494,21 @@
    -publish(mc_loc: str, run_id: str, semver: str = '0.1.0', notes: str = '')[source]
    +publish(mc_loc: str, semver: str = '0.1.0', notes: str = '', run_id: str | None = None, select_by: str | None = None)[source]

    Publishes a given experiments results to the model card.

    Parameters:
    • mc_loc – Location of metrics in the model card (e.g. performance.performanceMetrics)

    • -
    • run_id – Local experiment run ID to be selected

    • semver – Semantic version of release to create (if artifacts present), defaults to 0.1.0 or next

    • notes – Notes for release, defaults to “”

    • +
    • run_id – Local experiment run ID to be selected, defaults to None

    • +
    • select_by – String describing experiment to be selected (e.g. “accuracy MIN|MAX”), defaults to None

    -

    ..note:: mc_loc is dependent on the model card schema being used

    +

    ..note:: mc_loc is dependent on the model card schema being used +..warning:: User must specify either run_id or select_by, otherwise the code will error

    @@ -603,6 +609,29 @@
    +
    +
    +classmethod from_mlflow(client: Client, mlflow_uri: str, team_id: str, name: str, schema_id: str = MinimalSchema.MODEL, version: str | None = None, files: bool = True, visibility: ModelVisibility | None = None) Model[source]
    +

    Import an MLFlow Model into Bailo.

    +
    +
    Parameters:
    +
      +
    • client – A client object used to interact with Bailo

    • +
    • mlflow_uri – MLFlow server URI

    • +
    • team_id – A unique team ID

    • +
    • name – Name of model (on MLFlow). Same name will be used on Bailo

    • +
    • schema_id – A unique schema ID, only required when files is True, defaults to minimal-general-v10

    • +
    • version – Specific MLFlow model version to import, defaults to None

    • +
    • files – Import files?, defaults to True

    • +
    • visibility – Visibility of model on Bailo, using ModelVisibility enum (e.g Public or Private), defaults to None

    • +
    +
    +
    Returns:
    +

    A model object

    +
    +
    +
    +
    get_image()[source]
    @@ -676,6 +705,26 @@ property model_card_version
    +
    +
    +classmethod search(client: Client, task: str | None = None, libraries: list[str] | None = None, filters: list[str] | None = None, search: str = '') list[Model][source]
    +

    Return a list of model objects from Bailo, based on search parameters.

    +
    +
    Parameters:
    +
      +
    • client – A client object used to interact with Bailo

    • +
    • task – Model task (e.g. image classification), defaults to None

    • +
    • libraries – Model library (e.g. TensorFlow), defaults to None

    • +
    • filters – Custom filters, defaults to None

    • +
    • search – String to be located in model cards, defaults to “”

    • +
    +
    +
    Returns:
    +

    List of model objects

    +
    +
    +
    +
    update_model_card(model_card: dict[str, Any] | None = None) None[source]
    @@ -813,7 +862,7 @@
    Parameters:
    • path – The path, or name of file or directory to be uploaded

    • -
    • data – A BytesIO object if not loading from disk

    • +
    • data – A BytesIO object if not loading from disk, defaults to None

    Returns:
    @@ -823,6 +872,11 @@

    ..note:: If path provided is a directory, it will be uploaded as a zip

    +
    +
    +property version
    +
    +
    @@ -879,6 +933,23 @@
    +
    +
    +static get_all_schema_ids(client: Client, kind: SchemaKind | None = None) list[str][source]
    +

    Return all schema ids for a given type.

    +
    +
    Parameters:
    +
      +
    • client – A client object used to interact with Bailo

    • +
    • kind – Enum to define schema kind (e.g. Model or AccessRequest), defaults to None

    • +
    +
    +
    Returns:
    +

    List of schema IDs

    +
    +
    +
    + diff --git a/backend/python-docs/_build/html/genindex.html b/backend/python-docs/_build/html/genindex.html index c33c85f2d..29343d6ba 100644 --- a/backend/python-docs/_build/html/genindex.html +++ b/backend/python-docs/_build/html/genindex.html @@ -104,14 +104,17 @@

    Index

    | S | T | U + | V

    _

  • Importing existing experiments from MLFlow into Bailo
  • -
  • Publishing results to Bailo
  • +
  • Publishing results to Bailo +
  • Managing Models & Releases (ResNet-50 Example with PyTorch)
  • @@ -282,7 +286,11 @@

    Importing existing experiments from MLFlow into Bailo

    Publishing results to Bailo

    -

    Experiment runs can be published to the model card using the Experiment.publish() method, one at a time. This is because the intended use is only to publish the most successful run. Therefore, you must specify the run_id to publish, as well as specify the location of the metrics in your schema (in this case performance.performanceMetrics as per the schema we defined earlier).

    +

    Experiment runs can be published to the model card using the Experiment.publish() method, one at a time. This is because the intended use is only to publish the most successful run. Therefore, you must specify the run_id to publish, or specify an order so the client can select the best result. As well as this, you must specify the location of the metrics in your schema (in this case performance.performanceMetrics as per the schema we defined earlier).

    +

    Examples for both scenarios can be seen below.

    +
    +

    Publishing a specific run

    +

    To publish a specific run, you must pass the run_id into the method. In this example, use one of the IDs we created in the previous steps.

    [ ]:
     
    @@ -291,7 +299,21 @@

    Publishing results to Bailo +

    Publishing the best run

    +

    To publish the best run, you must define what the best is for your use case. This can be done using the select_by parameter with a string e.g. accuracy MIN|MAX. Depending on the requirements, accuracy could be any metric you have defined in your experiment.

    +

    In the below example, we will use accuracy MAX to publish the experiment run with the highest accuracy.

    +
    +
    [ ]:
    +
    +
    +
    experiment_mlflow.publish(mc_loc="performance.performanceMetrics", select_by="accuracy MAX")
    +
    +
    +
    +

    If successful, our metrics should now be under the Performance tab of your model card on the UI! Additionally, our artifact will have been published as a new release (this will have been done twice if you ran both the above steps).

    +

    diff --git a/backend/python-docs/_build/html/notebooks/models_and_releases_demo_pytorch.html b/backend/python-docs/_build/html/notebooks/models_and_releases_demo_pytorch.html index 5c2dba1b1..0b40ea8d5 100644 --- a/backend/python-docs/_build/html/notebooks/models_and_releases_demo_pytorch.html +++ b/backend/python-docs/_build/html/notebooks/models_and_releases_demo_pytorch.html @@ -85,6 +85,7 @@
  • Loading the model using PyTorch
  • +
  • Searching for models
  • Managing Schemas
  • @@ -166,7 +167,7 @@

    Introduction# Instantiating the Bailo client client = Client("http://127.0.0.1:8080") # <- INSERT BAILO URL (if not hosting locally) -
    + @@ -325,7 +326,7 @@

    Loading the model using PyTorch
    [ ]:
     
    -
    weights = torch.load("bailo_resnet50_weights.pth")
    +
    weights = torch.load("downloads/resnet50_weights.pth")
     torch_model = resnet50()
     torch_model.load_state_dict(weights)
     
    @@ -334,6 +335,27 @@

    Loading the model using PyTorch +

    Searching for models

    +

    In addition to fetching specific models, you can also use the Model.search() method to return a list of Model() objects that match your parameters. These parameters can be:

    +
      +
    • Task of the model (e.g. image classification).

    • +
    • Libraries used for the model (e.g. PyTorch).

    • +
    • Model card search (string to be found in model cards).

    • +
    +

    In the below example, we’ll just search for all models with no filters.

    +
    +
    [ ]:
    +
    +
    +
    models = Model.search(client=client)
    +
    +print(models)
    +
    +
    +
    +

    We should now have a list of Model() objects.

    + diff --git a/backend/python-docs/_build/html/objects.inv b/backend/python-docs/_build/html/objects.inv index a1b0236bdfbfd53c8e0805b40c80c82fce957561..daceb86ed4f9f1601f3001d25a622be11e00efdc 100644 GIT binary patch delta 13054 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 M1I#o350?500J9-B$p8QV delta 12856 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 WVoamZZ&cM(GCRf Date: Tue, 16 Jul 2024 11:23:29 +0000 Subject: [PATCH 3/3] Python version bump to 2.5.0 --- lib/python/src/bailo/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/src/bailo/__init__.py b/lib/python/src/bailo/__init__.py index 290768c7d..cbf322233 100644 --- a/lib/python/src/bailo/__init__.py +++ b/lib/python/src/bailo/__init__.py @@ -8,8 +8,8 @@ import logging -# Package Version 2.4.0 -__version__ = "2.4.0" +# Package Version 2.5.0 +__version__ = "2.5.0" from bailo.core.agent import Agent, PkiAgent, TokenAgent