Skip to content

Commit c81a190

Browse files
authored
Add a new model for user assets (#190)
1 parent 8dd76ba commit c81a190

File tree

4 files changed

+99
-1
lines changed

4 files changed

+99
-1
lines changed

llmstack/datasources/admin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.contrib import admin
22

3-
from .models import DataSource, DataSourceEntry, DataSourceType
3+
from .models import DataSource, DataSourceEntry, DataSourceType, UserFiles
44

55

66
class DataSourceEntryAdmin(admin.ModelAdmin):
@@ -15,3 +15,4 @@ class DataSourceAdmin(admin.ModelAdmin):
1515
admin.site.register(DataSourceEntry, DataSourceEntryAdmin)
1616
admin.site.register(DataSourceType, DataSourceAdmin)
1717
admin.site.register(DataSource)
18+
admin.site.register(UserFiles)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated by Django 4.2.10 on 2024-03-16 10:53
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
import llmstack.datasources.models
7+
import uuid
8+
9+
10+
class Migration(migrations.Migration):
11+
12+
dependencies = [
13+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14+
('datasources', '0002_datasource_config_and_more'),
15+
]
16+
17+
operations = [
18+
migrations.CreateModel(
19+
name='UserFiles',
20+
fields=[
21+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22+
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, help_text='UUID of the asset')),
23+
('file', models.FileField(blank=True, null=True, storage=llmstack.datasources.models.select_storage, upload_to=llmstack.datasources.models.upload_to)),
24+
('metadata', models.JSONField(blank=True, default=dict, help_text='Metadata for the asset', null=True)),
25+
('created_at', models.DateTimeField(auto_now_add=True)),
26+
('user', models.OneToOneField(help_text='User this asset belongs to', on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
27+
],
28+
),
29+
]

llmstack/datasources/models.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import base64
12
import logging
23
import uuid
34

@@ -6,6 +7,7 @@
67
from django.utils.timezone import now
78

89
from llmstack.base.models import Profile
10+
from llmstack.common.utils.utils import validate_parse_data_uri
911

1012
logger = logging.getLogger(__name__)
1113

@@ -176,3 +178,66 @@ def user_can_read(self, user) -> bool:
176178
).organization
177179
)
178180
return False
181+
182+
183+
def select_storage():
184+
from django.core.files.storage import storages
185+
186+
return storages["useruploads"]
187+
188+
189+
def upload_to(instance, filename):
190+
return "/".join(
191+
[
192+
str(instance.profile_uuid),
193+
instance.path,
194+
filename,
195+
]
196+
)
197+
198+
199+
class UserFiles(models.Model):
200+
uuid = models.UUIDField(default=uuid.uuid4, editable=False, help_text="UUID of the asset")
201+
user = models.OneToOneField(User, on_delete=models.DO_NOTHING, help_text="User this asset belongs to")
202+
path = ""
203+
file = models.FileField(
204+
storage=select_storage,
205+
upload_to=upload_to,
206+
null=True,
207+
blank=True,
208+
)
209+
metadata = models.JSONField(
210+
default=dict,
211+
help_text="Metadata for the asset",
212+
null=True,
213+
blank=True,
214+
)
215+
created_at = models.DateTimeField(auto_now_add=True)
216+
217+
def __init__(self, *args, path="", **kwargs) -> None:
218+
super(UserFiles, self).__init__(*args, **kwargs)
219+
self.path = path
220+
221+
@property
222+
def profile_uuid(self):
223+
return Profile.objects.get(user=self.user).uuid
224+
225+
226+
def create_from_bytes(user, file_bytes, filename, metadata=None):
227+
from django.core.files.base import ContentFile
228+
229+
asset = UserFiles(user=user)
230+
asset.file.save(
231+
filename,
232+
ContentFile(file_bytes),
233+
)
234+
bytes_size = len(file_bytes)
235+
asset.metadata = {**metadata, "file_size": bytes_size}
236+
asset.save()
237+
return asset
238+
239+
240+
def create_from_data_uri(user, data_uri, metadata={}):
241+
mime_type, file_name, file_data = validate_parse_data_uri(data_uri)
242+
file_bytes = base64.b64decode(file_data)
243+
return create_from_bytes(user, file_bytes, file_name, {**metadata, "mime_type": mime_type, "file_name": file_name})

llmstack/server/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@
208208
"base_url": GENERATEDFILES_URL,
209209
},
210210
},
211+
"useruploads": {
212+
"BACKEND": "django.core.files.storage.FileSystemStorage",
213+
},
211214
}
212215

213216
# Default primary key field type

0 commit comments

Comments
 (0)