Skip to content

Notebooks

albert.collections.notebooks

NotebookBlock module-attribute

NotebookBlock = Annotated[
    _NotebookBlockUnion, Field(discriminator="type")
]

AlbertException

AlbertException(message: str)

Bases: Exception

Source code in src/albert/exceptions.py
def __init__(self, message: str):
    super().__init__(message)
    self.message = message

message instance-attribute

message = message

AlbertSession

AlbertSession(
    *,
    base_url: str,
    token: str | None = None,
    client_credentials: ClientCredentials | None = None,
    retries: int | None = None,
)

Bases: Session

A session that has a base URL, which is prefixed to all request URLs.

Parameters:

Name Type Description Default
base_url str

The base URL to prefix to all requests. (e.g., "https://sandbox.albertinvent.com")

required
retries int

The number of retries for failed requests. Defaults to 3.

None
client_credentials ClientCredentials | None

The client credentials for programmatic authentication. Optional if token is provided.

None
token str | None

The JWT token for authentication. Optional if client credentials are provided.

None

Methods:

Name Description
request
Source code in src/albert/session.py
def __init__(
    self,
    *,
    base_url: str,
    token: str | None = None,
    client_credentials: ClientCredentials | None = None,
    retries: int | None = None,
):
    super().__init__()
    self.base_url = base_url
    self.headers.update(
        {
            "Content-Type": "application/json",
            "Accept": "application/json",
            "User-Agent": f"albert-SDK V.{albert.__version__}",
        }
    )

    if token is None and client_credentials is None:
        raise ValueError("Either client credentials or token must be specified.")

    self._provided_token = token
    self._token_manager = (
        TokenManager(base_url, client_credentials) if client_credentials is not None else None
    )

    # Set up retry logic
    retries = retries if retries is not None else 3
    retry = Retry(
        total=retries,
        read=retries,
        connect=retries,
        backoff_factor=0.3,
        status_forcelist=(500, 502, 503, 504, 403),
        raise_on_status=False,
    )
    adapter = HTTPAdapter(max_retries=retry)
    self.mount("http://", adapter)
    self.mount("https://", adapter)

base_url instance-attribute

base_url = base_url

request

request(
    method: str, path: str, *args, **kwargs
) -> Response
Source code in src/albert/session.py
def request(self, method: str, path: str, *args, **kwargs) -> requests.Response:
    self.headers["Authorization"] = f"Bearer {self._access_token}"
    full_url = urljoin(self.base_url, path) if not path.startswith("http") else path
    with handle_http_errors():
        response = super().request(method, full_url, *args, **kwargs)
        response.raise_for_status()
        return response

BaseCollection

BaseCollection(*, session: AlbertSession)

BaseCollection is the base class for all collection classes.

Parameters:

Name Type Description Default
session AlbertSession

The Albert API Session instance.

required
Source code in src/albert/collections/base.py
def __init__(self, *, session: AlbertSession):
    self.session = session

session instance-attribute

session = session

NotFoundError

NotFoundError(response: Response)

Bases: AlbertClientError

HTTP Error due to a 404 Not Found response.

Source code in src/albert/exceptions.py
def __init__(self, response: requests.Response):
    message = self._format_message(response)
    super().__init__(message)
    self.response = response

Notebook

Bases: BaseResource

blocks class-attribute instance-attribute

blocks: list[NotebookBlock] = Field(default_factory=list)

id class-attribute instance-attribute

id: NotebookId | None = Field(
    default=None, alias="albertId"
)
links: list[NotebookLink] | None = Field(default=None)

name class-attribute instance-attribute

name: str = Field(default='Untitled Notebook')

parent_id class-attribute instance-attribute

parent_id: ProjectId | TaskId = Field(..., alias="parentId")

version class-attribute instance-attribute

version: datetime | None = Field(default=None)

NotebookCollection

NotebookCollection(*, session: AlbertSession)

Bases: BaseCollection

NotebookCollection is a collection class for managing Notebook entities in the Albert platform.

Parameters:

