chunkr-ai 0.0.46__py3-none-any.whl → 0.0.48__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
chunkr_ai/api/auth.py CHANGED
@@ -1,5 +1,6 @@
1
1
  class HeadersMixin:
2
2
  """Mixin class for handling authorization headers"""
3
+ _api_key: str = ""
3
4
 
4
5
  def get_api_key(self) -> str:
5
6
  """Get the API key"""
chunkr_ai/api/chunkr.py CHANGED
@@ -1,12 +1,13 @@
1
1
  from pathlib import Path
2
2
  from PIL import Image
3
- from typing import Union, BinaryIO, Optional
3
+ from typing import Union, BinaryIO, Optional, cast, Awaitable
4
4
 
5
5
  from .configuration import Configuration
6
6
  from .decorators import anywhere, ensure_client, retry_on_429
7
7
  from .misc import prepare_upload_data
8
8
  from .task_response import TaskResponse
9
9
  from .chunkr_base import ChunkrBase
10
+ from .protocol import ChunkrClientProtocol
10
11
 
11
12
  class Chunkr(ChunkrBase):
12
13
  """Chunkr API client that works in both sync and async contexts"""
@@ -15,49 +16,51 @@ class Chunkr(ChunkrBase):
15
16
  @ensure_client()
16
17
  async def upload(
17
18
  self,
18
- file: Union[str, Path, BinaryIO, Image.Image],
19
- config: Configuration = None,
19
+ file: Union[str, Path, BinaryIO, Image.Image, bytes, bytearray, memoryview],
20
+ config: Optional[Configuration] = None,
20
21
  filename: Optional[str] = None,
21
22
  ) -> TaskResponse:
22
- task = await self.create_task(file, config, filename)
23
- return await task.poll()
23
+ task = await cast(Awaitable[TaskResponse], self.create_task(file, config, filename))
24
+ return await cast(Awaitable[TaskResponse], task.poll())
24
25
 
25
26
  @anywhere()
26
27
  @ensure_client()
27
28
  async def update(self, task_id: str, config: Configuration) -> TaskResponse:
28
- task = await self.update_task(task_id, config)
29
- return await task.poll()
29
+ task = await cast(Awaitable[TaskResponse], self.update_task(task_id, config))
30
+ return await cast(Awaitable[TaskResponse], task.poll())
30
31
 
31
32
  @anywhere()
32
33
  @ensure_client()
33
34
  @retry_on_429()
34
35
  async def create_task(
35
36
  self,
36
- file: Union[str, Path, BinaryIO, Image.Image],
37
- config: Configuration = None,
37
+ file: Union[str, Path, BinaryIO, Image.Image, bytes, bytearray, memoryview],
38
+ config: Optional[Configuration] = None,
38
39
  filename: Optional[str] = None,
39
40
  ) -> TaskResponse:
40
41
  """Create a new task with the given file and configuration."""
41
42
  data = await prepare_upload_data(file, filename, config)
43
+ assert self._client is not None
42
44
  r = await self._client.post(
43
45
  f"{self.url}/api/v1/task/parse", json=data, headers=self._headers()
44
46
  )
45
47
  r.raise_for_status()
46
- return TaskResponse(**r.json()).with_client(self, True, False)
48
+ return TaskResponse(**r.json()).with_client(cast(ChunkrClientProtocol, self), True, False)
47
49
 
48
50
  @anywhere()
49
51
  @ensure_client()
50
52
  @retry_on_429()
51
- async def update_task(self, task_id: str, config: Configuration) -> TaskResponse:
53
+ async def update_task(self, task_id: str, config: Optional[Configuration] = None) -> TaskResponse:
52
54
  """Update an existing task with new configuration."""
53
55
  data = await prepare_upload_data(None, None, config)
56
+ assert self._client is not None
54
57
  r = await self._client.patch(
55
58
  f"{self.url}/api/v1/task/{task_id}/parse",
56
59
  json=data,
57
60
  headers=self._headers(),
58
61
  )
59
62
  r.raise_for_status()
60
- return TaskResponse(**r.json()).with_client(self, True, False)
63
+ return TaskResponse(**r.json()).with_client(cast(ChunkrClientProtocol, self), True, False)
61
64
 
