Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions ai_models/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ class VideoModelSpecAdmin(admin.ModelAdmin):
"updated_at",
]

search_fields = [
"name",
"label",
"model_id",
] + [f"pricing__{field}" for field in ModelPricingAdmin.search_fields]
search_fields = ["name", "label", "model_id", "category"] + [
f"pricing__{field}" for field in ModelPricingAdmin.search_fields
]
autocomplete_fields = ["pricing"]

readonly_fields = [
Expand All @@ -43,6 +41,7 @@ class VideoModelSpecAdmin(admin.ModelAdmin):
"name",
"label",
"model_id",
"category",
"schema",
"pricing",
]
Expand Down
22 changes: 22 additions & 0 deletions ai_models/migrations/0003_videomodelspec_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.1.3 on 2025-10-17 08:41

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("ai_models", "0002_alter_videomodelspec_pricing"),
]

operations = [
migrations.AddField(
model_name="videomodelspec",
name="category",
field=models.IntegerField(
choices=[(1, "Video"), (2, "Audio")],
help_text="Model category: generates Audio, Video, etc.",
null=True,
),
),
]
Comment on lines +12 to +22
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Backfill and index required to prevent empty model lists post-migration.

Adding a nullable category without a data migration will exclude all existing rows from UI queries that filter by category, breaking model selection until each row is edited. Add a RunPython migration to set existing rows to Video by default and consider indexing for frequent filtering.

Additional migration (new file example):

# ai_models/migrations/0004_backfill_videomodelspec_category.py
from django.db import migrations

def forwards(apps, schema_editor):
    VideoModelSpec = apps.get_model("ai_models", "VideoModelSpec")
    # Default all existing to Video (1). Adjust as needed.
    VideoModelSpec.objects.filter(category__isnull=True).update(category=1)

def backwards(apps, schema_editor):
    VideoModelSpec = apps.get_model("ai_models", "VideoModelSpec")
    VideoModelSpec.objects.filter(category=1).update(category=None)

class Migration(migrations.Migration):
    dependencies = [("ai_models", "0003_videomodelspec_category")]
    operations = [migrations.RunPython(forwards, backwards)]

If appropriate, follow up with:

migrations.AlterField(
    model_name="videomodelspec",
    name="category",
    field=models.IntegerField(choices=[(1, "Video"), (2, "Audio")], help_text=..., null=False, default=1, db_index=True),
)
🧰 Tools
🪛 Ruff (0.14.1)

12-22: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

🤖 Prompt for AI Agents
In ai_models/migrations/0003_videomodelspec_category.py lines 12-22, adding a
nullable category field without a backfill will make existing rows invisible to
category-filtering UI; add a follow-up RunPython migration that sets category=1
(Video) for all rows where category is NULL in the forwards function and
restores NULL in backwards, then optionally add a subsequent AlterField
migration to make category non-null with default=1 and db_index=True to enforce
the default and optimize queries.

11 changes: 11 additions & 0 deletions ai_models/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from django.db import models


class Category(models.IntegerChoices):
Video = (1, "Video")
Audio = (2, "Audio")


class VideoModelSpec(models.Model):
name = models.TextField(
unique=True,
Expand All @@ -17,6 +22,12 @@ class VideoModelSpec(models.Model):
default=dict,
)

category = models.IntegerField(
choices=Category.choices,
help_text="Model category: generates Audio, Video, etc.",
null=True,
)

pricing = models.ForeignKey(
"usage_costs.ModelPricing",
on_delete=models.SET_NULL,
Expand Down
14 changes: 14 additions & 0 deletions daras_ai_v2/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ def ffprobe(filename: str) -> dict:
return json.loads(text)


def ffprobe_metadata(filename: str) -> dict:
text = call_cmd(
"ffprobe",
"-v",
"quiet",
"-print_format",
"json",
"-show_format",
filename,
err_msg=FFMPEG_ERR_MSG,
)
return json.loads(text)


def call_cmd(
*args, err_msg: str = "", ok_returncodes: typing.Iterable[int] = ()
) -> str:
Expand Down
Loading