uploads

Log | Files | Refs

docs.html (23327B)


      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4     <meta charset="UTF-8">
      5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
      6     <title>Docs &middot; Upload Hub</title>
      7     <link rel="preconnect" href="https://fonts.googleapis.com">
      8     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
      9     <link href="https://fonts.googleapis.com/css2?family=Lexend:wght@300;400;500;600;700&display=swap" rel="stylesheet">
     10     <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0" rel="stylesheet" />
     11     <script src="https://cdn.tailwindcss.com"></script>
     12     <script>
     13         tailwind.config = {
     14             theme: {
     15                 extend: {
     16                     fontFamily: { sans: ['Lexend', 'sans-serif'] },
     17                     colors: {
     18                         m3: {
     19                             background: '#FDFCFB', backgroundDark: '#1A1C19',
     20                             surfaceContainer: '#F1F1EA', surfaceContainerDark: '#2D2F2B',
     21                             surfaceContainerHigh: '#EBEBE4', surfaceContainerHighDark: '#333531',
     22                             surfaceContainerHighest: '#E5E6DE', surfaceContainerHighestDark: '#434541',
     23                             onSurface: '#1A1C19', onSurfaceDark: '#E3E3DC',
     24                             onSurfaceVariant: '#43483E', onSurfaceVariantDark: '#C3C8BC',
     25                             primary: '#386A20', primaryDark: '#9CD67D',
     26                             onPrimary: '#FFFFFF', onPrimaryDark: '#0C3900',
     27                             secondaryContainer: '#D7E8CD', secondaryContainerDark: '#374B2E',
     28                             onSecondaryContainer: '#111F0F', onSecondaryContainerDark: '#D7E8CD',
     29                             outline: '#74796D', outlineDark: '#8D9286',
     30                         }
     31                     }
     32                 }
     33             }
     34         }
     35     </script>
     36     <style>
     37         body { background-color: #FDFCFB; margin: 0; -webkit-font-smoothing: antialiased; }
     38         @media (prefers-color-scheme: dark) { body { background-color: #1A1C19; } }
     39         
     40         .diagram-box { background: #F1F1EA; }
     41         @media (prefers-color-scheme: dark) { .diagram-box { background: #2D2F2B; } }
     42         
     43         .node { fill: #D7E8CD; stroke: #386A20; }
     44         @media (prefers-color-scheme: dark) { .node { fill: #374B2E; stroke: #9CD67D; } }
     45         
     46         .node-alt { fill: #E5E6DE; stroke: #74796D; }
     47         @media (prefers-color-scheme: dark) { .node-alt { fill: #434541; stroke: #8D9286; } }
     48         
     49         .arrow { stroke: #74796D; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
     50         @media (prefers-color-scheme: dark) { .arrow { stroke: #8D9286; } }
     51         
     52         .arrow-label { fill: #43483E; font-family: 'Lexend', sans-serif; font-size: 10px; }
     53         @media (prefers-color-scheme: dark) { .arrow-label { fill: #C3C8BC; } }
     54         
     55         code { background: #E5E6DE; padding: 2px 6px; border-radius: 4px; font-size: 0.85em; }
     56         @media (prefers-color-scheme: dark) { code { background: #434541; } }
     57     </style>
     58 </head>
     59 <body class="bg-m3-background dark:bg-m3-backgroundDark text-m3-onSurface dark:text-m3-onSurfaceDark font-sans">
     60 <div class="max-w-[720px] mx-auto px-4 py-10">
     61     <a href="https://uploads.amit.is-a.dev" class="inline-flex items-center gap-1 text-sm font-semibold text-m3-primary dark:text-m3-primaryDark mb-6">
     62         <span class="material-symbols-outlined text-[18px]">arrow_back</span> Back to Upload
     63     </a>
     64     <h1 class="text-3xl font-bold tracking-tight mb-2">How this tool works</h1>
     65     <p class="text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark mb-10">
     66         A permanent, free file host built on a Hugging Face dataset repo, served through a serverless 
     67         FastAPI backend on Vercel. Here's exactly what happens behind each button.
     68     </p>
     69 
     70     <!-- ===================== Section: Architecture ===================== -->
     71     <section class="mb-14">
     72         <h2 class="text-xl font-bold mb-3">1. The building blocks</h2>
     73         <p class="text-sm leading-relaxed text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark mb-4">
     74             There are three pieces: the <strong>frontend</strong> (this website, plain HTML/JS), the 
     75             <strong>backend</strong> (a Python FastAPI app running as a Vercel serverless function), and 
     76             <strong>storage</strong> (a public Hugging Face dataset repo, which gives ~unlimited free storage 
     77             and a permanent, directly-linkable URL per file).
     78         </p>
     79         <div class="diagram-box rounded-[20px] p-4 overflow-x-auto">
     80             <svg viewBox="0 0 680 140" xmlns="http://www.w3.org/2000/svg" class="min-w-[600px]">
     81                 <defs>
     82                     <marker id="arrowhead" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto">
     83                         <path d="M0,0 L8,4 L0,8 Z" class="node-alt" />
     84                     </marker>
     85                 </defs>
     86                 
     87                 <rect x="20" y="45" width="150" height="50" rx="12" class="node-alt"/>
     88                 <foreignObject x="20" y="45" width="150" height="50">
     89                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-1 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
     90                         Browser
     91                         <span class="text-[10px] opacity-80 font-normal">index.html</span>
     92                     </div>
     93                 </foreignObject>
     94 
     95                 <rect x="265" y="45" width="150" height="50" rx="12" class="node"/>
     96                 <foreignObject x="265" y="45" width="150" height="50">
     97                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-1 text-[12px] font-semibold text-m3-onSecondaryContainer dark:text-m3-onSecondaryContainerDark leading-tight">
     98                         FastAPI backend
     99                         <span class="text-[10px] opacity-80 font-normal">index.py (Vercel)</span>
    100                     </div>
    101                 </foreignObject>
    102 
    103                 <rect x="510" y="45" width="150" height="50" rx="12" class="node-alt"/>
    104                 <foreignObject x="510" y="45" width="150" height="50">
    105                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-1 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    106                         HF Dataset
    107                         <span class="text-[10px] opacity-80 font-normal">notamitgamer/uploads</span>
    108                     </div>
    109                 </foreignObject>
    110 
    111                 <path d="M170,65 L265,65" class="arrow"/>
    112                 <text x="217" y="55" text-anchor="middle" class="arrow-label">HTTP request</text>
    113                 
    114                 <path d="M415,65 L510,65" class="arrow"/>
    115                 <text x="462" y="55" text-anchor="middle" class="arrow-label">HF API</text>
    116             </svg>
    117         </div>
    118     </section>
    119 
    120     <!-- ===================== Section: Regular upload ===================== -->
    121     <section class="mb-14">
    122         <h2 class="text-xl font-bold mb-3">2. Uploading a file</h2>
    123         <p class="text-sm leading-relaxed text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark mb-4">
    124             Drop a file (or several, or paste one) and the browser sends it straight to <code>/api/upload</code> 
    125             as <code>multipart/form-data</code>. No file ever touches disk on the server &mdash; it's read into memory 
    126             and streamed directly to Hugging Face.
    127         </p>
    128         <div class="diagram-box rounded-[20px] p-4 overflow-x-auto mb-4">
    129             <svg viewBox="0 0 680 250" xmlns="http://www.w3.org/2000/svg" class="min-w-[600px]">
    130                 <rect x="20" y="10" width="200" height="40" rx="10" class="node-alt"/>
    131                 <foreignObject x="20" y="10" width="200" height="40">
    132                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    133                         Select / drop / paste file(s)
    134                     </div>
    135                 </foreignObject>
    136                 <path d="M120,50 L120,80" class="arrow"/>
    137                 
    138                 <rect x="20" y="80" width="200" height="40" rx="10" class="node-alt"/>
    139                 <foreignObject x="20" y="80" width="200" height="40">
    140                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    141                         POST /api/upload
    142                     </div>
    143                 </foreignObject>
    144                 <path d="M120,120 L120,150" class="arrow"/>
    145                 
    146                 <rect x="20" y="150" width="200" height="50" rx="10" class="node"/>
    147                 <foreignObject x="20" y="150" width="200" height="50">
    148                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-semibold text-m3-onSecondaryContainer dark:text-m3-onSecondaryContainerDark leading-tight">
    149                         Sanitize custom_id
    150                         <span class="text-[10px] opacity-80 font-normal">or generate random ID</span>
    151                     </div>
    152                 </foreignObject>
    153                 <path d="M220,175 L340,175" class="arrow"/>
    154                 
    155                 <rect x="340" y="155" width="200" height="40" rx="10" class="node"/>
    156                 <foreignObject x="340" y="155" width="200" height="40">
    157                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-semibold text-m3-onSecondaryContainer dark:text-m3-onSecondaryContainerDark leading-tight">
    158                         Upload bytes to HF dataset
    159                     </div>
    160                 </foreignObject>
    161                 <path d="M440,195 L440,230 L120,230 L120,200" class="arrow"/>
    162                 <text x="280" y="225" text-anchor="middle" class="arrow-label">return link to browser</text>
    163             </svg>
    164         </div>
    165         <ul class="text-sm leading-relaxed text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark list-disc pl-5 space-y-1">
    166             <li>Any file extension is accepted &mdash; the server never inspects file type, only reuses the extension for the generated ID.</li>
    167             <li>Max size is <strong>~4.4&nbsp;MB</strong> per file, kept just under Vercel's hard 4.5&nbsp;MB request-body limit.</li>
    168             <li>A custom ID is only allowed when uploading exactly one file, and is sanitized to block path traversal.</li>
    169         </ul>
    170     </section>
    171 
    172     <!-- ===================== Section: Link serving ===================== -->
    173     <section class="mb-14">
    174         <h2 class="text-xl font-bold mb-3">3. How links are served instantly</h2>
    175         <p class="text-sm leading-relaxed text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark mb-4">
    176             Because all uploads are permanent, links are handled entirely by Vercel's static configuration
    177             in <code>vercel.json</code>. The Python backend function is completely bypassed when you open a file.
    178         </p>
    179         <div class="diagram-box rounded-[20px] p-4 overflow-x-auto mb-4">
    180             <svg viewBox="0 0 680 180" xmlns="http://www.w3.org/2000/svg" class="min-w-[600px]">
    181                 <rect x="240" y="10" width="200" height="40" rx="10" class="node-alt"/>
    182                 <foreignObject x="240" y="10" width="200" height="40">
    183                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    184                         Someone opens /&lt;item_id&gt;
    185                     </div>
    186                 </foreignObject>
    187                 <path d="M340,50 L340,80" class="arrow"/>
    188                 
    189                 <rect x="240" y="80" width="200" height="40" rx="10" class="node"/>
    190                 <foreignObject x="240" y="80" width="200" height="40">
    191                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-semibold text-m3-onSecondaryContainer dark:text-m3-onSecondaryContainerDark leading-tight">
    192                         vercel.json intercept
    193                     </div>
    194                 </foreignObject>
    195                 
    196                 <path d="M340,120 L340,150" class="arrow"/>
    197                 <text x="390" y="140" text-anchor="middle" class="arrow-label">static redirect (instant)</text>
    198                 
    199                 <rect x="240" y="150" width="200" height="30" rx="8" class="node-alt"/>
    200                 <foreignObject x="240" y="150" width="200" height="30">
    201                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    202                         File downloaded from HF
    203                     </div>
    204                 </foreignObject>
    205             </svg>
    206         </div>
    207         <ul class="text-sm leading-relaxed text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark list-disc pl-5 space-y-1">
    208             <li>Since the python server never wakes up to process the link, cold-starts are completely eliminated.</li>
    209             <li>Files are instantly redirected and served directly off Hugging Face's global CDN.</li>
    210         </ul>
    211     </section>
    212 
    213     <!-- ===================== Section: Upload via URL ===================== -->
    214     <section class="mb-14">
    215         <h2 class="text-xl font-bold mb-3">4. Uploading from a URL</h2>
    216         <p class="text-sm leading-relaxed text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark mb-4">
    217             Instead of uploading from your device, you can hand the tool a link and have the server fetch 
    218             and re-host it &mdash; useful for backing up an image or file that's only temporarily available elsewhere.
    219         </p>
    220         <div class="diagram-box rounded-[20px] p-4 overflow-x-auto">
    221             <svg viewBox="0 0 680 100" xmlns="http://www.w3.org/2000/svg" class="min-w-[600px]">
    222                 <rect x="10" y="30" width="150" height="40" rx="10" class="node-alt"/>
    223                 <foreignObject x="10" y="30" width="150" height="40">
    224                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    225                         You paste a URL
    226                     </div>
    227                 </foreignObject>
    228                 <path d="M160,50 L250,50" class="arrow"/>
    229                 
    230                 <rect x="250" y="30" width="180" height="40" rx="10" class="node"/>
    231                 <foreignObject x="250" y="30" width="180" height="40">
    232                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-semibold text-m3-onSecondaryContainer dark:text-m3-onSecondaryContainerDark leading-tight">
    233                         Backend fetches the URL
    234                     </div>
    235                 </foreignObject>
    236                 <path d="M430,50 L520,50" class="arrow"/>
    237                 
    238                 <rect x="520" y="30" width="150" height="40" rx="10" class="node-alt"/>
    239                 <foreignObject x="520" y="30" width="150" height="40">
    240                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    241                         Uploaded to HF normally
    242                     </div>
    243                 </foreignObject>
    244             </svg>
    245         </div>
    246     </section>
    247 
    248     <!-- ===================== Section: Batch links ===================== -->
    249     <section class="mb-14">
    250         <h2 class="text-xl font-bold mb-3">5. Batch links</h2>
    251         <p class="text-sm leading-relaxed text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark mb-4">
    252             Upload more than one file at once and, alongside each file's own link, you also get a single 
    253             shareable <code>/batch/&lt;id&gt;</code> link that opens a page listing every file from that upload.
    254         </p>
    255         <div class="diagram-box rounded-[20px] p-4 overflow-x-auto">
    256             <svg viewBox="0 0 680 180" xmlns="http://www.w3.org/2000/svg" class="min-w-[600px]">
    257                 <rect x="20" y="20" width="200" height="40" rx="10" class="node-alt"/>
    258                 <foreignObject x="20" y="20" width="200" height="40">
    259                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    260                         Upload 3+ files together
    261                     </div>
    262                 </foreignObject>
    263                 <path d="M120,60 L120,90" class="arrow"/>
    264                 
    265                 <rect x="20" y="90" width="200" height="50" rx="10" class="node"/>
    266                 <foreignObject x="20" y="90" width="200" height="50">
    267                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-semibold text-m3-onSecondaryContainer dark:text-m3-onSecondaryContainerDark leading-tight">
    268                         Each file uploaded normally
    269                         <span class="text-[10px] opacity-80 font-normal">gets its own item_id</span>
    270                     </div>
    271                 </foreignObject>
    272                 <path d="M220,115 L340,115" class="arrow"/>
    273                 
    274                 <rect x="340" y="90" width="200" height="50" rx="10" class="node"/>
    275                 <foreignObject x="340" y="90" width="200" height="50">
    276                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[12px] font-semibold text-m3-onSecondaryContainer dark:text-m3-onSecondaryContainerDark leading-tight">
    277                         Manifest written
    278                         <span class="text-[10px] opacity-80 font-normal">_batches/&lt;batch_id&gt;.json</span>
    279                     </div>
    280                 </foreignObject>
    281                 <path d="M540,115 L620,115 L620,150" class="arrow"/>
    282                 
    283                 <rect x="510" y="150" width="150" height="30" rx="8" class="node-alt"/>
    284                 <foreignObject x="510" y="150" width="150" height="30">
    285                     <div xmlns="http://www.w3.org/1999/xhtml" class="w-full h-full flex flex-col items-center justify-center text-center px-2 text-[10px] font-medium text-m3-onSurface dark:text-m3-onSurfaceDark leading-tight">
    286                         /batch/&lt;id&gt; page
    287                     </div>
    288                 </foreignObject>
    289             </svg>
    290         </div>
    291     </section>
    292 
    293     <!-- ===================== Section: Limits table ===================== -->
    294     <section class="mb-14">
    295         <h2 class="text-xl font-bold mb-3">6. Limits &amp; behavior at a glance</h2>
    296         <div class="bg-m3-surfaceContainer dark:bg-m3-surfaceContainerDark rounded-[16px] overflow-hidden text-sm">
    297             <div class="overflow-x-auto">
    298                 <table class="w-full border-collapse min-w-[500px] sm:min-w-full">
    299                     <tbody>
    300                         <tr class="border-b border-m3-surfaceContainerHighest dark:border-m3-surfaceContainerHighestDark">
    301                             <td class="px-4 py-3 font-semibold align-top w-[140px] sm:w-1/3">Max file size</td>
    302                             <td class="px-4 py-3 text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark align-top">~4.4&nbsp;MB per file (Vercel request-body limit)</td>
    303                         </tr>
    304                         <tr class="border-b border-m3-surfaceContainerHighest dark:border-m3-surfaceContainerHighestDark">
    305                             <td class="px-4 py-3 font-semibold align-top">File types</td>
    306                             <td class="px-4 py-3 text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark align-top">Any extension, unrestricted</td>
    307                         </tr>
    308                         <tr class="border-b border-m3-surfaceContainerHighest dark:border-m3-surfaceContainerHighestDark">
    309                             <td class="px-4 py-3 font-semibold align-top">Multiple files</td>
    310                             <td class="px-4 py-3 text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark align-top">Supported; each gets its own link + one shared batch link</td>
    311                         </tr>
    312                         <tr class="border-b border-m3-surfaceContainerHighest dark:border-m3-surfaceContainerHighestDark">
    313                             <td class="px-4 py-3 font-semibold align-top">Custom ID</td>
    314                             <td class="px-4 py-3 text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark align-top">Single-file uploads only, sanitized to letters/numbers/dot/dash/underscore</td>
    315                         </tr>
    316                         <tr class="border-b border-m3-surfaceContainerHighest dark:border-m3-surfaceContainerHighestDark">
    317                             <td class="px-4 py-3 font-semibold align-top">Deletion</td>
    318                             <td class="px-4 py-3 text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark align-top">Not supported by design</td>
    319                         </tr>
    320                         <tr class="border-b border-m3-surfaceContainerHighest dark:border-m3-surfaceContainerHighestDark">
    321                             <td class="px-4 py-3 font-semibold align-top">Authentication</td>
    322                             <td class="px-4 py-3 text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark align-top">None &mdash; the tool is intentionally open</td>
    323                         </tr>
    324                         <tr>
    325                             <td class="px-4 py-3 font-semibold align-top">Storage</td>
    326                             <td class="px-4 py-3 text-m3-onSurfaceVariant dark:text-m3-onSurfaceVariantDark align-top">Public Hugging Face dataset repo</td>
    327                         </tr>
    328                     </tbody>
    329                 </table>
    330             </div>
    331         </div>
    332     </section>
    333 
    334     <a href="https://uploads.amit.is-a.dev" class="inline-flex items-center gap-1 text-sm font-semibold text-m3-primary dark:text-m3-primaryDark">
    335         <span class="material-symbols-outlined text-[18px]">arrow_back</span> Back to Upload
    336     </a>
    337 
    338     <div class="w-full text-center text-xs font-medium text-m3-outline dark:text-m3-outlineDark mt-10 mb-4">
    339         &copy; 2026 <a href="https://github.com/notamitgamer">notamitgamer</a>
    340     </div>
    341 </div>
    342 </body>
    343 </html>
© notamitgamer • Site Built: 2026-07-21 13:58:23 UTC • git-mirror commit: 1037f62 [view raw info]
Originally created with stagit • modified by notamitgamer
Forked from github.com/notamitgamer/git-mirror