Name Type Description Default
session AlbertSession

The Albert session instance.

required

Methods:

Name Description
copy

Create a copy of a Notebook into a specified parent

create

Create or return notebook for the provided notebook.

delete

Deletes a notebook by its ID.

get_block_by_id

Retrieve a Notebook Block by its ID.

get_by_id

Retrieve a Notebook by its ID.

list_by_parent_id

Retrieve a Notebook by parent ID.

update

Update a notebook.

update_block_content

Updates the block content of a Notebook. This does not update the notebook name (use .update for that).

Source code in src/albert/collections/notebooks.py
def __init__(self, *, session: AlbertSession):
    """
    Initializes the NotebookCollection with the provided session.

    Parameters
    ----------
    session : AlbertSession
        The Albert session instance.
    """
    super().__init__(session=session)
    self.base_path = f"/api/{NotebookCollection._api_version}/notebooks"

base_path instance-attribute

base_path = f'/api/{_api_version}/notebooks'

copy

copy(
    *,
    notebook_copy_info: NotebookCopyInfo,
    type: NotebookCopyType,
) -> Notebook

Create a copy of a Notebook into a specified parent

Parameters:

Name Type Description Default
notebook_copy_info NotebookCopyInfo

The copy information for the Notebook copy

required
type NotebookCopyType

Differentiate whether copy is for templates, task, project or restoreTemplate

required

Returns:

Type Description
Notebook

The result of the copied Notebook.

Source code in src/albert/collections/notebooks.py
def copy(self, *, notebook_copy_info: NotebookCopyInfo, type: NotebookCopyType) -> Notebook:
    """Create a copy of a Notebook into a specified parent

    Parameters
    ----------
    notebook_copy_info : NotebookCopyInfo
        The copy information for the Notebook copy
    type : NotebookCopyType
        Differentiate whether copy is for templates, task, project or restoreTemplate

    Returns
    -------
    Notebook
        The result of the copied Notebook.
    """
    response = self.session.post(
        url=f"{self.base_path}/copy",
        json=notebook_copy_info.model_dump(mode="json", by_alias=True, exclude_none=True),
        params={"type": type, "parentId": notebook_copy_info.parent_id},
    )
    return Notebook(**response.json())

create

create(*, notebook: Notebook) -> Notebook

Create or return notebook for the provided notebook. This endpoint automatically tries to find an existing notebook with the same parameter setpoints, and will either return the existing notebook or create a new one.

Parameters:

Name Type Description Default
notebook Notebook

A list of Notebook objects to find or create.

required

Returns:

Type Description
Notebook

A list of created or found Notebook objects.

Source code in src/albert/collections/notebooks.py
def create(self, *, notebook: Notebook) -> Notebook:
    """Create or return notebook for the provided notebook.
    This endpoint automatically tries to find an existing notebook with the same parameter setpoints, and will either return the existing notebook or create a new one.

    Parameters
    ----------
    notebook : Notebook
        A list of Notebook objects to find or create.

    Returns
    -------
    Notebook
        A list of created or found Notebook objects.
    """
    if notebook.blocks:
        # This check keeps a user from corrupting the Notebook data.
        msg = (
            "Cannot create a Notebook with pre-filled blocks. "
            "Set `blocks=[]` (or do not set it) when creating it. "
            "Use `.update_block_content()` afterward to add, update, or delete blocks."
        )
        raise AlbertException(msg)
    response = self.session.post(
        url=self.base_path,
        json=notebook.model_dump(mode="json", by_alias=True, exclude_none=True),
        params={"parentId": notebook.parent_id},
    )
    return Notebook(**response.json())

delete

delete(*, id: str) -> None

Deletes a notebook by its ID.

Parameters:

Name Type Description Default
id str

The ID of the notebook to delete.

required
Source code in src/albert/collections/notebooks.py
def delete(self, *, id: str) -> None:
    """
    Deletes a notebook by its ID.

    Parameters
    ----------
    id : str
        The ID of the notebook to delete.
    """
    self.session.delete(f"{self.base_path}/{id}")