62
65
  @anywhere()
63
66
  @ensure_client()
@@ -66,17 +69,19 @@ class Chunkr(ChunkrBase):
66
69
  "base64_urls": str(base64_urls).lower(),
67
70
  "include_chunks": str(include_chunks).lower()
68
71
  }
72
+ assert self._client is not None
69
73
  r = await self._client.get(
70
74
  f"{self.url}/api/v1/task/{task_id}",
71
75
  params=params,
72
76
  headers=self._headers()
73
77
  )
74
78
  r.raise_for_status()
75
- return TaskResponse(**r.json()).with_client(self, include_chunks, base64_urls)
79
+ return TaskResponse(**r.json()).with_client(cast(ChunkrClientProtocol, self), include_chunks, base64_urls)
76
80
 
77
81
  @anywhere()
78
82
  @ensure_client()
79
83
  async def delete_task(self, task_id: str) -> None:
84
+ assert self._client is not None
80
85
  r = await self._client.delete(
81
86
  f"{self.url}/api/v1/task/{task_id}", headers=self._headers()
82
87
  )
@@ -85,6 +90,7 @@ class Chunkr(ChunkrBase):
85
90
  @anywhere()
86
91
  @ensure_client()
87
92
  async def cancel_task(self, task_id: str) -> None:
93
+ assert self._client is not None
88
94
  r = await self._client.get(
89
95
  f"{self.url}/api/v1/task/{task_id}/cancel", headers=self._headers()
90
96
  )
@@ -18,17 +18,23 @@ class ChunkrBase(HeadersMixin):
18
18
  raise_on_failure: Whether to raise an exception if the task fails. Defaults to False.
19
19
  """
20
20
 
21
- def __init__(self, url: str = None, api_key: str = None, raise_on_failure: bool = False):
21
+ url: str
22
+ _api_key: str
23
+ raise_on_failure: bool
24
+ _client: Optional[httpx.AsyncClient]
25
+
26
+ def __init__(self, url: Optional[str] = None, api_key: Optional[str] = None, raise_on_failure: bool = False):
22
27
  load_dotenv(override=True)
23
28
  self.url = url or os.getenv("CHUNKR_URL") or "https://api.chunkr.ai"
24
- self._api_key = api_key or os.getenv("CHUNKR_API_KEY")
29
+ _api_key = api_key or os.getenv("CHUNKR_API_KEY")
25
30
  self.raise_on_failure = raise_on_failure
26
31
 
27
- if not self._api_key:
32
+ if not _api_key:
28
33
  raise ValueError(
29
34
  "API key must be provided either directly, in .env file, or as CHUNKR_API_KEY environment variable. You can get an api key at: https://www.chunkr.ai"
30
35
  )
31
36
 
37
+ self._api_key = _api_key
32
38
  self.url = self.url.rstrip("/")
33
39
  self._client = httpx.AsyncClient()
34
40
 
@@ -36,7 +42,7 @@ class ChunkrBase(HeadersMixin):
36
42
  def upload(
37
43
  self,
38
44
  file: Union[str, Path, BinaryIO, Image.Image],
39
- config: Configuration = None,
45
+ config: Optional[Configuration] = None,
40
46
  filename: Optional[str] = None,
41
47
  ) -> TaskResponse:
42
48
  """Upload a file and wait for processing to complete.
@@ -90,7 +96,7 @@ class ChunkrBase(HeadersMixin):
90
96
  def create_task(
91
97
  self,
92
98
  file: Union[str, Path, BinaryIO, Image.Image],
93
- config: Configuration = None,
99
+ config: Optional[Configuration] = None,
94
100
  filename: Optional[str] = None,
95
101
  ) -> TaskResponse:
96
102
  """Upload a file for processing and immediately return the task response. It will not wait for processing to complete. To wait for the full processing to complete, use `task.poll()`.
@@ -127,7 +133,7 @@ class ChunkrBase(HeadersMixin):
127
133
 
128
134
  @abstractmethod
129
135
  def update_task(
130
- self, task_id: str, config: Configuration
136
+ self, task_id: str, config: Optional[Configuration] = None
131
137
  ) -> TaskResponse:
132
138
  """Update a task by its ID and immediately return the task response. It will not wait for processing to complete. To wait for the full processing to complete, use `task.poll()`.
