Skip to content

Commit 0067f12

Browse files
authored
feat: 🎉 Added support for batch mode & batch querying (#302)
feat: 🎉 Added support for batch mode & batch querying
1 parent 065acde commit 0067f12

4 files changed

Lines changed: 95 additions & 32 deletions

File tree

ai21/clients/studio/resources/studio_library.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
)
1010
from ai21.http_client.async_http_client import AsyncAI21HTTPClient
1111
from ai21.http_client.http_client import AI21HTTPClient
12-
from ai21.models import FileResponse
12+
from ai21.models import FileResponse, BatchStatusResponse
13+
from ai21.models.upload_mode import UploadMode
1314
from ai21.types import NOT_GIVEN, NotGiven
1415
from ai21.utils.typing import remove_not_given
1516

@@ -24,6 +25,7 @@ def __init__(self, client: AI21HTTPClient):
2425

2526
class LibraryFiles(StudioResource):
2627
_module_name = "library/files"
28+
_sub_module_name = "library"
2729

2830
def create(
2931
self,
@@ -32,10 +34,22 @@ def create(
3234
path: Optional[str] | NotGiven = NOT_GIVEN,
3335
labels: Optional[List[str]] | NotGiven = NOT_GIVEN,
3436
public_url: Optional[str] | NotGiven = NOT_GIVEN,
37+
batch_id: Optional[str] | NotGiven = NOT_GIVEN,
3538
**kwargs,
3639
) -> str:
3740
files = {"file": open(file_path, "rb")}
38-
body = remove_not_given({"path": path, "labels": labels, "publicUrl": public_url, **kwargs})
41+
body = remove_not_given(
42+
{
43+
"path": path,
44+
"labels": labels,
45+
"publicUrl": public_url,
46+
"batch_id": batch_id,
47+
**kwargs,
48+
}
49+
)
50+
51+
if body.get("batch_id"):
52+
body["upload_mode"] = UploadMode.BATCH
3953

4054
raw_response = self._post(path=f"/{self._module_name}", files=files, body=body, response_cls=dict)
4155

@@ -44,6 +58,9 @@ def create(
4458
def get(self, file_id: str) -> FileResponse:
4559
return self._get(path=f"/{self._module_name}/{file_id}", response_cls=FileResponse)
4660

61+
def get_batch_status(self, batch_id: str) -> BatchStatusResponse:
62+
return self._get(path=f"/{self._sub_module_name}/batches/{batch_id}/status", response_cls=BatchStatusResponse)
63+
4764
def list(
4865
self,
4966
*,
@@ -86,6 +103,7 @@ def __init__(self, client: AsyncAI21HTTPClient):
86103

87104
class AsyncLibraryFiles(AsyncStudioResource):
88105
_module_name = "library/files"
106+
_sub_module_name = "library"
89107

90108
async def create(
91109
self,
@@ -94,10 +112,22 @@ async def create(
94112
path: Optional[str] | NotGiven = NOT_GIVEN,
95113
labels: Optional[List[str]] | NotGiven = NOT_GIVEN,
96114
public_url: Optional[str] | NotGiven = NOT_GIVEN,
115+
batch_id: Optional[str] | NotGiven = NOT_GIVEN,
97116
**kwargs,
98117
) -> str:
99118
files = {"file": open(file_path, "rb")}
100-
body = remove_not_given({"path": path, "labels": labels, "publicUrl": public_url, **kwargs})
119+
body = remove_not_given(
120+
{
121+
"path": path,
122+
"labels": labels,
123+
"publicUrl": public_url,
124+
"batch_id": batch_id,
125+
**kwargs,
126+
}
127+
)
128+
129+
if body.get("batch_id"):
130+
body["upload_mode"] = UploadMode.BATCH
101131

102132
raw_response = await self._post(path=f"/{self._module_name}", files=files, body=body, response_cls=dict)
103133

@@ -106,6 +136,11 @@ async def create(
106136
async def get(self, file_id: str) -> FileResponse:
107137
return await self._get(path=f"/{self._module_name}/{file_id}", response_cls=FileResponse)
108138

139+
async def get_batch_status(self, batch_id: str) -> BatchStatusResponse:
140+
return await self._get(
141+
path=f"/{self._sub_module_name}/batches/{batch_id}/status", response_cls=BatchStatusResponse
142+
)
143+
109144
async def list(
110145
self,
111146
*,

ai21/models/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
ConversationalRagSource,
99
)
1010
from ai21.models.responses.file_response import FileResponse
11+
from ai21.models.upload_mode import BatchStatusResponse
1112

1213
__all__ = [
1314
"ChatMessage",
@@ -20,4 +21,5 @@
2021
"FileResponse",
2122
"ConversationalRagResponse",
2223
"ConversationalRagSource",
24+
"BatchStatusResponse",
2325
]

ai21/models/upload_mode.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from enum import Enum
2+
from typing import List
3+
4+
from pydantic import BaseModel, Field
5+
6+
7+
class UploadMode(str, Enum):
8+
BATCH = "batch"
9+
10+
11+
class BatchStatusCount(BaseModel):
12+
status: str
13+
count: int
14+
15+
16+
class BatchStatusResponse(BaseModel):
17+
batch_id: str = Field(description="The UUID of the batch")
18+
total_documents: int = Field(description="Total number of documents in the batch")
19+
statuses: List[BatchStatusCount] = Field(description="List of document counts by status")

init.sh

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,45 @@
1-
#!/bin/bash
2-
3-
cd "$(dirname "$0")" || exit
1+
#!/usr/bin/env bash
42

53
# create .git folder
64
if [[ ! -d .git ]]; then
75
git init
86
fi
97

10-
# install the python version specified in .python-version, if not already installed
11-
if pyenv --version; then
12-
pyenv install --skip-existing
13-
fi
14-
15-
# install poetry if not already installed
16-
if ! poetry --version; then
17-
brew install poetry
18-
fi
19-
20-
# poetry needs to create the venv with the same python version
21-
poetry env use "$(cat .python-version)"
22-
23-
# update lock file
24-
poetry lock --no-update
25-
26-
# install dependencies
27-
poetry install
8+
PYTHON_VERSION=$(cat .python-version)
289

29-
# install pre-commit if not already installed
30-
if ! pre-commit --version; then
31-
brew install pre-commit
10+
# install the python version specified in .python-version, if not already installed
11+
if ! pyenv versions --bare | grep -q "^${PYTHON_VERSION}"; then
12+
pyenv install "${PYTHON_VERSION}" --skip-existing
3213
fi
3314

34-
# install pre-commit hooks
35-
pre-commit install --install-hooks -t pre-commit -t commit-msg
36-
37-
# shellcheck source=/dev/null
38-
source .venv/bin/activate
15+
{ [[ -d .venv ]] || {
16+
echo 'creating virtualenv...'
17+
python -m venv .venv
18+
}; } && {
19+
# shellcheck disable=SC1091
20+
. .venv/bin/activate
21+
} && {
22+
# install poetry if not already installed, or upgrade to version 2.x
23+
poetry_version_installed=$(poetry --version 2> /dev/null || true)
24+
poetry_major_version=$(echo "$poetry_version_installed" | awk '{print $3}' | cut -d '.' -f1)
25+
26+
# Check if poetry_major_version is a number and if it's >= 2
27+
if [[ -z $poetry_version_installed || ! $poetry_major_version =~ ^[0-9]+$ || $poetry_major_version -lt 2 ]]; then
28+
echo "Poetry >=2 is not installed. Installing/upgrading..."
29+
pip install --upgrade poetry || brew install poetry
30+
fi
31+
} && {
32+
# update lock file
33+
poetry lock
34+
} && {
35+
# install dependencies
36+
poetry install --no-root && poetry sync
37+
}
38+
39+
{
40+
# install pre-commit if not already installed
41+
pre-commit --version || brew install pre-commit
42+
} && {
43+
# install pre-commit hooks
44+
pre-commit install --install-hooks -t pre-commit -t pre-push -t commit-msg
45+
}

0 commit comments

Comments
 (0)