slide-narrator 5.1.1__tar.gz → 5.2.0__tar.gz
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.
Potentially problematic release.
This version of slide-narrator might be problematic. Click here for more details.
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/PKG-INFO +2 -3
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/README.md +0 -1
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/__init__.py +1 -1
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/models/attachment.py +30 -4
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/storage/file_store.py +12 -5
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/pyproject.toml +2 -2
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/.gitignore +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/LICENSE +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/database/__init__.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/database/cli.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/database/migrations/__init__.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/database/models.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/database/storage_backend.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/database/thread_store.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/models/__init__.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/models/message.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/models/thread.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/storage/__init__.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/utils/__init__.py +0 -0
- {slide_narrator-5.1.1 → slide_narrator-5.2.0}/narrator/utils/logging.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: slide-narrator
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.2.0
|
|
4
4
|
Summary: Thread and file storage components for conversational AI - the companion to Tyler AI framework
|
|
5
5
|
Project-URL: Homepage, https://github.com/adamwdraper/slide
|
|
6
6
|
Project-URL: Repository, https://github.com/adamwdraper/slide
|
|
@@ -21,10 +21,10 @@ Requires-Dist: aiosqlite>=0.21.0
|
|
|
21
21
|
Requires-Dist: alembic>=1.14.1
|
|
22
22
|
Requires-Dist: asyncpg>=0.30.0
|
|
23
23
|
Requires-Dist: click>=8.1.8
|
|
24
|
+
Requires-Dist: filetype>=1.2.0
|
|
24
25
|
Requires-Dist: greenlet>=3.2.3
|
|
25
26
|
Requires-Dist: pydantic>=2.10.4
|
|
26
27
|
Requires-Dist: pypdf>=5.3.0
|
|
27
|
-
Requires-Dist: python-magic>=0.4.0
|
|
28
28
|
Requires-Dist: sqlalchemy>=2.0.36
|
|
29
29
|
Requires-Dist: typing-extensions>=4.12.0
|
|
30
30
|
Provides-Extra: dev
|
|
@@ -537,7 +537,6 @@ The test suite requires:
|
|
|
537
537
|
- Python 3.13+
|
|
538
538
|
- pytest with async support
|
|
539
539
|
- Test coverage reporting
|
|
540
|
-
- System dependencies (libmagic for file type detection)
|
|
541
540
|
|
|
542
541
|
## Contributing
|
|
543
542
|
|
|
@@ -2,7 +2,8 @@ from typing import Dict, Optional, Any, Union, Literal
|
|
|
2
2
|
from pydantic import BaseModel, computed_field
|
|
3
3
|
import base64
|
|
4
4
|
import io
|
|
5
|
-
import
|
|
5
|
+
import filetype
|
|
6
|
+
import mimetypes
|
|
6
7
|
from ..utils.logging import get_logger
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from ..storage.file_store import FileStore
|
|
@@ -61,7 +62,15 @@ class Attachment(BaseModel):
|
|
|
61
62
|
content = file_path.read_bytes()
|
|
62
63
|
|
|
63
64
|
# Detect MIME type
|
|
64
|
-
mime_type =
|
|
65
|
+
mime_type = filetype.guess_mime(content)
|
|
66
|
+
|
|
67
|
+
if not mime_type:
|
|
68
|
+
# Fallback: extension-based detection
|
|
69
|
+
mime_type, _ = mimetypes.guess_type(str(file_path))
|
|
70
|
+
|
|
71
|
+
if not mime_type:
|
|
72
|
+
# Default: binary
|
|
73
|
+
mime_type = 'application/octet-stream'
|
|
65
74
|
|
|
66
75
|
return cls(
|
|
67
76
|
filename=file_path.name,
|
|
@@ -88,7 +97,15 @@ class Attachment(BaseModel):
|
|
|
88
97
|
return
|
|
89
98
|
|
|
90
99
|
# Detect MIME type
|
|
91
|
-
detected_mime_type =
|
|
100
|
+
detected_mime_type = filetype.guess_mime(content_bytes)
|
|
101
|
+
|
|
102
|
+
if not detected_mime_type:
|
|
103
|
+
# Fallback: extension-based detection
|
|
104
|
+
detected_mime_type, _ = mimetypes.guess_type(self.filename)
|
|
105
|
+
|
|
106
|
+
if not detected_mime_type:
|
|
107
|
+
# Default: binary
|
|
108
|
+
detected_mime_type = 'application/octet-stream'
|
|
92
109
|
|
|
93
110
|
if not self.mime_type:
|
|
94
111
|
self.mime_type = detected_mime_type
|
|
@@ -209,7 +226,16 @@ class Attachment(BaseModel):
|
|
|
209
226
|
|
|
210
227
|
# Detect/verify MIME type
|
|
211
228
|
logger.debug("Detecting MIME type")
|
|
212
|
-
detected_mime_type =
|
|
229
|
+
detected_mime_type = filetype.guess_mime(content_bytes)
|
|
230
|
+
|
|
231
|
+
if not detected_mime_type:
|
|
232
|
+
# Fallback: extension-based detection
|
|
233
|
+
detected_mime_type, _ = mimetypes.guess_type(self.filename)
|
|
234
|
+
|
|
235
|
+
if not detected_mime_type:
|
|
236
|
+
# Default: binary
|
|
237
|
+
detected_mime_type = 'application/octet-stream'
|
|
238
|
+
|
|
213
239
|
logger.debug(f"Detected MIME type: {detected_mime_type}")
|
|
214
240
|
|
|
215
241
|
if not self.mime_type:
|
|
@@ -11,7 +11,7 @@ import mimetypes
|
|
|
11
11
|
from datetime import datetime, UTC
|
|
12
12
|
from sqlalchemy import select
|
|
13
13
|
from ..utils.logging import get_logger
|
|
14
|
-
import
|
|
14
|
+
import filetype
|
|
15
15
|
import base64
|
|
16
16
|
|
|
17
17
|
# Get configured logger
|
|
@@ -282,11 +282,18 @@ class FileStore:
|
|
|
282
282
|
|
|
283
283
|
# Detect or validate MIME type
|
|
284
284
|
if not mime_type:
|
|
285
|
-
|
|
285
|
+
# Primary: content-based detection
|
|
286
|
+
mime_type = filetype.guess_mime(content)
|
|
287
|
+
|
|
288
|
+
if not mime_type:
|
|
289
|
+
# Fallback: extension-based detection
|
|
290
|
+
mime_type, _ = mimetypes.guess_type(filename)
|
|
291
|
+
|
|
286
292
|
if not mime_type:
|
|
287
|
-
#
|
|
288
|
-
mime_type =
|
|
289
|
-
|
|
293
|
+
# Default: binary
|
|
294
|
+
mime_type = 'application/octet-stream'
|
|
295
|
+
|
|
296
|
+
logger.debug(f"Detected MIME type for {filename}: {mime_type}")
|
|
290
297
|
|
|
291
298
|
if mime_type not in self.allowed_mime_types:
|
|
292
299
|
raise UnsupportedFileTypeError(f"Unsupported file type: {mime_type}")
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "slide-narrator"
|
|
7
|
-
version = "5.
|
|
7
|
+
version = "5.2.0"
|
|
8
8
|
description = "Thread and file storage components for conversational AI - the companion to Tyler AI framework"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -27,7 +27,7 @@ dependencies = [
|
|
|
27
27
|
"alembic>=1.14.1",
|
|
28
28
|
"asyncpg>=0.30.0",
|
|
29
29
|
"aiosqlite>=0.21.0",
|
|
30
|
-
"
|
|
30
|
+
"filetype>=1.2.0",
|
|
31
31
|
"pydantic>=2.10.4",
|
|
32
32
|
"typing-extensions>=4.12.0",
|
|
33
33
|
"pypdf>=5.3.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|