get_block_by_id

get_block_by_id(
    *, notebook_id: str, block_id: str
) -> NotebookBlock

Retrieve a Notebook Block by its ID.

Parameters:

Name Type Description Default
notebook_id str

The ID of the Notebook to which the Block belongs.

required
block_id str

The ID of the Notebook Block to retrieve.

required

Returns:

Type Description
NotebookBlock

The NotebookBlock object.

Source code in src/albert/collections/notebooks.py
def get_block_by_id(self, *, notebook_id: str, block_id: str) -> NotebookBlock:
    """Retrieve a Notebook Block by its ID.

    Parameters
    ----------
    notebook_id : str
        The ID of the Notebook to which the Block belongs.
    block_id : str
        The ID of the Notebook Block to retrieve.

    Returns
    -------
    NotebookBlock
        The NotebookBlock object.
    """
    response = self.session.get(f"{self.base_path}/{notebook_id}/blocks/{block_id}")
    return TypeAdapter(NotebookBlock).validate_python(response.json())

get_by_id

get_by_id(*, id: str) -> Notebook

Retrieve a Notebook by its ID.

Parameters:

Name Type Description Default
id str

The ID of the Notebook to retrieve.

required

Returns:

Type Description
Notebook

The Notebook object.

Source code in src/albert/collections/notebooks.py
def get_by_id(self, *, id: str) -> Notebook:
    """Retrieve a Notebook by its ID.

    Parameters
    ----------
    id : str
        The ID of the Notebook to retrieve.

    Returns
    -------
    Notebook
        The Notebook object.
    """
    response = self.session.get(f"{self.base_path}/{id}")
    return Notebook(**response.json())

list_by_parent_id

list_by_parent_id(*, parent_id: str) -> list[Notebook]

Retrieve a Notebook by parent ID.

Parameters:

Name Type Description Default
parent_id str

The ID of the parent ID, e.g. task.

required

Returns:

Type Description
list[Notebook]

list of notebook references.

Source code in src/albert/collections/notebooks.py
def list_by_parent_id(self, *, parent_id: str) -> list[Notebook]:
    """Retrieve a Notebook by parent ID.

    Parameters
    ----------
    parent_id : str
        The ID of the parent ID, e.g. task.

    Returns
    -------
    list[Notebook]
        list of notebook references.

    """

    # search
    response = self.session.get(f"{self.base_path}/{parent_id}/search")
    # return
    return [self.get_by_id(id=x["id"]) for x in response.json()["Items"]]

update

update(*, notebook: Notebook) -> Notebook

Update a notebook.

Parameters:

Name Type Description Default
notebook Notebook

The updated notebook object.

required

Returns:

Type Description
Notebook

The updated notebook object as returned by the server.

Source code in src/albert/collections/notebooks.py
def update(self, *, notebook: Notebook) -> Notebook:
    """Update a notebook.

    Parameters
    ----------
    notebook : Notebook
        The updated notebook object.

    Returns
    -------
    Notebook
        The updated notebook object as returned by the server.
    """
    existing_notebook = self.get_by_id(id=notebook.id)
    patch_data = self._generate_patch_payload(existing=existing_notebook, updated=notebook)
    url = f"{self.base_path}/{notebook.id}"

    self.session.patch(url, json=patch_data.model_dump(mode="json", by_alias=True))

    return self.get_by_id(id=notebook.id)

update_block_content

update_block_content(*, notebook: Notebook) -> Notebook

Updates the block content of a Notebook. This does not update the notebook name (use .update for that). If a block in the Notebook does not already exist on Albert, it will be created. Note: The order of the Blocks in your Notebook matter and will be used in the updated Notebook!

Parameters:

Name Type Description Default
notebook Notebook

The updated notebook object.

required

Returns:

Type Description
Notebook

The updated notebook object as returned by the server.

