{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c2b3a63a",
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a84d3520",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2026-06-27 22:09:01 DEBUG    | Logging configured\n",
      "2026-06-27 22:09:01 DEBUG    | Initialized async database runtime for database_url=sqlite+aiosqlite:///./transcription.db\n",
      "2026-06-27 22:09:01 DEBUG    | Database schema bootstrap complete for database_url=sqlite+aiosqlite:///./transcription.db\n"
     ]
    }
   ],
   "source": [
    "from pathlib import Path\n",
    "from uuid import UUID\n",
    "\n",
    "import rich\n",
    "\n",
    "from transcription.config import configure_logging\n",
    "from transcription.config import get_settings\n",
    "from transcription.db.operations import create_all\n",
    "from transcription.db.runtime import get_engine\n",
    "from transcription.db.runtime import get_session\n",
    "from transcription.models import Document\n",
    "from transcription.models import Job\n",
    "from transcription.models import JobStatus\n",
    "from transcription.services import ServiceBundle\n",
    "from transcription.services.documents import DocumentService\n",
    "from transcription.services.documents import create_upload_job\n",
    "from transcription.services.jobs import JobService\n",
    "from transcription.services.store import store_file\n",
    "from transcription.worker import process_queued_job\n",
    "\n",
    "configure_logging()\n",
    "settings = get_settings(worker_max_retries=2)\n",
    "engine = get_engine(settings=settings)\n",
    "await create_all(engine=engine)\n",
    "services = ServiceBundle()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b3b2c783",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">[</span>\n",
       "    <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"font-weight: bold\">(</span>\n",
       "        <span style=\"color: #808000; text-decoration-color: #808000\">id</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'c79d20d1-ab5c-4b3b-a898-13eac7d2c71a'</span><span style=\"font-weight: bold\">)</span>,\n",
       "        <span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
       "        <span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">55</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">13</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">69063</span><span style=\"font-weight: bold\">)</span>,\n",
       "        <span style=\"color: #808000; text-decoration-color: #808000\">document_id</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'105e84b2-d773-4abb-bd49-8dc26b966046'</span><span style=\"font-weight: bold\">)</span>,\n",
       "        <span style=\"color: #808000; text-decoration-color: #808000\">status</span>=<span style=\"font-weight: bold\">&lt;</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">JobStatus.TRANSCRIBED:</span><span style=\"color: #000000; text-decoration-color: #000000\"> </span><span style=\"color: #008000; text-decoration-color: #008000\">'transcribed'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">created_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">55</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">13</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">69054</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'271b688e-63c7-4652-9ccf-5c1dd3f61058'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">55</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">17</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">189346</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">document_id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'06f49121-9b98-4b0e-b879-7a3b959fe984'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">status</span><span style=\"color: #000000; text-decoration-color: #000000\">=&lt;JobStatus.TRANSCRIBED: </span><span style=\"color: #008000; text-decoration-color: #008000\">'transcribed'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">created_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">55</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">17</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">189338</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'4386391c-3ce9-412a-9bd4-46b3860d0ef7'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">55</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">19</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">161570</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">document_id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'ac04c024-25ca-4707-8cd8-641606976344'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">status</span><span style=\"color: #000000; text-decoration-color: #000000\">=&lt;JobStatus.TRANSCRIBED: </span><span style=\"color: #008000; text-decoration-color: #008000\">'transcribed'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">created_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">55</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">19</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">161560</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'6637b36d-82e1-41e1-8776-037183851d30'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">55</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">26</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">921982</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">document_id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'9c6d8632-fe6b-4f70-bb9b-5e8d762b4b3e'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">status</span><span style=\"color: #000000; text-decoration-color: #000000\">=&lt;JobStatus.TRANSCRIBED: </span><span style=\"color: #008000; text-decoration-color: #008000\">'transcribed'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">created_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">55</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">26</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">921974</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'758f457a-343c-4b4a-98af-278875303803'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">40</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">999438</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">document_id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'0fb70d21-6409-40cc-83df-abce2917f367'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">status</span><span style=\"color: #000000; text-decoration-color: #000000\">=&lt;JobStatus.TRANSCRIBED: </span><span style=\"color: #008000; text-decoration-color: #008000\">'transcribed'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">created_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">40</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">999427</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'01060a33-464d-48c9-b4bb-f1f6acd91820'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">7</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">284063</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">document_id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'c8d0eacb-87dd-4d88-a576-ce810436dc45'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">status</span><span style=\"color: #000000; text-decoration-color: #000000\">=&lt;JobStatus.TRANSCRIBED: </span><span style=\"color: #008000; text-decoration-color: #008000\">'transcribed'</span><span style=\"color: #000000; text-decoration-color: #000000\">&gt;,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">created_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">7</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">284053</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">    </span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'50800d67-fece-452e-b3ff-b7045fb1838f'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">8</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"color: #000000; text-decoration-color: #000000\">, </span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">737235</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">document_id</span><span style=\"color: #000000; text-decoration-color: #000000\">=</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'273a58fd-4c4d-4e3a-93dd-4f391650e646'</span><span style=\"color: #000000; text-decoration-color: #000000; font-weight: bold\">)</span><span style=\"color: #000000; text-decoration-color: #000000\">,</span>\n",
       "<span style=\"color: #000000; text-decoration-color: #000000\">        </span><span style=\"color: #808000; text-decoration-color: #808000\">status</span><span style=\"color: #000000; text-decoration-color: #000000\">=&lt;JobStatus.TRANSCRIBED: </span><span style=\"color: #008000; text-decoration-color: #008000\">'transcribed'</span><span style=\"font-weight: bold\">&gt;</span>,\n",
       "        <span style=\"color: #808000; text-decoration-color: #808000\">created_at</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">8</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">737226</span><span style=\"font-weight: bold\">)</span>\n",
       "    <span style=\"font-weight: bold\">)</span>\n",
       "<span style=\"font-weight: bold\">]</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m[\u001b[0m\n",
       "    \u001b[1;35mJob\u001b[0m\u001b[1m(\u001b[0m\n",
       "        \u001b[33mid\u001b[0m=\u001b[1;35mUUID\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'c79d20d1-ab5c-4b3b-a898-13eac7d2c71a'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "        \u001b[33mretry_count\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
       "        \u001b[33mupdated_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2026\u001b[0m, \u001b[1;36m6\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m55\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m69063\u001b[0m\u001b[1m)\u001b[0m,\n",
       "        \u001b[33mdocument_id\u001b[0m=\u001b[1;35mUUID\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'105e84b2-d773-4abb-bd49-8dc26b966046'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "        \u001b[33mstatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mJobStatus.TRANSCRIBED:\u001b[0m\u001b[39m \u001b[0m\u001b[32m'transcribed'\u001b[0m\u001b[39m>,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mcreated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m55\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m13\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m69054\u001b[0m\u001b[1;39m)\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;35mJob\u001b[0m\u001b[1;39m(\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mid\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'271b688e-63c7-4652-9ccf-5c1dd3f61058'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mretry_count\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mupdated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m55\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m17\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m189346\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mdocument_id\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'06f49121-9b98-4b0e-b879-7a3b959fe984'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mstatus\u001b[0m\u001b[39m=<JobStatus.TRANSCRIBED: \u001b[0m\u001b[32m'transcribed'\u001b[0m\u001b[39m>,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mcreated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m55\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m17\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m189338\u001b[0m\u001b[1;39m)\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;35mJob\u001b[0m\u001b[1;39m(\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mid\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'4386391c-3ce9-412a-9bd4-46b3860d0ef7'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mretry_count\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mupdated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m55\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m19\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m161570\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mdocument_id\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'ac04c024-25ca-4707-8cd8-641606976344'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mstatus\u001b[0m\u001b[39m=<JobStatus.TRANSCRIBED: \u001b[0m\u001b[32m'transcribed'\u001b[0m\u001b[39m>,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mcreated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m55\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m19\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m161560\u001b[0m\u001b[1;39m)\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;35mJob\u001b[0m\u001b[1;39m(\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mid\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'6637b36d-82e1-41e1-8776-037183851d30'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mretry_count\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mupdated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m55\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m26\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m921982\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mdocument_id\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'9c6d8632-fe6b-4f70-bb9b-5e8d762b4b3e'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mstatus\u001b[0m\u001b[39m=<JobStatus.TRANSCRIBED: \u001b[0m\u001b[32m'transcribed'\u001b[0m\u001b[39m>,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mcreated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m55\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m26\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m921974\u001b[0m\u001b[1;39m)\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;35mJob\u001b[0m\u001b[1;39m(\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mid\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'758f457a-343c-4b4a-98af-278875303803'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mretry_count\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mupdated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m3\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m4\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m40\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m999438\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mdocument_id\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'0fb70d21-6409-40cc-83df-abce2917f367'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mstatus\u001b[0m\u001b[39m=<JobStatus.TRANSCRIBED: \u001b[0m\u001b[32m'transcribed'\u001b[0m\u001b[39m>,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mcreated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m3\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m4\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m40\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m999427\u001b[0m\u001b[1;39m)\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;35mJob\u001b[0m\u001b[1;39m(\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mid\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'01060a33-464d-48c9-b4bb-f1f6acd91820'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mretry_count\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mupdated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m3\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m7\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m284063\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mdocument_id\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'c8d0eacb-87dd-4d88-a576-ce810436dc45'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mstatus\u001b[0m\u001b[39m=<JobStatus.TRANSCRIBED: \u001b[0m\u001b[32m'transcribed'\u001b[0m\u001b[39m>,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mcreated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m3\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m7\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m284053\u001b[0m\u001b[1;39m)\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m    \u001b[0m\u001b[1;35mJob\u001b[0m\u001b[1;39m(\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mid\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'50800d67-fece-452e-b3ff-b7045fb1838f'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mretry_count\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mupdated_at\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1;39m(\u001b[0m\u001b[1;36m2026\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m6\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m28\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m3\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m8\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m, \u001b[0m\u001b[1;36m737235\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mdocument_id\u001b[0m\u001b[39m=\u001b[0m\u001b[1;35mUUID\u001b[0m\u001b[1;39m(\u001b[0m\u001b[32m'273a58fd-4c4d-4e3a-93dd-4f391650e646'\u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n",
       "\u001b[39m        \u001b[0m\u001b[33mstatus\u001b[0m\u001b[39m=<JobStatus.TRANSCRIBED: \u001b[0m\u001b[32m'transcribed'\u001b[0m\u001b[1m>\u001b[0m,\n",
       "        \u001b[33mcreated_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2026\u001b[0m, \u001b[1;36m6\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m8\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m737226\u001b[0m\u001b[1m)\u001b[0m\n",
       "    \u001b[1m)\u001b[0m\n",
       "\u001b[1m]\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "jobs = await services.jobs.list_jobs()\n",
    "rich.print(jobs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "60788806",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Time Rolls On - page 013.jpg'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "doc_path = Path(\"uploads/7c6ee648-4171-4e70-b901-ba94ee227d6a_Time Rolls On - page 013.jpg\")\n",
    "doc_path.name.rpartition(\"_\")[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "63881a49",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2026-06-27 22:09:01 DEBUG    | Initialized async database runtime for database_url=sqlite+aiosqlite:///./transcription.db\n",
      "2026-06-27 22:09:01 INFO     | Stored uploaded file: uploads/9d3ce411-e027-4e97-9c11-786783926ce4_Time Rolls On - page 013.jpg\n",
      "2026-06-27 22:09:01 INFO     | Created upload job document_id=7102ad0c-dcc3-4164-a86f-4e601fe31e70 job_id=5bb45fc1-6b3b-4e92-9942-f8f059baaaaf\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UploadJobResult</span><span style=\"font-weight: bold\">(</span>\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">document_id</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'7102ad0c-dcc3-4164-a86f-4e601fe31e70'</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">job_id</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'5bb45fc1-6b3b-4e92-9942-f8f059baaaaf'</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">stored_path</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">PosixPath</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'uploads/9d3ce411-e027-4e97-9c11-786783926ce4_Time Rolls On - page 013.jpg'</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">original_filename</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'Time Rolls On - page 013.jpg'</span>\n",
       "<span style=\"font-weight: bold\">)</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1;35mUploadJobResult\u001b[0m\u001b[1m(\u001b[0m\n",
       "    \u001b[33mdocument_id\u001b[0m=\u001b[1;35mUUID\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'7102ad0c-dcc3-4164-a86f-4e601fe31e70'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33mjob_id\u001b[0m=\u001b[1;35mUUID\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'5bb45fc1-6b3b-4e92-9942-f8f059baaaaf'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33mstored_path\u001b[0m=\u001b[1;35mPosixPath\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'uploads/9d3ce411-e027-4e97-9c11-786783926ce4_Time Rolls On - page 013.jpg'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33moriginal_filename\u001b[0m=\u001b[32m'Time Rolls On - page 013.jpg'\u001b[0m\n",
       "\u001b[1m)\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "async with get_session(settings=settings) as session:\n",
    "    result = await create_upload_job(\n",
    "        session=session,\n",
    "        filename=doc_path.name.rpartition(\"_\")[2],\n",
    "        file_bytes=doc_path.read_bytes(),\n",
    "        settings=settings,\n",
    "    )\n",
    "\n",
    "rich.print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c3d92127",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"font-weight: bold\">(</span>\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">id</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'5bb45fc1-6b3b-4e92-9942-f8f059baaaaf'</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">9</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">351464</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">document_id</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'7102ad0c-dcc3-4164-a86f-4e601fe31e70'</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">status</span>=<span style=\"font-weight: bold\">&lt;</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">JobStatus.QUEUED:</span><span style=\"color: #000000; text-decoration-color: #000000\"> </span><span style=\"color: #008000; text-decoration-color: #008000\">'queued'</span><span style=\"font-weight: bold\">&gt;</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">created_at</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">9</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">351451</span><span style=\"font-weight: bold\">)</span>\n",
       "<span style=\"font-weight: bold\">)</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1;35mJob\u001b[0m\u001b[1m(\u001b[0m\n",
       "    \u001b[33mid\u001b[0m=\u001b[1;35mUUID\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'5bb45fc1-6b3b-4e92-9942-f8f059baaaaf'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33mretry_count\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
       "    \u001b[33mupdated_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2026\u001b[0m, \u001b[1;36m6\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m9\u001b[0m, \u001b[1;36m1\u001b[0m, \u001b[1;36m351464\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33mdocument_id\u001b[0m=\u001b[1;35mUUID\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'7102ad0c-dcc3-4164-a86f-4e601fe31e70'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33mstatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mJobStatus.QUEUED:\u001b[0m\u001b[39m \u001b[0m\u001b[32m'queued'\u001b[0m\u001b[1m>\u001b[0m,\n",
       "    \u001b[33mcreated_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2026\u001b[0m, \u001b[1;36m6\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m9\u001b[0m, \u001b[1;36m1\u001b[0m, \u001b[1;36m351451\u001b[0m\u001b[1m)\u001b[0m\n",
       "\u001b[1m)\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import random\n",
    "\n",
    "job = random.choice(await services.jobs.query_jobs(status=JobStatus.QUEUED))\n",
    "rich.print(job)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5209430c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2026-06-27 22:09:01 DEBUG    | Initialized async database runtime for database_url=sqlite+aiosqlite:///./transcription.db\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Job</span><span style=\"font-weight: bold\">(</span>\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">id</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'5bb45fc1-6b3b-4e92-9942-f8f059baaaaf'</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">retry_count</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">updated_at</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">9</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">351464</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">document_id</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">UUID</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'7102ad0c-dcc3-4164-a86f-4e601fe31e70'</span><span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">status</span>=<span style=\"font-weight: bold\">&lt;</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff; font-weight: bold\">JobStatus.QUEUED:</span><span style=\"color: #000000; text-decoration-color: #000000\"> </span><span style=\"color: #008000; text-decoration-color: #008000\">'queued'</span><span style=\"font-weight: bold\">&gt;</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">created_at</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">datetime</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">.datetime</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2026</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">28</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">9</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">351451</span><span style=\"font-weight: bold\">)</span>\n",
       "<span style=\"font-weight: bold\">)</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1;35mJob\u001b[0m\u001b[1m(\u001b[0m\n",
       "    \u001b[33mid\u001b[0m=\u001b[1;35mUUID\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'5bb45fc1-6b3b-4e92-9942-f8f059baaaaf'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33mretry_count\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
       "    \u001b[33mupdated_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2026\u001b[0m, \u001b[1;36m6\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m9\u001b[0m, \u001b[1;36m1\u001b[0m, \u001b[1;36m351464\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33mdocument_id\u001b[0m=\u001b[1;35mUUID\u001b[0m\u001b[1m(\u001b[0m\u001b[32m'7102ad0c-dcc3-4164-a86f-4e601fe31e70'\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    \u001b[33mstatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mJobStatus.QUEUED:\u001b[0m\u001b[39m \u001b[0m\u001b[32m'queued'\u001b[0m\u001b[1m>\u001b[0m,\n",
       "    \u001b[33mcreated_at\u001b[0m=\u001b[1;35mdatetime\u001b[0m\u001b[1;35m.datetime\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m2026\u001b[0m, \u001b[1;36m6\u001b[0m, \u001b[1;36m28\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m9\u001b[0m, \u001b[1;36m1\u001b[0m, \u001b[1;36m351451\u001b[0m\u001b[1m)\u001b[0m\n",
       "\u001b[1m)\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "async with get_session(settings=settings) as session:\n",
    "    jobs = await services.jobs.query_jobs(\n",
    "        status=JobStatus.QUEUED,\n",
    "        session=session,\n",
    "    )\n",
    "\n",
    "    job = random.choice(jobs)\n",
    "    job = Job.model_copy(job)\n",
    "\n",
    "rich.print(job)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "569e5d9f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2026-06-27 22:09:06 DEBUG    | Initialized async database runtime for database_url=sqlite+aiosqlite:///./transcription.db\n"
     ]
    },
    {
     "ename": "InvalidRequestError",
     "evalue": "Instance '<Job at 0x7b19c4bb0b40>' is not persistent within this Session",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mInvalidRequestError\u001b[39m                       Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m      1\u001b[39m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mwith\u001b[39;00m get_session(settings=settings) \u001b[38;5;28;01mas\u001b[39;00m session:\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m     await process_job(\n\u001b[32m      3\u001b[39m         job,\n\u001b[32m      4\u001b[39m         services=services,\n\u001b[32m      5\u001b[39m         settings=settings,\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/transcription/src/transcription/worker.py:106\u001b[39m, in \u001b[36mprocess_job\u001b[39m\u001b[34m(job, services, settings, session)\u001b[39m\n\u001b[32m    104\u001b[39m     \u001b[38;5;28;01mcase\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01m_\u001b[39;00m:\n\u001b[32m    105\u001b[39m         \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m106\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m services.jobs.update_job(job, session=session)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/transcription/src/transcription/services/jobs.py:50\u001b[39m, in \u001b[36mJobService.update_job\u001b[39m\u001b[34m(self, job, session)\u001b[39m\n\u001b[32m     48\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m _session.merge(job)\n\u001b[32m     49\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m _session.commit()\n\u001b[32m---> \u001b[39m\u001b[32m50\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m _session.refresh(job)\n\u001b[32m     51\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m job\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/transcription/.venv/lib/python3.12/site-packages/sqlalchemy/ext/asyncio/session.py:328\u001b[39m, in \u001b[36mAsyncSession.refresh\u001b[39m\u001b[34m(self, instance, attribute_names, with_for_update)\u001b[39m\n\u001b[32m    308\u001b[39m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mrefresh\u001b[39m(\n\u001b[32m    309\u001b[39m     \u001b[38;5;28mself\u001b[39m,\n\u001b[32m    310\u001b[39m     instance: \u001b[38;5;28mobject\u001b[39m,\n\u001b[32m    311\u001b[39m     attribute_names: Optional[Iterable[\u001b[38;5;28mstr\u001b[39m]] = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m    312\u001b[39m     with_for_update: ForUpdateParameter = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m    313\u001b[39m ) -> \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m    314\u001b[39m \u001b[38;5;250m    \u001b[39m\u001b[33;03m\"\"\"Expire and refresh the attributes on the given instance.\u001b[39;00m\n\u001b[32m    315\u001b[39m \n\u001b[32m    316\u001b[39m \u001b[33;03m    A query will be issued to the database and all attributes will be\u001b[39;00m\n\u001b[32m   (...)\u001b[39m\u001b[32m    325\u001b[39m \n\u001b[32m    326\u001b[39m \u001b[33;03m    \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m328\u001b[39m     \u001b[38;5;28;01mawait\u001b[39;00m greenlet_spawn(\n\u001b[32m    329\u001b[39m         \u001b[38;5;28mself\u001b[39m.sync_session.refresh,\n\u001b[32m    330\u001b[39m         instance,\n\u001b[32m    331\u001b[39m         attribute_names=attribute_names,\n\u001b[32m    332\u001b[39m         with_for_update=with_for_update,\n\u001b[32m    333\u001b[39m     )\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/transcription/.venv/lib/python3.12/site-packages/sqlalchemy/util/_concurrency_py3k.py:190\u001b[39m, in \u001b[36mgreenlet_spawn\u001b[39m\u001b[34m(fn, _require_await, *args, **kwargs)\u001b[39m\n\u001b[32m    185\u001b[39m \u001b[38;5;66;03m# runs the function synchronously in gl greenlet. If the execution\u001b[39;00m\n\u001b[32m    186\u001b[39m \u001b[38;5;66;03m# is interrupted by await_only, context is not dead and result is a\u001b[39;00m\n\u001b[32m    187\u001b[39m \u001b[38;5;66;03m# coroutine to wait. If the context is dead the function has\u001b[39;00m\n\u001b[32m    188\u001b[39m \u001b[38;5;66;03m# returned, and its result can be returned.\u001b[39;00m\n\u001b[32m    189\u001b[39m switch_occurred = \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m190\u001b[39m result = \u001b[30;43mcontext\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mswitch\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m    191\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m context.dead:\n\u001b[32m    192\u001b[39m     switch_occurred = \u001b[38;5;28;01mTrue\u001b[39;00m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/transcription/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py:3155\u001b[39m, in \u001b[36mSession.refresh\u001b[39m\u001b[34m(self, instance, attribute_names, with_for_update)\u001b[39m\n\u001b[32m   3152\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m exc.NO_STATE \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[32m   3153\u001b[39m     \u001b[38;5;28;01mraise\u001b[39;00m exc.UnmappedInstanceError(instance) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01merr\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m3155\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_expire_state\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mstate\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mattribute_names\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m   3157\u001b[39m \u001b[38;5;66;03m# this autoflush previously used to occur as a secondary effect\u001b[39;00m\n\u001b[32m   3158\u001b[39m \u001b[38;5;66;03m# of the load_on_ident below.   Meaning we'd organize the SELECT\u001b[39;00m\n\u001b[32m   3159\u001b[39m \u001b[38;5;66;03m# based on current DB pks, then flush, then if pks changed in that\u001b[39;00m\n\u001b[32m   3160\u001b[39m \u001b[38;5;66;03m# flush, crash.  this was unticketed but discovered as part of\u001b[39;00m\n\u001b[32m   3161\u001b[39m \u001b[38;5;66;03m# #8703.  So here, autoflush up front, dont autoflush inside\u001b[39;00m\n\u001b[32m   3162\u001b[39m \u001b[38;5;66;03m# load_on_ident.\u001b[39;00m\n\u001b[32m   3163\u001b[39m \u001b[38;5;28mself\u001b[39m._autoflush()\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/transcription/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py:3281\u001b[39m, in \u001b[36mSession._expire_state\u001b[39m\u001b[34m(self, state, attribute_names)\u001b[39m\n\u001b[32m   3276\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_expire_state\u001b[39m(\n\u001b[32m   3277\u001b[39m     \u001b[38;5;28mself\u001b[39m,\n\u001b[32m   3278\u001b[39m     state: InstanceState[Any],\n\u001b[32m   3279\u001b[39m     attribute_names: Optional[Iterable[\u001b[38;5;28mstr\u001b[39m]],\n\u001b[32m   3280\u001b[39m ) -> \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m3281\u001b[39m     \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_validate_persistent\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mstate\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m   3282\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m attribute_names:\n\u001b[32m   3283\u001b[39m         state._expire_attributes(state.dict, attribute_names)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/Documents/transcription/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py:4139\u001b[39m, in \u001b[36mSession._validate_persistent\u001b[39m\u001b[34m(self, state)\u001b[39m\n\u001b[32m   4137\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_validate_persistent\u001b[39m(\u001b[38;5;28mself\u001b[39m, state: InstanceState[Any]) -> \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m   4138\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m.identity_map.contains_state(state):\n\u001b[32m-> \u001b[39m\u001b[32m4139\u001b[39m         \u001b[38;5;28;01mraise\u001b[39;00m sa_exc.InvalidRequestError(\n\u001b[32m   4140\u001b[39m             \u001b[33m\"\u001b[39m\u001b[33mInstance \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m is not persistent within this Session\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m   4141\u001b[39m             % state_str(state)\n\u001b[32m   4142\u001b[39m         )\n",
      "\u001b[31mInvalidRequestError\u001b[39m: Instance '<Job at 0x7b19c4bb0b40>' is not persistent within this Session"
     ]
    }
   ],
   "source": [
    "async with get_session(settings=settings) as session:\n",
    "    await process_queued_job(\n",
    "        job,\n",
    "        services=services,\n",
    "        settings=settings,\n",
    "        session=session,\n",
    "    )\n",
    "    rich.print(job)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a5c06eaa",
   "metadata": {},
   "outputs": [],
   "source": [
    "doc_path = Path(\"uploads/7c6ee648-4171-4e70-b901-ba94ee227d6a_Time Rolls On - page 013.jpg\")\n",
    "idx, og_name = doc_path.name.rpartition(\"_\")[::2]\n",
    "doc_id = UUID(idx)\n",
    "doc = Document(id=doc_id, filename=og_name, file_path=str(doc_path))\n",
    "\n",
    "document_service = DocumentService()\n",
    "doc = await document_service.create_document(document=doc)\n",
    "rich.print(doc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58d68d4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = await document_service.list_documents()\n",
    "rich.print(docs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35a06ab1",
   "metadata": {},
   "outputs": [],
   "source": [
    "job = await services.jobs.read_job(UUID(\"6400c83d-e245-497c-902b-d8bc9db8a216\"))\n",
    "rich.print(job)\n",
    "rich.print(job.document)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d892d74",
   "metadata": {},
   "outputs": [],
   "source": [
    "rich.print(await services.jobs.list_jobs())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b17fd22",
   "metadata": {},
   "outputs": [],
   "source": [
    "rich.print(await document_service.list_documents())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d14be1d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "async with services.jobs._session_scope() as session:\n",
    "    jobs = await services.jobs.list_jobs(session=session, load_docs=True)\n",
    "    rich.print({job.id: job.document for job in jobs})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3845c342",
   "metadata": {},
   "outputs": [],
   "source": [
    "job_service = JobService()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8889d812",
   "metadata": {},
   "outputs": [],
   "source": [
    "doc_path.stem.rpartition(\"-\")[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "258a97be",
   "metadata": {},
   "outputs": [],
   "source": [
    "async with get_session() as session:\n",
    "    job = await services.jobs.read_job(job.id, session=session)\n",
    "    rich.print(job.status)\n",
    "    job.status = JobStatus.FAILED\n",
    "    job.retry_count = 0\n",
    "    await services.jobs.update_job(job, session=session)\n",
    "    rich.print(job)\n",
    "    await process_queued_job(job, services=services, session=session)\n",
    "    rich.print(job)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ff66c87c",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "transcription (3.12.11)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