133
139
 
@@ -13,10 +13,7 @@ P = ParamSpec('P')
13
13
 
14
14
  _sync_loop = None
15
15
 
16
- @overload
17
- def anywhere() -> Callable[[Callable[P, Awaitable[T]]], Callable[P, Union[Awaitable[T], T]]]: ...
18
-
19
- def anywhere():
16
+ def anywhere() -> Callable[[Callable[P, Awaitable[T]]], Callable[P, Union[Awaitable[T], T]]]:
20
17
  """Decorator that allows an async function to run anywhere - sync or async context."""
21
18
  def decorator(async_func: Callable[P, Awaitable[T]]) -> Callable[P, Union[Awaitable[T], T]]:
22
19
  @functools.wraps(async_func)
@@ -42,22 +39,22 @@ def anywhere():
42
39
  return wrapper
43
40
  return decorator
44
41
 
45
- def ensure_client() -> Callable[[Callable[P, Awaitable[T]]], Callable[P, Awaitable[T]]]:
42
+ def ensure_client() -> Callable[[Callable[..., Awaitable[T]]], Callable[..., Awaitable[T]]]:
46
43
  """Decorator that ensures a valid httpx.AsyncClient exists before executing the method"""
47
- def decorator(async_func: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]]:
44
+ def decorator(async_func: Callable[..., Awaitable[T]]) -> Callable[..., Awaitable[T]]:
48
45
  @functools.wraps(async_func)
49
- async def wrapper(self: Any, *args: P.args, **kwargs: P.kwargs) -> T:
46
+ async def wrapper(self: Any, *args: Any, **kwargs: Any) -> T:
50
47
  if not self._client or self._client.is_closed:
51
48
  self._client = httpx.AsyncClient()
52
49
  return await async_func(self, *args, **kwargs)
53
50
  return wrapper
54
51
  return decorator
55
52
 
56
- def require_task() -> Callable[[Callable[P, Awaitable[T]]], Callable[P, Awaitable[T]]]:
53
+ def require_task() -> Callable[[Callable[..., Awaitable[T]]], Callable[..., Awaitable[T]]]:
57
54
  """Decorator that ensures task has required attributes and valid client before execution"""
58
- def decorator(async_func: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]]:
55
+ def decorator(async_func: Callable[..., Awaitable[T]]) -> Callable[..., Awaitable[T]]:
59
56
  @functools.wraps(async_func)
60
- async def wrapper(self: Any, *args: P.args, **kwargs: P.kwargs) -> T:
57
+ async def wrapper(self: Any, *args: Any, **kwargs: Any) -> T:
61
58
  if not self.task_url:
62
59
  raise ValueError("Task URL not found")
63
60
  if not self._client:
chunkr_ai/api/misc.py CHANGED
@@ -3,9 +3,9 @@ import base64
3
3
  import io
4
4
  from pathlib import Path
5
5
  from PIL import Image
6
- from typing import Union, Tuple, BinaryIO, Optional
6
+ from typing import Union, Tuple, BinaryIO, Optional, Any
7
7
 
8
- async def prepare_file(file: Union[str, Path, BinaryIO, Image.Image]) -> Tuple[Optional[str], str]:
8
+ async def prepare_file(file: Union[str, Path, BinaryIO, Image.Image, bytes, bytearray, memoryview]) -> Tuple[Optional[str], str]:
9
9
  """Convert various file types into a tuple of (filename, file content).
10
10
 
11
11
  Args:
@@ -15,6 +15,7 @@ async def prepare_file(file: Union[str, Path, BinaryIO, Image.Image]) -> Tuple[O
15
15
  - Local file path (will be converted to base64)
16
16
  - Opened binary file (will be converted to base64)
17
17
  - PIL/Pillow Image object (will be converted to base64)
18
+ - Bytes object (will be converted to base64)
18
19
 
19
20
  Returns:
20
21
  Tuple[Optional[str], str]: (filename, content) where content is either a URL or base64 string
@@ -26,18 +27,54 @@ async def prepare_file(file: Union[str, Path, BinaryIO, Image.Image]) -> Tuple[O
26
27
  ValueError: If the URL is invalid or unreachable
27
28
  ValueError: If the MIME type is unsupported
28
29
  """