Source code in src/albert/collections/notebooks.py
def update_block_content(self, *, notebook: Notebook) -> Notebook:
    """
    Updates the block content of a Notebook. This does not update the notebook name (use .update for that).
    If a block in the Notebook does not already exist on Albert, it will be created.
    *Note: The order of the Blocks in your Notebook matter and will be used in the updated Notebook!*


    Parameters
    ----------
    notebook : Notebook
        The updated notebook object.

    Returns
    -------
    Notebook
        The updated notebook object as returned by the server.
    """
    put_data = self._generate_put_block_payload(notebook=notebook)
    url = f"{self.base_path}/{notebook.id}/content"

    self.session.put(url, json=put_data.model_dump(mode="json", by_alias=True))

    return self.get_by_id(id=notebook.id)

NotebookCopyInfo

Bases: BaseAlbertModel

acl class-attribute instance-attribute

acl: NotebookCopyACL | None = Field(default=None)

id instance-attribute

id: NotebookId

name class-attribute instance-attribute

name: str | None = Field(default=None)

notebook_name class-attribute instance-attribute

notebook_name: str | None = Field(
    default=None, alias="notebookName"
)

parent_id class-attribute instance-attribute

parent_id: str = Field(alias='parentId')

NotebookCopyType

Bases: str, Enum

GEN_TASK_TEMPLATE class-attribute instance-attribute

GEN_TASK_TEMPLATE = 'genTaskTemplate'

PROJECT class-attribute instance-attribute

PROJECT = 'Project'

RESTORE_TEMPLATE class-attribute instance-attribute

RESTORE_TEMPLATE = 'restoreTemplate'

TASK class-attribute instance-attribute

TASK = 'Task'

TEMPLATE class-attribute instance-attribute

TEMPLATE = 'template'

PutBlockDatum

Bases: BaseAlbertModel

Methods:

Name Description
content_matches_type
model_dump

Shallow model_dump to exclude None values (None only removed from top level).

content class-attribute instance-attribute

content: NotebookContent | None = Field(default=None)

id instance-attribute

id: str

operation instance-attribute

operation: PutOperation

previous_block_id class-attribute instance-attribute

previous_block_id: str | None = Field(
    default=None, alias="previousBlockId"
)

type class-attribute instance-attribute

type: BlockType | None = Field(
    default=None, alias="blockType"
)

content_matches_type

content_matches_type() -> PutBlockDatum
Source code in src/albert/resources/notebooks.py
@model_validator(mode="after")
def content_matches_type(self) -> "PutBlockDatum":
    if self.content is None:
        return self  # skip check if there's no content

    content_type = allowed_notebook_contents.get(self.type)
    if content_type and not isinstance(self.content, content_type):
        msg = f"The content type and block type do not match. [content_type={type(self.content)}, block_type={self.type}]"
        raise AlbertException(msg)
    return self

model_dump

model_dump(**kwargs) -> dict[str, Any]

Shallow model_dump to exclude None values (None only removed from top level). This ensures required attrs are not removed.

Source code in src/albert/resources/notebooks.py
def model_dump(self, **kwargs) -> dict[str, Any]:
    """
    Shallow model_dump to exclude None values (None only removed from top level).
    This ensures required attrs are not removed.
    """
    base = super().model_dump(**kwargs)
    return {k: v for k, v in base.items() if v is not None}

PutBlockPayload

Bases: BaseAlbertModel

Methods:

Name Description
model_dump

model_dump to ensure only top-level None attrs are removed on PutBlockDatum.

data instance-attribute

model_dump

model_dump(**kwargs) -> dict[str, Any]

model_dump to ensure only top-level None attrs are removed on PutBlockDatum.

Source code in src/albert/resources/notebooks.py
def model_dump(self, **kwargs) -> dict[str, Any]:
    """model_dump to ensure only top-level None attrs are removed on PutBlockDatum."""
    return {"data": [item.model_dump(**kwargs) for item in self.data]}

PutOperation

Bases: str, Enum

DELETE class-attribute instance-attribute

DELETE = 'delete'

UPDATE class-attribute instance-attribute

UPDATE = 'update'