Skip to content

Commit

Permalink
feat: add asset dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
frederik-encord committed Dec 17, 2024
1 parent 8524f17 commit ca85693
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 6 deletions.
4 changes: 2 additions & 2 deletions encord_agents/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import requests
from encord.constants.enums import DataType
from encord.objects.ontology_labels_impl import LabelRowV2
from encord.user_client import EncordUserClient
from encord.orm.storage import StorageItemType
from encord.user_client import EncordUserClient

from encord_agents.core.data_model import FrameData, LabelRowInitialiseLabelsArgs, LabelRowMetadataIncludeArgs
from encord_agents.core.settings import Settings
Expand Down Expand Up @@ -79,7 +79,7 @@ def _guess_file_suffix(url: str, lr: LabelRowV2) -> tuple[str, str]:
- lr: the associated label row
Returns:
A file type and suffix that can be used to store the file.
A file type and suffix that can be used to store the file.
For example, ("image", ".jpg") or ("video", ".mp4").
"""
fallback_mimetype = "video/mp4" if lr.data_type == DataType.VIDEO else "image/png"
Expand Down
35 changes: 35 additions & 0 deletions encord_agents/fastapi/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def my_agent(
"""

from pathlib import Path
from typing import Annotated, Callable, Generator, Iterator

import cv2
Expand Down Expand Up @@ -188,6 +189,40 @@ def my_route(
return np.asarray(img, dtype=np.uint8)


def dep_asset(lr: LabelRowV2) -> Generator[Path, None, None]:
"""
Get a local file path to data asset temporarily stored till end of agent execution.
This dependency will fetch the underlying data asset based on a signed url.
It will temporarily store the data on disk. Once the task is completed, the
asset will be removed from disk again.
**Example:**
```python
from encord_agents.fastapi.depencencies import dep_asset
...
runner = Runner(project_hash="<project_hash_a>")
@app.post("/my-route")
def my_agent(
asset: Annotated[Path, Depends(dep_asset)],
) -> str | None:
asset.stat() # read file stats
...
```
Returns:
The path to the asset.
Raises:
`ValueError` if the underlying assets are not videos, images, or audio.
`EncordException` if data type not supported by SDK yet.
"""
with download_asset(lr) as asset:
yield asset


def dep_video_iterator(lr: Annotated[LabelRowV2, Depends(dep_label_row)]) -> Generator[Iterator[Frame], None, None]:
"""
Dependency to inject a video frame iterator for doing things over many frames.
Expand Down
38 changes: 37 additions & 1 deletion encord_agents/gcp/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def my_agent(
- [`label_row_v2`](https://docs.encord.com/sdk-documentation/sdk-references/LabelRowV2) is automatically loaded based on the frame data.
"""

from pathlib import Path
from typing import Callable, Generator, Iterator

import cv2
Expand Down Expand Up @@ -106,11 +107,46 @@ def my_agent(
return np.asarray(img, dtype=np.uint8)


def dep_asset(lr: LabelRowV2) -> Generator[Path, None, None]:
"""
Get a local file path to data asset temporarily stored till end of agent execution.
This dependency will fetch the underlying data asset based on a signed url.
It will temporarily store the data on disk. Once the task is completed, the
asset will be removed from disk again.
**Example:**
```python
from encord_agents.gcp import editor_agent
from encord_agents.gcp.dependencies import dep_asset
...
runner = Runner(project_hash="<project_hash_a>")
@editor_agent()
def my_agent(
asset: Annotated[Path, Depends(dep_asset)]
) -> None:
asset.stat() # read file stats
...
```
Returns:
The path to the asset.
Raises:
`ValueError` if the underlying assets are not videos, images, or audio.
`EncordException` if data type not supported by SDK yet.
"""
with download_asset(lr) as asset:
yield asset


def dep_video_iterator(lr: LabelRowV2) -> Generator[Iterator[Frame], None, None]:
"""
Dependency to inject a video frame iterator for doing things over many frames.
**Intended use**
**Example:**
```python
from encord_agents import FrameData
Expand Down
5 changes: 2 additions & 3 deletions encord_agents/tasks/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass
from typing import Callable, Generator, Iterator
from pathlib import Path
from typing import Callable, Generator, Iterator

import cv2
import numpy as np
Expand Down Expand Up @@ -133,7 +133,7 @@ def dep_asset(lr: LabelRowV2) -> Generator[Path, None, None]:
...
runner = Runner(project_hash="<project_hash_a>")
@runner.stage("<my_stage_name_in_project_a>")
@runner.stage("<stage_name_or_uuid>")
def my_agent(
asset: Annotated[Path, Depends(dep_asset)],
) -> str | None:
Expand All @@ -152,7 +152,6 @@ def my_agent(
yield asset



@dataclass(frozen=True)
class Twin:
"""
Expand Down

0 comments on commit ca85693

Please sign in to comment.