Skip to content

Smart Projects (🧪Beta)

albert.resources.smart_projects

SmartProjectScope

Bases: BaseAlbertModel

Scope of a smart project, defining which targets drive its smart dataset.

Show JSON schema:
{
  "description": "Scope of a smart project, defining which targets drive its smart dataset.",
  "properties": {
    "targetIds": {
      "description": "The target IDs that are part of this smart project scope.",
      "items": {
        "type": "string"
      },
      "title": "Targetids",
      "type": "array"
    }
  },
  "title": "SmartProjectScope",
  "type": "object"
}

Fields:

targets

targets: list[TargetId]

The target IDs that are part of this smart project scope.

SmartProjectPatchAttribute

Bases: str, Enum

Attributes supported when updating a smart project.

Attributes:

Name Type Description
SMART_PROJECT
TARGETS
DATASET_ID

SMART_PROJECT

SMART_PROJECT = 'smartproject'

TARGETS

TARGETS = 'targets'

DATASET_ID

DATASET_ID = 'datasetId'

SmartProject

Bases: BaseSessionResource

Project-bound interface for Smart Projects workflows.

SmartProject is the SDK entry point for anything that mirrors the Smart Projects product experience: targets and smart datasets scoped to a specific project. Access it via Project.smart after fetching or creating a project.

For resources that exist independently of a project, use the standalone collections instead: TargetCollection (client.targets) and SmartDatasetCollection (client.smart_datasets). Those collections create entities on their own; associating them with a project requires separate steps.

Methods on this resource that accept new entity payloads (without an existing ID) perform create-and-assign in a single call. No prior call to client.targets.create or client.smart_datasets.create is required for the project-bound Smart Projects flow.

Example

from albert import Albert
from albert.resources.targets import (
    Target,
    TargetType,
    Criterion,
    ComparisonOperator,
)

client = Albert()
project = client.projects.get_by_id(id="PRO123")
smart = project.smart

# Create a target and add it to the project in one step
smart.add_target(
    target=Target(
        name="Viscosity spec",
        type=TargetType.PERFORMANCE,
        data_template_id="DAT9999999",
        data_column_id="DAC9999999",
        target_value=Criterion(operator=ComparisonOperator.GTE, value=90),
        is_required=True,
    )
)

# Build and attach a smart dataset from the current target scope
smart.update_dataset()

Methods:

Name Description
add_target

Add a target to this smart project's scope.

remove_target

Remove a target from this smart project's scope.

update_dataset

Update the smart dataset attached to this smart project.