29
- # Handle strings
30
+ # Handle bytes-like objects
31
+ if isinstance(file, (bytes, bytearray, memoryview)):
32
+ # Convert to bytes first if it's not already
33
+ file_bytes = bytes(file)
34
+
35
+ # Check if this might be an already-encoded base64 string in bytes form
36
+ try:
37
+ # Try to decode the bytes to a string and see if it's valid base64
38
+ potential_base64 = file_bytes.decode('utf-8', errors='strict')
39
+ base64.b64decode(potential_base64)
40
+ # If we get here, it was a valid base64 string in bytes form
41
+ return None, potential_base64
42
+ except:
43
+ # Not a base64 string in bytes form, encode it as base64
44
+ base64_str = base64.b64encode(file_bytes).decode()
45
+ return None, base64_str
46
+
47
+ # Handle strings - urls or paths or base64
30
48
  if isinstance(file, str):
49
+ # Handle URLs
31
50
  if file.startswith(('http://', 'https://')):
32
51
  return None, file
33
- try:
34
- base64.b64decode(file)
52
+
53
+ # Handle data URLs
54
+ if file.startswith('data:'):
35
55
  return None, file
36
- except:
56
+
57
+ # Try to handle as a file path
58
+ try:
59
+ path = Path(file)
60
+ if path.exists():
61
+ # It's a valid file path, convert to Path object and continue processing
62
+ file = path
63
+ else:
64
+ # If not a valid file path, try treating as base64
65
+ try:
66
+ # Just test if it's valid base64, don't store the result
67
+ base64.b64decode(file)
68
+ return None, file
69
+ except:
70
+ raise ValueError(f"File not found: {file} and it's not a valid base64 string")
71
+ except Exception as e:
72
+ # If string can't be converted to Path or decoded as base64, it might still be a base64 string
37
73
  try:
38
- file = Path(file)
74
+ base64.b64decode(file)
75
+ return None, file
39
76
  except:
40
- raise ValueError("File must be a valid path, URL, or base64 string")
77
+ raise ValueError(f"Unable to process file: {e}")
41
78
 
42
79
  # Handle file paths - convert to base64
43
80
  if isinstance(file, Path):