Show JSON schema:
{
  "$defs": {
    "AuditFields": {
      "description": "The audit fields for a resource",
      "properties": {
        "by": {
          "default": null,
          "title": "By",
          "type": "string"
        },
        "byName": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Byname"
        },
        "at": {
          "anyOf": [
            {
              "format": "date-time",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "At"
        }
      },
      "title": "AuditFields",
      "type": "object"
    },
    "SmartProjectScope": {
      "description": "Scope of a smart project, defining which targets drive its smart dataset.",
      "properties": {
        "targetIds": {
          "description": "The target IDs that are part of this smart project scope.",
          "items": {
            "type": "string"
          },
          "title": "Targetids",
          "type": "array"
        }
      },
      "title": "SmartProjectScope",
      "type": "object"
    },
    "Status": {
      "description": "The status of a resource.\n\nAttributes\n----------\nACTIVE : str\n    The resource is fully operational and visible in normal operations.\nINACTIVE : str\n    The resource is hidden from normal operations and disabled from use.",
      "enum": [
        "active",
        "inactive"
      ],
      "title": "Status",
      "type": "string"
    }
  },
  "description": "Project-bound interface for Smart Projects workflows.\n\n[`SmartProject`][albert.resources.smart_projects.SmartProject] is the SDK\nentry point for anything that mirrors the Smart Projects product experience:\ntargets and smart datasets scoped to a specific project. Access it via\n[`Project.smart`][albert.resources.projects.Project.smart] after fetching or\ncreating a project.\n\nFor resources that exist independently of a project, use the standalone\ncollections instead:\n[`TargetCollection`][albert.collections.targets.TargetCollection]\n(``client.targets``) and\n[`SmartDatasetCollection`][albert.collections.smart_datasets.SmartDatasetCollection]\n(``client.smart_datasets``). Those collections create entities on their own;\nassociating them with a project requires separate steps.\n\nMethods on this resource that accept new entity payloads (without an existing\nID) perform create-and-assign in a single call. No prior call to\n``client.targets.create`` or ``client.smart_datasets.create`` is required\nfor the project-bound Smart Projects flow.\n\n!!! example\n    ```python\n    from albert import Albert\n    from albert.resources.targets import (\n        Target,\n        TargetType,\n        Criterion,\n        ComparisonOperator,\n    )\n\n    client = Albert()\n    project = client.projects.get_by_id(id=\"PRO123\")\n    smart = project.smart\n\n    # Create a target and add it to the project in one step\n    smart.add_target(\n        target=Target(\n            name=\"Viscosity spec\",\n            type=TargetType.PERFORMANCE,\n            data_template_id=\"DAT9999999\",\n            data_column_id=\"DAC9999999\",\n            target_value=Criterion(operator=ComparisonOperator.GTE, value=90),\n            is_required=True,\n        )\n    )\n\n    # Build and attach a smart dataset from the current target scope\n    smart.update_dataset()\n    ```\n\nMethods\n-------\nadd_target(target) -> SmartProject\n    Add a target to this smart project's scope.\nremove_target(target, delete) -> SmartProject\n    Remove a target from this smart project's scope.\nupdate_dataset(dataset) -> SmartProject\n    Update the smart dataset attached to this smart project.",
  "properties": {
    "status": {
      "anyOf": [
        {
          "$ref": "#/$defs/Status"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "The status of the resource, optional."
    },
    "Created": {
      "anyOf": [
        {
          "$ref": "#/$defs/AuditFields"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Audit fields for the creation of the resource, optional."
    },
    "Updated": {
      "anyOf": [
        {
          "$ref": "#/$defs/AuditFields"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Audit fields for the update of the resource, optional."
    },
    "project_id": {
      "description": "The ID of the project this smart project belongs to.",
      "title": "Project Id",
      "type": "string"
    },
    "scope": {
      "$ref": "#/$defs/SmartProjectScope",
      "description": "The target scope of the smart project."
    },
    "datasetId": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "The ID of the smart dataset attached to the project, if any.",
      "title": "Datasetid"
    },
    "logs": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Build logs for the smart dataset.",
      "title": "Logs"
    },
    "lastRefreshAt": {
      "anyOf": [
        {
          "format": "date-time",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "When the smart dataset was last refreshed. Methods ------- add_target(target) -> SmartProject Add a target to this smart project's scope. remove_target(target, delete) -> SmartProject Remove a target from this smart project's scope. update_dataset(dataset) -> SmartProject Update the smart dataset attached to this smart project.",
      "title": "Lastrefreshat"
    }
  },
  "required": [
    "project_id",
    "scope"
  ],
  "title": "SmartProject",
  "type": "object"
}

Fields:

Validators:

  • _bind_session

project_id

project_id: ProjectId

The ID of the project this smart project belongs to.

scope

The target scope of the smart project.

dataset_id

dataset_id: SmartDatasetId | None = None

The ID of the smart dataset attached to the project, if any.

logs

logs: dict[str, Any] | None = None

Build logs for the smart dataset.

last_refresh_at

last_refresh_at: datetime | None = None

When the smart dataset was last refreshed. Methods ------- add_target(target) -> SmartProject Add a target to this smart project's scope. remove_target(target, delete) -> SmartProject Remove a target from this smart project's scope. update_dataset(dataset) -> SmartProject Update the smart dataset attached to this smart project.

add_target

add_target(*, target: Target | TargetId) -> SmartProject

Add a target to this smart project's scope.

When adding a target as part of a Smart Projects workflow, pass a new Target without an id. That creates the target and associates it with this project in one call; no separate client.targets.create is needed.

Parameters:

Name Type Description Default
target Target | TargetId

The target to add. See Notes for how the argument is interpreted.

required

Returns:

Type Description
SmartProject

This smart project, updated.

Notes

target is interpreted in three ways:

  • A Target without an id: create the target and associate it with this project. This is the Smart Projects UX path.
  • A Target with an id: associate that existing target with this project (does not create a new target).
  • A TargetId: associate that existing target with this project.

Only the first path (new Target without id) is supported by the current Smart Projects product UI. The other paths are available programmatically.

Source code in src/albert/resources/smart_projects.py
def add_target(self, *, target: Target | TargetId) -> SmartProject:
    """Add a target to this smart project's scope.

    When adding a target as part of a Smart Projects workflow, pass a new
    [`Target`][albert.resources.targets.Target] without an ``id``. That
    creates the target and associates it with this project in one call; no
    separate ``client.targets.create`` is needed.

    Parameters
    ----------
    target : Target | TargetId
        The target to add. See Notes for how the argument is interpreted.

    Returns
    -------
    SmartProject
        This smart project, updated.

    Notes
    -----
    ``target`` is interpreted in three ways:

    * A [`Target`][albert.resources.targets.Target] **without** an ``id``:
      create the target and associate it with this project. This is the
      Smart Projects UX path.
    * A [`Target`][albert.resources.targets.Target] **with** an ``id``:
      associate that existing target with this project (does not create a
      new target).
    * A [`TargetId`][albert.core.shared.identifiers.TargetId]: associate
      that existing target with this project.

    Only the first path (new ``Target`` without ``id``) is supported by the
    current Smart Projects product UI. The other paths are available
    programmatically.
    """

    # If the target is a new target, create it and add it to the scope.
    if isinstance(target, Target) and target.id is None:
        self.session.post(
            f"{_PROJECTS_BASE_PATH}/{self.project_id}/addTargetToProject",
            json=target.model_dump(by_alias=True, exclude_none=True, mode="json"),
        )
        return self._refresh()

    # If the target is an existing target, add it to the scope.
    target_id = target.id if isinstance(target, Target) else target
    return self._update(
        data=[
            PatchDatum(
                operation=PatchOperation.ADD,
                attribute=SmartProjectPatchAttribute.TARGETS,
                new_value=[target_id],
            )
        ]
    )

remove_target

remove_target(
    *, target: Target | TargetId, delete: bool = False
) -> SmartProject

Remove a target from this smart project's scope.

Parameters:

Name Type Description Default
target Target | TargetId

The target to remove, or its ID.

required
delete bool

When True, also deactivate the target record. When False, only remove the target from the scope.

False

Returns:

Type Description
SmartProject

This smart project, updated.

Source code in src/albert/resources/smart_projects.py
def remove_target(self, *, target: Target | TargetId, delete: bool = False) -> SmartProject:
    """Remove a target from this smart project's scope.

    Parameters
    ----------
    target : Target | TargetId
        The target to remove, or its ID.
    delete : bool, optional
        When ``True``, also deactivate the target record. When ``False``,
        only remove the target from the scope.

    Returns
    -------
    SmartProject
        This smart project, updated.
    """
    target_id = target.id if isinstance(target, Target) else target
    self.session.delete(
        f"{_PROJECTS_BASE_PATH}/{self.project_id}/deleteTarget/{target_id}",
        params={"delete": delete},
    )
    return self._refresh()

update_dataset

update_dataset(
    *,
    dataset: SmartDatasetId
    | SmartDatasetScope
    | None = None,
) -> SmartProject

Update the smart dataset attached to this smart project.

When building a dataset as part of a Smart Projects workflow, pass a SmartDatasetScope or omit dataset entirely. Either choice builds a new smart dataset from the scope and attaches it to this project in one call; no separate client.smart_datasets.create is needed.

Parameters:

Name Type Description Default
dataset SmartDatasetId | SmartDatasetScope | None

If a SmartDatasetId, attach that existing smart dataset to this project. If a SmartDatasetScope, build a new smart dataset from the scope and attach it. If None, build from this smart project's current target scope.

None

Returns:

Type Description
SmartProject

This smart project, updated.

Notes

When dataset is a SmartDatasetScope or None, this method performs create-and-assign in one step for the project-bound Smart Projects flow. When dataset is a SmartDatasetId, an existing smart dataset built via SmartDatasetCollection is attached instead.

When dataset is omitted (None), the default build scope automatically discovers all cross-project linked reference formulas on this project and includes their parent project IDs alongside this project's ID. This pulls historical experimental results from linked projects into the smart dataset snapshot, enabling Target Overview reference columns, Compare Formula Data reference bars, and Breakthrough inverse design machine learning without re-entering data.

Source code in src/albert/resources/smart_projects.py
def update_dataset(
    self,
    *,
    dataset: SmartDatasetId | SmartDatasetScope | None = None,
) -> SmartProject:
    """Update the smart dataset attached to this smart project.

    When building a dataset as part of a Smart Projects workflow, pass a
    [`SmartDatasetScope`][albert.resources.smart_datasets.SmartDatasetScope]
    or omit ``dataset`` entirely. Either choice builds a new smart dataset
    from the scope and attaches it to this project in one call; no separate
    ``client.smart_datasets.create`` is needed.

    Parameters
    ----------
    dataset : SmartDatasetId | SmartDatasetScope | None, optional
        If a [`SmartDatasetId`][albert.core.shared.identifiers.SmartDatasetId],
        attach that existing smart dataset to this project. If a
        [`SmartDatasetScope`][albert.resources.smart_datasets.SmartDatasetScope],
        build a new smart dataset from the scope and attach it. If ``None``,
        build from this smart project's current target scope.

    Returns
    -------
    SmartProject
        This smart project, updated.

    Notes
    -----
    When ``dataset`` is a
    [`SmartDatasetScope`][albert.resources.smart_datasets.SmartDatasetScope]
    or ``None``, this method performs create-and-assign in one step for the
    project-bound Smart Projects flow. When ``dataset`` is a
    [`SmartDatasetId`][albert.core.shared.identifiers.SmartDatasetId], an
    existing smart dataset built via
    [`SmartDatasetCollection`][albert.collections.smart_datasets.SmartDatasetCollection]
    is attached instead.

    When ``dataset`` is omitted (``None``), the default build scope automatically
    discovers all cross-project linked reference formulas on this project and
    includes their parent project IDs alongside this project's ID. This pulls
    historical experimental results from linked projects into the smart dataset
    snapshot, enabling Target Overview reference columns, Compare Formula Data
    reference bars, and Breakthrough inverse design machine learning without
    re-entering data.
    """

    # Existing dataset ID (SmartDatasetId is an Annotated[str, ...] alias, so check str)
    # -> attach that dataset to the smart record.
    if isinstance(dataset, str):
        return self._update(
            data=[
                PatchDatum(
                    operation=PatchOperation.UPDATE,
                    attribute=SmartProjectPatchAttribute.DATASET_ID,
                    new_value=dataset,
                )
            ]
        )

    # Otherwise build a new dataset: from the given scope, or from the current scope when None.
    if isinstance(dataset, SmartDatasetScope):
        scope = dataset
    else:
        linked_parent_project_ids: list[ProjectId] = []
        try:
            response = self.session.get(
                f"{_PROJECTS_BASE_PATH}/{self.project_id}/referenceFormulas",
                params={"worksheetId": "external"},
            )
            linked_parent_project_ids = parse_linked_parent_project_ids(response.json())
        except AlbertHTTPError as e:
            logger.warning(
                f"Could not fetch linked reference formulas for project {self.project_id}: {e}"
            )

        scope = build_default_smart_dataset_scope(
            project_id=self.project_id,
            target_ids=self.scope.targets,
            linked_parent_project_ids=linked_parent_project_ids,
        )

    _ = self.session.post(
        f"{_PROJECTS_BASE_PATH}/{self.project_id}/addDatasetToProject",
        json={"scope": scope.model_dump(by_alias=True, exclude_none=False, mode="json")},
    )
    return self._refresh()