@@ -67,17 +104,16 @@ async def prepare_file(file: Union[str, Path, BinaryIO, Image.Image]) -> Tuple[O
67
104
  file.seek(0)
68
105
  file_content = file.read()
69
106
  name = getattr(file, "name", "document")
70
- file_ext = Path(name).suffix.lower().lstrip('.')
71
- if not file_ext:
72
- raise ValueError("File must have an extension")
107
+ if not name or not isinstance(name, str):
108
+ name = None
73
109
  base64_str = base64.b64encode(file_content).decode()
74
- return Path(name).name, base64_str
110
+ return name, base64_str
75
111
 
76
112
  raise TypeError(f"Unsupported file type: {type(file)}")
77
113
 
78
114
 
79
115
  async def prepare_upload_data(
80
- file: Optional[Union[str, Path, BinaryIO, Image.Image]] = None,
116
+ file: Optional[Union[str, Path, BinaryIO, Image.Image, bytes, bytearray, memoryview]] = None,
81
117
  filename: Optional[str] = None,
82
118
  config: Optional[Configuration] = None,
83
119
  ) -> dict:
@@ -85,8 +121,8 @@ async def prepare_upload_data(
85
121
 
86
122
  Args:
87
123
  file: The file to upload
124
+ filename: Optional filename to use (overrides any filename from the file)
88
125
  config: Optional configuration settings
89
- client: HTTP client for downloading remote files
90
126
 
91
127
  Returns:
92
128
  dict: JSON-serializable data dictionary ready for upload
@@ -1,5 +1,5 @@
1
1
  from datetime import datetime
2
- from typing import TypeVar, Optional, Generic
2
+ from typing import Optional, cast, Awaitable, Union
3
3
  from pydantic import BaseModel, PrivateAttr
4
4
  import asyncio
5
5
  import json
@@ -11,9 +11,7 @@ from .protocol import ChunkrClientProtocol
11
11
  from .misc import prepare_upload_data
12
12
  from .decorators import anywhere, require_task, retry_on_429
13
13
 
14
- T = TypeVar("T", bound="TaskResponse")
15
-
16
- class TaskResponse(BaseModel, Generic[T]):
14
+ class TaskResponse(BaseModel):
17
15
  configuration: OutputConfiguration
18
16
  created_at: datetime
19
17
  expires_at: Optional[datetime] = None
@@ -28,13 +26,13 @@ class TaskResponse(BaseModel, Generic[T]):
28
26
  _base64_urls: bool = False
29
27
  _client: Optional[ChunkrClientProtocol] = PrivateAttr(default=None)
30
28
 
31
- def with_client(self, client: ChunkrClientProtocol, include_chunks: bool = False, base64_urls: bool = False) -> T:
29
+ def with_client(self, client: ChunkrClientProtocol, include_chunks: bool = False, base64_urls: bool = False) -> "TaskResponse":
32
30
  self._client = client
33
31
  self.include_chunks = include_chunks
34
32
  self._base64_urls = base64_urls
35
33
  return self
36
34
 
37
- def _check_status(self) -> Optional[T]:
35
+ def _check_status(self) -> Optional["TaskResponse"]:
38
36
  """Helper method to check task status and handle completion/failure"""
39
37
  if self.status == "Failed":
40
38
  if getattr(self._client, 'raise_on_failure', True):
@@ -47,6 +45,11 @@ class TaskResponse(BaseModel, Generic[T]):
47
45
  @require_task()
48
46
  async def _poll_request(self) -> dict:
49
47
  try:
48
+ if not self._client:
49
+ raise ValueError("Chunkr client protocol is not initialized")
50
+ if not self._client._client or self._client._client.is_closed:
51
+ raise ValueError("httpx client is not open")
52
+ assert self.task_url is not None
50
53
  r = await self._client._client.get(
51
54
  self.task_url, headers=self._client._headers()
52
55
  )
@@ -64,10 +67,12 @@ class TaskResponse(BaseModel, Generic[T]):
64
67
  raise e
65
68
 
66
69
  @anywhere()
67
- async def poll(self) -> T:
70
+ async def poll(self) -> "TaskResponse":
68
71
  """Poll the task for completion."""
69
72
  while True:
70
73
  j = await self._poll_request()
74
+ if not self._client:
75
+ raise ValueError("Chunkr client protocol is not initialized")
71
76
  updated = TaskResponse(**j).with_client(self._client)
72
77
  self.__dict__.update(updated.__dict__)
73
78
  if res := self._check_status():
@@ -77,9 +82,14 @@ class TaskResponse(BaseModel, Generic[T]):
77
82
  @anywhere()
78
83
  @require_task()
79
84
  @retry_on_429()
80
- async def update(self, config: Configuration) -> T:
85
+ async def update(self, config: Configuration) -> "TaskResponse":
81
86
  """Update the task configuration."""
82
87
  data = await prepare_upload_data(None, None, config)
88
+ if not self._client:
89
+ raise ValueError("Chunkr client protocol is not initialized")
90
+ if not self._client._client or self._client._client.is_closed:
91
+ raise ValueError("httpx client is not open")
92
+ assert self.task_url is not None
83
93
  r = await self._client._client.patch(
84
94
  f"{self.task_url}/parse",
85
95
  json=data,
@@ -88,12 +98,17 @@ class TaskResponse(BaseModel, Generic[T]):
88
98
  r.raise_for_status()
89
99
  updated = TaskResponse(**r.json()).with_client(self._client)
90
100
  self.__dict__.update(updated.__dict__)
91
- return await self.poll()
101
+ return cast(TaskResponse, self.poll())
92
102
 
93
103
  @anywhere()
94
104
  @require_task()
95
- async def delete(self) -> T:
105
+ async def delete(self) -> "TaskResponse":
96
106
  """Delete the task."""
107
+ if not self._client:
108
+ raise ValueError("Chunkr client protocol is not initialized")
109
+ if not self._client._client or self._client._client.is_closed:
110
+ raise ValueError("httpx client is not open")
111
+ assert self.task_url is not None
97
112
  r = await self._client._client.delete(
98
113
  self.task_url, headers=self._client._headers()
99
114
  )
@@ -102,15 +117,20 @@ class TaskResponse(BaseModel, Generic[T]):
102
117
 
103
118
  @anywhere()
104
119
  @require_task()
105
- async def cancel(self) -> T:
120
+ async def cancel(self) -> "TaskResponse":
106
121
  """Cancel the task."""
122
+ if not self._client:
123
+ raise ValueError("Chunkr client protocol is not initialized")
124
+ if not self._client._client or self._client._client.is_closed:
125
+ raise ValueError("httpx client is not open")
126
+ assert self.task_url is not None
107
127
  r = await self._client._client.get(
108
128
  f"{self.task_url}/cancel", headers=self._client._headers()
109
129
  )
110
130
  r.raise_for_status()
111
- return await self.poll()
131
+ return cast(TaskResponse, self.poll())
112
132
 
113
- def _write_to_file(self, content: str | dict, output_file: str, is_json: bool = False) -> None:
133
+ def _write_to_file(self, content: Union[str, dict], output_file: Optional[str], is_json: bool = False) -> None:
114
134
  """Helper method to write content to a file
115
135
 
116
136
  Args:
@@ -131,9 +151,12 @@ class TaskResponse(BaseModel, Generic[T]):
131
151
  if is_json:
132
152
  json.dump(content, f, cls=DateTimeEncoder, indent=2)
133
153
  else:
134
- f.write(content)
154
+ if isinstance(content, str):
155
+ f.write(content)
156
+ else:
157
+ raise ValueError("Content is not a string")
135
158
 
136
- def html(self, output_file: str = None) -> str:
159
+ def html(self, output_file: Optional[str] = None) -> str:
137
160
  """Get the full HTML of the task
138
161
 
139
162
  Args:
@@ -143,7 +166,7 @@ class TaskResponse(BaseModel, Generic[T]):
143
166
  self._write_to_file(content, output_file)
144
167
  return content
145
168
 
146
- def markdown(self, output_file: str = None) -> str:
169
+ def markdown(self, output_file: Optional[str] = None) -> str:
147
170
  """Get the full markdown of the task
148
171
 
149
172
  Args:
@@ -153,7 +176,7 @@ class TaskResponse(BaseModel, Generic[T]):
153
176
  self._write_to_file(content, output_file)
154
177
  return content
155
178
 
156
- def content(self, output_file: str = None) -> str:
179
+ def content(self, output_file: Optional[str] = None) -> str:
157
180
  """Get the full content of the task
158
181
 
159
182
  Args:
@@ -163,7 +186,7 @@ class TaskResponse(BaseModel, Generic[T]):
163
186
  self._write_to_file(content, output_file)
164
187
  return content
165
188
 
166
- def json(self, output_file: str = None) -> dict:
189
+ def json(self, output_file: Optional[str] = None) -> dict:
167
190
  """Get the full task data as JSON
168
191
 
169
192
  Args:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chunkr-ai
3
- Version: 0.0.46
3
+ Version: 0.0.48
4
4
  Summary: Python client for Chunkr: open source document intelligence
5
5
  Author-email: Ishaan Kapoor <ishaan@lumina.sh>
6
6
  License: MIT License
@@ -0,0 +1,16 @@
1
+ chunkr_ai/__init__.py,sha256=6KpYv2lmD6S5z2kc9pqwuLP5VDHmOuu2qDZArUIhb1s,53
2
+ chunkr_ai/models.py,sha256=L0L9CjY8SgSh9_Fzvo_nJXqKf_2urZHngMWtBVlAQAo,1006
3
+ chunkr_ai/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ chunkr_ai/api/auth.py,sha256=0RSNFPvHt4Nrg8qtP2xvA2KbR0J_KUe1B_tKynbq9Fc,436
5
+ chunkr_ai/api/chunkr.py,sha256=uSNYtB_mcs4-QRKsX7wZb8yv6ayXgRrJSDNZ-EbAyvc,3857
6
+ chunkr_ai/api/chunkr_base.py,sha256=8roSPoCADmaXM2r7zz2iHfZzIcY9NopOfa4j-dfk8RA,6310
7
+ chunkr_ai/api/configuration.py,sha256=aCYi_NjuTDynDc6g_N94jVGTb8SQQaUQ4LM8_a5v29g,9882
8
+ chunkr_ai/api/decorators.py,sha256=w1l_ZEkl99C-BO3qRTbi74sYwHDFspB1Bjt1Arv9lPc,4384
9
+ chunkr_ai/api/misc.py,sha256=AaGLxZlMzNgVPwErskDRKc2UVGkC0JwxLXU-enPwzA0,5354
10
+ chunkr_ai/api/protocol.py,sha256=LjPrYSq52m1afIlAo0yVGXlGZxPRh8J6g7S4PAit3Zo,388
11
+ chunkr_ai/api/task_response.py,sha256=VYa62E08VlZUyjn2YslnY4cohdK9e53HbEzsaYIXKXM,8028
12
+ chunkr_ai-0.0.48.dist-info/licenses/LICENSE,sha256=w3R12yNDyZpMiy2lxy_hvNbsldC75ww79sF0u11rkho,1069
13
+ chunkr_ai-0.0.48.dist-info/METADATA,sha256=s63jhAgp5pet4y06Ntq3zMsSkEJPIj4-JmW0aCRSN7w,7053
14
+ chunkr_ai-0.0.48.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
15
+ chunkr_ai-0.0.48.dist-info/top_level.txt,sha256=0IZY7PZIiS8bw5r4NUQRUQ-ATi-L_3vLQVq3ZLouOW8,10
16
+ chunkr_ai-0.0.48.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (79.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,16 +0,0 @@
1
- chunkr_ai/__init__.py,sha256=6KpYv2lmD6S5z2kc9pqwuLP5VDHmOuu2qDZArUIhb1s,53
2
- chunkr_ai/models.py,sha256=L0L9CjY8SgSh9_Fzvo_nJXqKf_2urZHngMWtBVlAQAo,1006
3
- chunkr_ai/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- chunkr_ai/api/auth.py,sha256=hlv0GiUmlsbFO1wLL9sslqOnsBSoBqkL_6Mk2SDvxgE,413
5
- chunkr_ai/api/chunkr.py,sha256=BzwcKNCuLfVR-HzgY8tKStsW4pIDVVjBgnEqPLyUUMM,3292
6
- chunkr_ai/api/chunkr_base.py,sha256=FDl0Ew8eOY4hur5FFqPENZiq9YQy0G3XWEqcKPeCO-U,6130
7
- chunkr_ai/api/configuration.py,sha256=aCYi_NjuTDynDc6g_N94jVGTb8SQQaUQ4LM8_a5v29g,9882
8
- chunkr_ai/api/decorators.py,sha256=VJX4qGBIL00K2zY8bh5KAMWv7SltJ38TvPJH06FnFss,4415
9
- chunkr_ai/api/misc.py,sha256=QN-2YWQ8e3VvvK63Ua-e8jsx6gxVxkO88Z96yWOofu0,3653
10
- chunkr_ai/api/protocol.py,sha256=LjPrYSq52m1afIlAo0yVGXlGZxPRh8J6g7S4PAit3Zo,388
11
- chunkr_ai/api/task_response.py,sha256=6kk9g2f7OZB3PAsmp4Or5A42r1dXTAzWAHEIVtLQ9sA,6545
12
- chunkr_ai-0.0.46.dist-info/licenses/LICENSE,sha256=w3R12yNDyZpMiy2lxy_hvNbsldC75ww79sF0u11rkho,1069
13
- chunkr_ai-0.0.46.dist-info/METADATA,sha256=Zjo2enHVCP5x0QqMTcS0k20nAWKogUoL88LZEVFoMZ8,7053
14
- chunkr_ai-0.0.46.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
15
- chunkr_ai-0.0.46.dist-info/top_level.txt,sha256=0IZY7PZIiS8bw5r4NUQRUQ-ATi-L_3vLQVq3ZLouOW8,10
16
- chunkr_ai-0.0.46.dist-info/RECORD,,