Darius Morawiec commited on
Commit
d5c4625
·
1 Parent(s): aef46d3

Add initial app

Browse files
Files changed (7) hide show
  1. .gitignore +775 -0
  2. .python-version +1 -0
  3. README.md +7 -4
  4. app.py +244 -0
  5. pyproject.toml +12 -0
  6. requirements.txt +260 -0
  7. uv.lock +0 -0
.gitignore ADDED
@@ -0,0 +1,775 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .gradio
2
+ .vscode
3
+ output
4
+
5
+ # Created by https://www.toptal.com/developers/gitignore/api/linux,macos,dotenv,python,windows,intellij,visualstudio,visualstudiocode
6
+ # Edit at https://www.toptal.com/developers/gitignore?templates=linux,macos,dotenv,python,windows,intellij,visualstudio,visualstudiocode
7
+
8
+ ### dotenv ###
9
+ .env
10
+
11
+ ### Intellij ###
12
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
13
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
14
+
15
+ # User-specific stuff
16
+ .idea/**/workspace.xml
17
+ .idea/**/tasks.xml
18
+ .idea/**/usage.statistics.xml
19
+ .idea/**/dictionaries
20
+ .idea/**/shelf
21
+
22
+ # AWS User-specific
23
+ .idea/**/aws.xml
24
+
25
+ # Generated files
26
+ .idea/**/contentModel.xml
27
+
28
+ # Sensitive or high-churn files
29
+ .idea/**/dataSources/
30
+ .idea/**/dataSources.ids
31
+ .idea/**/dataSources.local.xml
32
+ .idea/**/sqlDataSources.xml
33
+ .idea/**/dynamic.xml
34
+ .idea/**/uiDesigner.xml
35
+ .idea/**/dbnavigator.xml
36
+
37
+ # Gradle
38
+ .idea/**/gradle.xml
39
+ .idea/**/libraries
40
+
41
+ # Gradle and Maven with auto-import
42
+ # When using Gradle or Maven with auto-import, you should exclude module files,
43
+ # since they will be recreated, and may cause churn. Uncomment if using
44
+ # auto-import.
45
+ # .idea/artifacts
46
+ # .idea/compiler.xml
47
+ # .idea/jarRepositories.xml
48
+ # .idea/modules.xml
49
+ # .idea/*.iml
50
+ # .idea/modules
51
+ # *.iml
52
+ # *.ipr
53
+
54
+ # CMake
55
+ cmake-build-*/
56
+
57
+ # Mongo Explorer plugin
58
+ .idea/**/mongoSettings.xml
59
+
60
+ # File-based project format
61
+ *.iws
62
+
63
+ # IntelliJ
64
+ out/
65
+
66
+ # mpeltonen/sbt-idea plugin
67
+ .idea_modules/
68
+
69
+ # JIRA plugin
70
+ atlassian-ide-plugin.xml
71
+
72
+ # Cursive Clojure plugin
73
+ .idea/replstate.xml
74
+
75
+ # SonarLint plugin
76
+ .idea/sonarlint/
77
+
78
+ # Crashlytics plugin (for Android Studio and IntelliJ)
79
+ com_crashlytics_export_strings.xml
80
+ crashlytics.properties
81
+ crashlytics-build.properties
82
+ fabric.properties
83
+
84
+ # Editor-based Rest Client
85
+ .idea/httpRequests
86
+
87
+ # Android studio 3.1+ serialized cache file
88
+ .idea/caches/build_file_checksums.ser
89
+
90
+ ### Intellij Patch ###
91
+ # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
92
+
93
+ # *.iml
94
+ # modules.xml
95
+ # .idea/misc.xml
96
+ # *.ipr
97
+
98
+ # Sonarlint plugin
99
+ # https://plugins.jetbrains.com/plugin/7973-sonarlint
100
+ .idea/**/sonarlint/
101
+
102
+ # SonarQube Plugin
103
+ # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
104
+ .idea/**/sonarIssues.xml
105
+
106
+ # Markdown Navigator plugin
107
+ # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
108
+ .idea/**/markdown-navigator.xml
109
+ .idea/**/markdown-navigator-enh.xml
110
+ .idea/**/markdown-navigator/
111
+
112
+ # Cache file creation bug
113
+ # See https://youtrack.jetbrains.com/issue/JBR-2257
114
+ .idea/$CACHE_FILE$
115
+
116
+ # CodeStream plugin
117
+ # https://plugins.jetbrains.com/plugin/12206-codestream
118
+ .idea/codestream.xml
119
+
120
+ # Azure Toolkit for IntelliJ plugin
121
+ # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
122
+ .idea/**/azureSettings.xml
123
+
124
+ ### Linux ###
125
+ *~
126
+
127
+ # temporary files which can be created if a process still has a handle open of a deleted file
128
+ .fuse_hidden*
129
+
130
+ # KDE directory preferences
131
+ .directory
132
+
133
+ # Linux trash folder which might appear on any partition or disk
134
+ .Trash-*
135
+
136
+ # .nfs files are created when an open file is removed but is still being accessed
137
+ .nfs*
138
+
139
+ ### macOS ###
140
+ # General
141
+ .DS_Store
142
+ .AppleDouble
143
+ .LSOverride
144
+
145
+ # Icon must end with two \r
146
+ Icon
147
+
148
+
149
+ # Thumbnails
150
+ ._*
151
+
152
+ # Files that might appear in the root of a volume
153
+ .DocumentRevisions-V100
154
+ .fseventsd
155
+ .Spotlight-V100
156
+ .TemporaryItems
157
+ .Trashes
158
+ .VolumeIcon.icns
159
+ .com.apple.timemachine.donotpresent
160
+
161
+ # Directories potentially created on remote AFP share
162
+ .AppleDB
163
+ .AppleDesktop
164
+ Network Trash Folder
165
+ Temporary Items
166
+ .apdisk
167
+
168
+ ### macOS Patch ###
169
+ # iCloud generated files
170
+ *.icloud
171
+
172
+ ### Python ###
173
+ # Byte-compiled / optimized / DLL files
174
+ __pycache__/
175
+ *.py[cod]
176
+ *$py.class
177
+
178
+ # C extensions
179
+ *.so
180
+
181
+ # Distribution / packaging
182
+ .Python
183
+ build/
184
+ develop-eggs/
185
+ dist/
186
+ downloads/
187
+ eggs/
188
+ .eggs/
189
+ lib/
190
+ lib64/
191
+ parts/
192
+ sdist/
193
+ var/
194
+ wheels/
195
+ share/python-wheels/
196
+ *.egg-info/
197
+ .installed.cfg
198
+ *.egg
199
+ MANIFEST
200
+
201
+ # PyInstaller
202
+ # Usually these files are written by a python script from a template
203
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
204
+ *.manifest
205
+ *.spec
206
+
207
+ # Installer logs
208
+ pip-log.txt
209
+ pip-delete-this-directory.txt
210
+
211
+ # Unit test / coverage reports
212
+ htmlcov/
213
+ .tox/
214
+ .nox/
215
+ .coverage
216
+ .coverage.*
217
+ .cache
218
+ nosetests.xml
219
+ coverage.xml
220
+ *.cover
221
+ *.py,cover
222
+ .hypothesis/
223
+ .pytest_cache/
224
+ cover/
225
+
226
+ # Translations
227
+ *.mo
228
+ *.pot
229
+
230
+ # Django stuff:
231
+ *.log
232
+ local_settings.py
233
+ db.sqlite3
234
+ db.sqlite3-journal
235
+
236
+ # Flask stuff:
237
+ instance/
238
+ .webassets-cache
239
+
240
+ # Scrapy stuff:
241
+ .scrapy
242
+
243
+ # Sphinx documentation
244
+ docs/_build/
245
+
246
+ # PyBuilder
247
+ .pybuilder/
248
+ target/
249
+
250
+ # Jupyter Notebook
251
+ .ipynb_checkpoints
252
+
253
+ # IPython
254
+ profile_default/
255
+ ipython_config.py
256
+
257
+ # pyenv
258
+ # For a library or package, you might want to ignore these files since the code is
259
+ # intended to run in multiple environments; otherwise, check them in:
260
+ # .python-version
261
+
262
+ # pipenv
263
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
264
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
265
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
266
+ # install all needed dependencies.
267
+ #Pipfile.lock
268
+
269
+ # poetry
270
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
271
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
272
+ # commonly ignored for libraries.
273
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
274
+ #poetry.lock
275
+
276
+ # pdm
277
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
278
+ #pdm.lock
279
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
280
+ # in version control.
281
+ # https://pdm.fming.dev/#use-with-ide
282
+ .pdm.toml
283
+
284
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
285
+ __pypackages__/
286
+
287
+ # Celery stuff
288
+ celerybeat-schedule
289
+ celerybeat.pid
290
+
291
+ # SageMath parsed files
292
+ *.sage.py
293
+
294
+ # Environments
295
+ .venv
296
+ env/
297
+ venv/
298
+ ENV/
299
+ env.bak/
300
+ venv.bak/
301
+
302
+ # Spyder project settings
303
+ .spyderproject
304
+ .spyproject
305
+
306
+ # Rope project settings
307
+ .ropeproject
308
+
309
+ # mkdocs documentation
310
+ /site
311
+
312
+ # mypy
313
+ .mypy_cache/
314
+ .dmypy.json
315
+ dmypy.json
316
+
317
+ # Pyre type checker
318
+ .pyre/
319
+
320
+ # pytype static type analyzer
321
+ .pytype/
322
+
323
+ # Cython debug symbols
324
+ cython_debug/
325
+
326
+ # PyCharm
327
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
328
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
329
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
330
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
331
+ #.idea/
332
+
333
+ ### Python Patch ###
334
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
335
+ poetry.toml
336
+
337
+ # ruff
338
+ .ruff_cache/
339
+
340
+ # LSP config files
341
+ pyrightconfig.json
342
+
343
+ ### VisualStudioCode ###
344
+ .vscode/*
345
+ !.vscode/settings.json
346
+ !.vscode/tasks.json
347
+ !.vscode/launch.json
348
+ !.vscode/extensions.json
349
+ !.vscode/*.code-snippets
350
+
351
+ # Local History for Visual Studio Code
352
+ .history/
353
+
354
+ # Built Visual Studio Code Extensions
355
+ *.vsix
356
+
357
+ ### VisualStudioCode Patch ###
358
+ # Ignore all local history of files
359
+ .history
360
+ .ionide
361
+
362
+ ### Windows ###
363
+ # Windows thumbnail cache files
364
+ Thumbs.db
365
+ Thumbs.db:encryptable
366
+ ehthumbs.db
367
+ ehthumbs_vista.db
368
+
369
+ # Dump file
370
+ *.stackdump
371
+
372
+ # Folder config file
373
+ [Dd]esktop.ini
374
+
375
+ # Recycle Bin used on file shares
376
+ $RECYCLE.BIN/
377
+
378
+ # Windows Installer files
379
+ *.cab
380
+ *.msi
381
+ *.msix
382
+ *.msm
383
+ *.msp
384
+
385
+ # Windows shortcuts
386
+ *.lnk
387
+
388
+ ### VisualStudio ###
389
+ ## Ignore Visual Studio temporary files, build results, and
390
+ ## files generated by popular Visual Studio add-ons.
391
+ ##
392
+ ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
393
+
394
+ # User-specific files
395
+ *.rsuser
396
+ *.suo
397
+ *.user
398
+ *.userosscache
399
+ *.sln.docstates
400
+
401
+ # User-specific files (MonoDevelop/Xamarin Studio)
402
+ *.userprefs
403
+
404
+ # Mono auto generated files
405
+ mono_crash.*
406
+
407
+ # Build results
408
+ [Dd]ebug/
409
+ [Dd]ebugPublic/
410
+ [Rr]elease/
411
+ [Rr]eleases/
412
+ x64/
413
+ x86/
414
+ [Ww][Ii][Nn]32/
415
+ [Aa][Rr][Mm]/
416
+ [Aa][Rr][Mm]64/
417
+ bld/
418
+ [Bb]in/
419
+ [Oo]bj/
420
+ [Ll]og/
421
+ [Ll]ogs/
422
+
423
+ # Visual Studio 2015/2017 cache/options directory
424
+ .vs/
425
+ # Uncomment if you have tasks that create the project's static files in wwwroot
426
+ #wwwroot/
427
+
428
+ # Visual Studio 2017 auto generated files
429
+ Generated\ Files/
430
+
431
+ # MSTest test Results
432
+ [Tt]est[Rr]esult*/
433
+ [Bb]uild[Ll]og.*
434
+
435
+ # NUnit
436
+ *.VisualState.xml
437
+ TestResult.xml
438
+ nunit-*.xml
439
+
440
+ # Build Results of an ATL Project
441
+ [Dd]ebugPS/
442
+ [Rr]eleasePS/
443
+ dlldata.c
444
+
445
+ # Benchmark Results
446
+ BenchmarkDotNet.Artifacts/
447
+
448
+ # .NET Core
449
+ project.lock.json
450
+ project.fragment.lock.json
451
+ artifacts/
452
+
453
+ # ASP.NET Scaffolding
454
+ ScaffoldingReadMe.txt
455
+
456
+ # StyleCop
457
+ StyleCopReport.xml
458
+
459
+ # Files built by Visual Studio
460
+ *_i.c
461
+ *_p.c
462
+ *_h.h
463
+ *.ilk
464
+ *.meta
465
+ *.obj
466
+ *.iobj
467
+ *.pch
468
+ *.pdb
469
+ *.ipdb
470
+ *.pgc
471
+ *.pgd
472
+ *.rsp
473
+ *.sbr
474
+ *.tlb
475
+ *.tli
476
+ *.tlh
477
+ *.tmp
478
+ *.tmp_proj
479
+ *_wpftmp.csproj
480
+ *.tlog
481
+ *.vspscc
482
+ *.vssscc
483
+ .builds
484
+ *.pidb
485
+ *.svclog
486
+ *.scc
487
+
488
+ # Chutzpah Test files
489
+ _Chutzpah*
490
+
491
+ # Visual C++ cache files
492
+ ipch/
493
+ *.aps
494
+ *.ncb
495
+ *.opendb
496
+ *.opensdf
497
+ *.sdf
498
+ *.cachefile
499
+ *.VC.db
500
+ *.VC.VC.opendb
501
+
502
+ # Visual Studio profiler
503
+ *.psess
504
+ *.vsp
505
+ *.vspx
506
+ *.sap
507
+
508
+ # Visual Studio Trace Files
509
+ *.e2e
510
+
511
+ # TFS 2012 Local Workspace
512
+ $tf/
513
+
514
+ # Guidance Automation Toolkit
515
+ *.gpState
516
+
517
+ # ReSharper is a .NET coding add-in
518
+ _ReSharper*/
519
+ *.[Rr]e[Ss]harper
520
+ *.DotSettings.user
521
+
522
+ # TeamCity is a build add-in
523
+ _TeamCity*
524
+
525
+ # DotCover is a Code Coverage Tool
526
+ *.dotCover
527
+
528
+ # AxoCover is a Code Coverage Tool
529
+ .axoCover/*
530
+ !.axoCover/settings.json
531
+
532
+ # Coverlet is a free, cross platform Code Coverage Tool
533
+ coverage*.json
534
+ coverage*.xml
535
+ coverage*.info
536
+
537
+ # Visual Studio code coverage results
538
+ *.coverage
539
+ *.coveragexml
540
+
541
+ # NCrunch
542
+ _NCrunch_*
543
+ .*crunch*.local.xml
544
+ nCrunchTemp_*
545
+
546
+ # MightyMoose
547
+ *.mm.*
548
+ AutoTest.Net/
549
+
550
+ # Web workbench (sass)
551
+ .sass-cache/
552
+
553
+ # Installshield output folder
554
+ [Ee]xpress/
555
+
556
+ # DocProject is a documentation generator add-in
557
+ DocProject/buildhelp/
558
+ DocProject/Help/*.HxT
559
+ DocProject/Help/*.HxC
560
+ DocProject/Help/*.hhc
561
+ DocProject/Help/*.hhk
562
+ DocProject/Help/*.hhp
563
+ DocProject/Help/Html2
564
+ DocProject/Help/html
565
+
566
+ # Click-Once directory
567
+ publish/
568
+
569
+ # Publish Web Output
570
+ *.[Pp]ublish.xml
571
+ *.azurePubxml
572
+ # Note: Comment the next line if you want to checkin your web deploy settings,
573
+ # but database connection strings (with potential passwords) will be unencrypted
574
+ *.pubxml
575
+ *.publishproj
576
+
577
+ # Microsoft Azure Web App publish settings. Comment the next line if you want to
578
+ # checkin your Azure Web App publish settings, but sensitive information contained
579
+ # in these scripts will be unencrypted
580
+ PublishScripts/
581
+
582
+ # NuGet Packages
583
+ *.nupkg
584
+ # NuGet Symbol Packages
585
+ *.snupkg
586
+ # The packages folder can be ignored because of Package Restore
587
+ **/[Pp]ackages/*
588
+ # except build/, which is used as an MSBuild target.
589
+ !**/[Pp]ackages/build/
590
+ # Uncomment if necessary however generally it will be regenerated when needed
591
+ #!**/[Pp]ackages/repositories.config
592
+ # NuGet v3's project.json files produces more ignorable files
593
+ *.nuget.props
594
+ *.nuget.targets
595
+
596
+ # Microsoft Azure Build Output
597
+ csx/
598
+ *.build.csdef
599
+
600
+ # Microsoft Azure Emulator
601
+ ecf/
602
+ rcf/
603
+
604
+ # Windows Store app package directories and files
605
+ AppPackages/
606
+ BundleArtifacts/
607
+ Package.StoreAssociation.xml
608
+ _pkginfo.txt
609
+ *.appx
610
+ *.appxbundle
611
+ *.appxupload
612
+
613
+ # Visual Studio cache files
614
+ # files ending in .cache can be ignored
615
+ *.[Cc]ache
616
+ # but keep track of directories ending in .cache
617
+ !?*.[Cc]ache/
618
+
619
+ # Others
620
+ ClientBin/
621
+ ~$*
622
+ *.dbmdl
623
+ *.dbproj.schemaview
624
+ *.jfm
625
+ *.pfx
626
+ *.publishsettings
627
+ orleans.codegen.cs
628
+
629
+ # Including strong name files can present a security risk
630
+ # (https://github.com/github/gitignore/pull/2483#issue-259490424)
631
+ #*.snk
632
+
633
+ # Since there are multiple workflows, uncomment next line to ignore bower_components
634
+ # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
635
+ #bower_components/
636
+
637
+ # RIA/Silverlight projects
638
+ Generated_Code/
639
+
640
+ # Backup & report files from converting an old project file
641
+ # to a newer Visual Studio version. Backup files are not needed,
642
+ # because we have git ;-)
643
+ _UpgradeReport_Files/
644
+ Backup*/
645
+ UpgradeLog*.XML
646
+ UpgradeLog*.htm
647
+ ServiceFabricBackup/
648
+ *.rptproj.bak
649
+
650
+ # SQL Server files
651
+ *.mdf
652
+ *.ldf
653
+ *.ndf
654
+
655
+ # Business Intelligence projects
656
+ *.rdl.data
657
+ *.bim.layout
658
+ *.bim_*.settings
659
+ *.rptproj.rsuser
660
+ *- [Bb]ackup.rdl
661
+ *- [Bb]ackup ([0-9]).rdl
662
+ *- [Bb]ackup ([0-9][0-9]).rdl
663
+
664
+ # Microsoft Fakes
665
+ FakesAssemblies/
666
+
667
+ # GhostDoc plugin setting file
668
+ *.GhostDoc.xml
669
+
670
+ # Node.js Tools for Visual Studio
671
+ .ntvs_analysis.dat
672
+ node_modules/
673
+
674
+ # Visual Studio 6 build log
675
+ *.plg
676
+
677
+ # Visual Studio 6 workspace options file
678
+ *.opt
679
+
680
+ # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
681
+ *.vbw
682
+
683
+ # Visual Studio 6 auto-generated project file (contains which files were open etc.)
684
+ *.vbp
685
+
686
+ # Visual Studio 6 workspace and project file (working project files containing files to include in project)
687
+ *.dsw
688
+ *.dsp
689
+
690
+ # Visual Studio 6 technical files
691
+
692
+ # Visual Studio LightSwitch build output
693
+ **/*.HTMLClient/GeneratedArtifacts
694
+ **/*.DesktopClient/GeneratedArtifacts
695
+ **/*.DesktopClient/ModelManifest.xml
696
+ **/*.Server/GeneratedArtifacts
697
+ **/*.Server/ModelManifest.xml
698
+ _Pvt_Extensions
699
+
700
+ # Paket dependency manager
701
+ .paket/paket.exe
702
+ paket-files/
703
+
704
+ # FAKE - F# Make
705
+ .fake/
706
+
707
+ # CodeRush personal settings
708
+ .cr/personal
709
+
710
+ # Python Tools for Visual Studio (PTVS)
711
+ *.pyc
712
+
713
+ # Cake - Uncomment if you are using it
714
+ # tools/**
715
+ # !tools/packages.config
716
+
717
+ # Tabs Studio
718
+ *.tss
719
+
720
+ # Telerik's JustMock configuration file
721
+ *.jmconfig
722
+
723
+ # BizTalk build output
724
+ *.btp.cs
725
+ *.btm.cs
726
+ *.odx.cs
727
+ *.xsd.cs
728
+
729
+ # OpenCover UI analysis results
730
+ OpenCover/
731
+
732
+ # Azure Stream Analytics local run output
733
+ ASALocalRun/
734
+
735
+ # MSBuild Binary and Structured Log
736
+ *.binlog
737
+
738
+ # NVidia Nsight GPU debugger configuration file
739
+ *.nvuser
740
+
741
+ # MFractors (Xamarin productivity tool) working folder
742
+ .mfractor/
743
+
744
+ # Local History for Visual Studio
745
+ .localhistory/
746
+
747
+ # Visual Studio History (VSHistory) files
748
+ .vshistory/
749
+
750
+ # BeatPulse healthcheck temp database
751
+ healthchecksdb
752
+
753
+ # Backup folder for Package Reference Convert tool in Visual Studio 2017
754
+ MigrationBackup/
755
+
756
+ # Ionide (cross platform F# VS Code tools) working folder
757
+ .ionide/
758
+
759
+ # Fody - auto-generated XML schema
760
+ FodyWeavers.xsd
761
+
762
+ # VS Code files for those working on multiple tools
763
+ *.code-workspace
764
+
765
+ # Local History for Visual Studio Code
766
+
767
+ # Windows Installer files from build outputs
768
+
769
+ # JetBrains Rider
770
+ *.sln.iml
771
+
772
+ ### VisualStudio Patch ###
773
+ # Additional files built by Visual Studio
774
+
775
+ # End of https://www.toptal.com/developers/gitignore/api/linux,macos,dotenv,python,windows,intellij,visualstudio,visualstudiocode
.python-version ADDED
@@ -0,0 +1 @@
 
 
1
+ 3.12
README.md CHANGED
@@ -1,12 +1,15 @@
1
  ---
2
- title: Qwen VL Object Detection
3
- emoji: 🦀
4
- colorFrom: red
5
- colorTo: green
 
6
  sdk: gradio
7
  sdk_version: 5.49.1
 
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Qwen-VL Object-Detection
3
+ short_description: Compare Qwen-VL model variants for object detection.
4
+ emoji:
5
+ colorFrom: indigo
6
+ colorTo: indigo
7
  sdk: gradio
8
  sdk_version: 5.49.1
9
+ python_version: 3.12.11
10
  app_file: app.py
11
  pinned: false
12
+ license: apache-2.0
13
  ---
14
 
15
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ import gc
3
+ import json
4
+ import os
5
+ from io import BytesIO
6
+
7
+ import gradio as gr
8
+ import torch
9
+ from json_repair import repair_json
10
+ from qwen_vl_utils import process_vision_info
11
+ from transformers import (
12
+ AutoProcessor,
13
+ Qwen2_5_VLForConditionalGeneration,
14
+ Qwen2VLForConditionalGeneration,
15
+ Qwen3VLForConditionalGeneration,
16
+ )
17
+
18
+ os.environ["CUDA_VISIBLE_DEVICES"] = "0"
19
+
20
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
21
+
22
+ model_ids = [
23
+ "Qwen/Qwen2-VL-2B-Instruct",
24
+ "Qwen/Qwen2-VL-7B-Instruct",
25
+ "Qwen/Qwen2.5-VL-3B-Instruct",
26
+ "Qwen/Qwen2.5-VL-7B-Instruct",
27
+ "Qwen/Qwen2.5-VL-32B-Instruct",
28
+ "Qwen/Qwen2.5-VL-72B-Instruct",
29
+ "Qwen/Qwen3-VL-2B-Instruct",
30
+ "Qwen/Qwen3-VL-4B-Instruct",
31
+ "Qwen/Qwen3-VL-8B-Instruct",
32
+ "Qwen/Qwen3-VL-32B-Instruct",
33
+ ]
34
+
35
+
36
+ def image_to_base64(image):
37
+ buffered = BytesIO()
38
+ image.save(buffered, format="PNG")
39
+ img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
40
+ return img_str
41
+
42
+
43
+ with gr.Blocks() as demo:
44
+ title = gr.Markdown("# Qwen-VL-Localization")
45
+
46
+ if DEVICE != "cuda":
47
+ gr.Markdown(
48
+ "⚠️ **CUDA not available.** This application requires a CUDA-compatible GPU to function properly. You can duplicate this space with a CUDA-enabled runtime."
49
+ )
50
+
51
+ with gr.Row():
52
+ with gr.Column():
53
+ gr.Markdown("## Inputs")
54
+
55
+ image_input = gr.Image(
56
+ label="Input Image",
57
+ type="pil",
58
+ )
59
+
60
+ gr.Markdown("## Settings")
61
+
62
+ input_model_id = gr.Dropdown(
63
+ choices=model_ids,
64
+ label="Select Model ID",
65
+ )
66
+ default_system_prompt = 'You are a helpful assistant to detect objects in images. When asked to detect elements based on a description, you return a valid JSON object containing bounding boxes for all elements in the form `[["bbox_2d": [XMIN, YMIN, XMAX, YMAX], "label": "LABEL"], ...]`. For example, a valid response could be: `[{"bbox_2d": [10, 30, 20, 60], "label": "face"}, {"bbox_2d": [40, 15, 52, 27], "label": "face"}]`.'
67
+ system_prompt = gr.Textbox(
68
+ label="System Prompt:",
69
+ lines=3,
70
+ value=default_system_prompt,
71
+ )
72
+ default_user_prompt = "detect humans"
73
+ user_prompt = gr.Textbox(
74
+ label="User Prompt:",
75
+ lines=3,
76
+ value=default_user_prompt,
77
+ )
78
+ max_new_tokens = gr.Slider(
79
+ label="Max New Tokens:",
80
+ minimum=32,
81
+ maximum=4096,
82
+ value=256,
83
+ step=32,
84
+ interactive=True,
85
+ )
86
+
87
+ with gr.Column():
88
+ gr.Markdown("## Outputs")
89
+
90
+ output_annotated_image = gr.AnnotatedImage(
91
+ format="jpeg",
92
+ key="output_annotated_image",
93
+ label="Output Image",
94
+ )
95
+
96
+ gr.Markdown("## Detections")
97
+
98
+ output_text = gr.Textbox(
99
+ label="Output Text",
100
+ lines=3,
101
+ key="output_text",
102
+ )
103
+
104
+ with gr.Row():
105
+ run_button = gr.Button("Run")
106
+
107
+ # Global variables to track loaded model
108
+ current_model = None
109
+ current_processor = None
110
+ current_model_id = None
111
+
112
+ def run(
113
+ image,
114
+ system_prompt: str,
115
+ user_prompt: str,
116
+ model_id: str,
117
+ max_new_tokens: int = 1024,
118
+ ):
119
+ global current_model, current_processor, current_model_id
120
+ scale = False if model_id.startswith("Qwen/Qwen2.5-VL") else True
121
+
122
+ # Only load model if it's different from the currently loaded one
123
+ if current_model_id != model_id or current_model is None:
124
+ # Clear previous model from memory
125
+ if current_model is not None:
126
+ del current_model
127
+ current_model = None
128
+
129
+ if current_processor is not None:
130
+ del current_processor
131
+ current_processor = None
132
+
133
+ # Force garbage collection and clear CUDA cache
134
+ gc.collect()
135
+ torch.cuda.empty_cache()
136
+
137
+ if torch.cuda.is_available():
138
+ torch.cuda.synchronize()
139
+
140
+ # Load new model
141
+ if model_id.startswith("Qwen/Qwen2-VL"):
142
+ model_loader = Qwen2VLForConditionalGeneration
143
+ elif model_id.startswith("Qwen/Qwen2.5-VL"):
144
+ model_loader = Qwen2_5_VLForConditionalGeneration
145
+ elif model_id.startswith("Qwen/Qwen3-VL"):
146
+ model_loader = Qwen3VLForConditionalGeneration
147
+ current_model = model_loader.from_pretrained(
148
+ model_id,
149
+ torch_dtype="auto",
150
+ device_map="auto",
151
+ ).eval()
152
+ current_processor = AutoProcessor.from_pretrained(model_id)
153
+ current_model_id = model_id
154
+
155
+ model = current_model
156
+ processor = current_processor
157
+
158
+ messages = [
159
+ {
160
+ "role": "user",
161
+ "content": [
162
+ {
163
+ "type": "image",
164
+ "image": f"data:image;base64,{image_to_base64(image)}",
165
+ },
166
+ {"type": "text", "text": system_prompt},
167
+ {"type": "text", "text": user_prompt},
168
+ ],
169
+ }
170
+ ]
171
+
172
+ text = processor.apply_chat_template(
173
+ messages,
174
+ tokenize=False,
175
+ add_generation_prompt=True,
176
+ )
177
+ image_inputs, video_inputs = process_vision_info(messages)
178
+ inputs = processor(
179
+ text=[text],
180
+ images=image_inputs,
181
+ videos=video_inputs,
182
+ padding=True,
183
+ return_tensors="pt",
184
+ )
185
+ inputs = inputs.to("cuda")
186
+
187
+ generated_ids = model.generate(**inputs, max_new_tokens=max_new_tokens)
188
+ generated_ids_trimmed = [
189
+ out_ids[len(in_ids) :]
190
+ for in_ids, out_ids in zip(inputs.input_ids, generated_ids)
191
+ ]
192
+ output_text = processor.batch_decode(
193
+ generated_ids_trimmed,
194
+ skip_special_tokens=True,
195
+ clean_up_tokenization_spaces=False,
196
+ )
197
+
198
+ output_text = str(output_text[0])
199
+ output_text = repair_json(output_text)
200
+ output_json = json.loads(output_text)
201
+
202
+ x_scale = float(image.width / 1000) if scale else 1.0
203
+ y_scale = float(image.height / 1000) if scale else 1.0
204
+ bboxes = []
205
+ for detection in output_json:
206
+ if "bbox_2d" not in detection:
207
+ continue
208
+ if len(detection["bbox_2d"]) != 4:
209
+ continue
210
+ if "label" not in detection:
211
+ continue
212
+
213
+ xmin, ymin, xmax, ymax = detection["bbox_2d"]
214
+ label = detection.get("label", "")
215
+ bbox = [
216
+ int(xmin * x_scale),
217
+ int(ymin * y_scale),
218
+ int(xmax * x_scale),
219
+ int(ymax * y_scale),
220
+ ]
221
+ bboxes.append((bbox, label))
222
+
223
+ return [(image, bboxes), str(output_text)]
224
+
225
+ # Connect the button to the detection function
226
+ run_button.click(
227
+ fn=run,
228
+ inputs=[
229
+ image_input,
230
+ system_prompt,
231
+ user_prompt,
232
+ input_model_id,
233
+ max_new_tokens,
234
+ ],
235
+ outputs=[
236
+ output_annotated_image,
237
+ output_text,
238
+ ],
239
+ )
240
+
241
+ if __name__ == "__main__":
242
+ demo.launch(
243
+ # share=True,
244
+ )
pyproject.toml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "qwen-vl-localization"
3
+ version = "0.1.0"
4
+ requires-python = ">=3.12"
5
+ dependencies = [
6
+ "gradio~=5.49.1",
7
+ "json-repair>=0.52.4",
8
+ "qwen-vl-utils>=0.0.14",
9
+ "torch~=2.8.0",
10
+ "torchvision>=0.23.0",
11
+ "transformers[torch]~=4.57.1",
12
+ ]
requirements.txt ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file was autogenerated by uv via the following command:
2
+ # uv pip compile pyproject.toml -o requirements.txt
3
+ accelerate==1.11.0
4
+ # via transformers
5
+ aiofiles==24.1.0
6
+ # via gradio
7
+ annotated-doc==0.0.4
8
+ # via fastapi
9
+ annotated-types==0.7.0
10
+ # via pydantic
11
+ anyio==4.11.0
12
+ # via
13
+ # gradio
14
+ # httpx
15
+ # starlette
16
+ av==16.0.1
17
+ # via qwen-vl-utils
18
+ brotli==1.2.0
19
+ # via gradio
20
+ certifi==2025.10.5
21
+ # via
22
+ # httpcore
23
+ # httpx
24
+ # requests
25
+ charset-normalizer==3.4.4
26
+ # via requests
27
+ click==8.3.0
28
+ # via
29
+ # typer
30
+ # uvicorn
31
+ fastapi==0.121.1
32
+ # via gradio
33
+ ffmpy==0.6.4
34
+ # via gradio
35
+ filelock==3.20.0
36
+ # via
37
+ # huggingface-hub
38
+ # torch
39
+ # transformers
40
+ fsspec==2025.10.0
41
+ # via
42
+ # gradio-client
43
+ # huggingface-hub
44
+ # torch
45
+ gradio==5.49.1
46
+ # via qwen-vl-localization (pyproject.toml)
47
+ gradio-client==1.13.3
48
+ # via gradio
49
+ groovy==0.1.2
50
+ # via gradio
51
+ h11==0.16.0
52
+ # via
53
+ # httpcore
54
+ # uvicorn
55
+ hf-xet==1.2.0
56
+ # via huggingface-hub
57
+ httpcore==1.0.9
58
+ # via httpx
59
+ httpx==0.28.1
60
+ # via
61
+ # gradio
62
+ # gradio-client
63
+ # safehttpx
64
+ huggingface-hub==0.36.0
65
+ # via
66
+ # accelerate
67
+ # gradio
68
+ # gradio-client
69
+ # tokenizers
70
+ # transformers
71
+ idna==3.11
72
+ # via
73
+ # anyio
74
+ # httpx
75
+ # requests
76
+ jinja2==3.1.6
77
+ # via
78
+ # gradio
79
+ # torch
80
+ json-repair==0.53.0
81
+ # via qwen-vl-localization (pyproject.toml)
82
+ markdown-it-py==4.0.0
83
+ # via rich
84
+ markupsafe==3.0.3
85
+ # via
86
+ # gradio
87
+ # jinja2
88
+ mdurl==0.1.2
89
+ # via markdown-it-py
90
+ mpmath==1.3.0
91
+ # via sympy
92
+ networkx==3.5
93
+ # via torch
94
+ numpy==2.3.4
95
+ # via
96
+ # accelerate
97
+ # gradio
98
+ # pandas
99
+ # torchvision
100
+ # transformers
101
+ nvidia-cublas-cu12==12.8.4.1
102
+ # via
103
+ # nvidia-cudnn-cu12
104
+ # nvidia-cusolver-cu12
105
+ # torch
106
+ nvidia-cuda-cupti-cu12==12.8.90
107
+ # via torch
108
+ nvidia-cuda-nvrtc-cu12==12.8.93
109
+ # via torch
110
+ nvidia-cuda-runtime-cu12==12.8.90
111
+ # via torch
112
+ nvidia-cudnn-cu12==9.10.2.21
113
+ # via torch
114
+ nvidia-cufft-cu12==11.3.3.83
115
+ # via torch
116
+ nvidia-cufile-cu12==1.13.1.3
117
+ # via torch
118
+ nvidia-curand-cu12==10.3.9.90
119
+ # via torch
120
+ nvidia-cusolver-cu12==11.7.3.90
121
+ # via torch
122
+ nvidia-cusparse-cu12==12.5.8.93
123
+ # via
124
+ # nvidia-cusolver-cu12
125
+ # torch
126
+ nvidia-cusparselt-cu12==0.7.1
127
+ # via torch
128
+ nvidia-nccl-cu12==2.27.3
129
+ # via torch
130
+ nvidia-nvjitlink-cu12==12.8.93
131
+ # via
132
+ # nvidia-cufft-cu12
133
+ # nvidia-cusolver-cu12
134
+ # nvidia-cusparse-cu12
135
+ # torch
136
+ nvidia-nvtx-cu12==12.8.90
137
+ # via torch
138
+ orjson==3.11.4
139
+ # via gradio
140
+ packaging==25.0
141
+ # via
142
+ # accelerate
143
+ # gradio
144
+ # gradio-client
145
+ # huggingface-hub
146
+ # qwen-vl-utils
147
+ # transformers
148
+ pandas==2.3.3
149
+ # via gradio
150
+ pillow==11.3.0
151
+ # via
152
+ # gradio
153
+ # qwen-vl-utils
154
+ # torchvision
155
+ psutil==7.1.3
156
+ # via accelerate
157
+ pydantic==2.11.10
158
+ # via
159
+ # fastapi
160
+ # gradio
161
+ pydantic-core==2.33.2
162
+ # via pydantic
163
+ pydub==0.25.1
164
+ # via gradio
165
+ pygments==2.19.2
166
+ # via rich
167
+ python-dateutil==2.9.0.post0
168
+ # via pandas
169
+ python-multipart==0.0.20
170
+ # via gradio
171
+ pytz==2025.2
172
+ # via pandas
173
+ pyyaml==6.0.3
174
+ # via
175
+ # accelerate
176
+ # gradio
177
+ # huggingface-hub
178
+ # transformers
179
+ qwen-vl-utils==0.0.14
180
+ # via qwen-vl-localization (pyproject.toml)
181
+ regex==2025.11.3
182
+ # via transformers
183
+ requests==2.32.5
184
+ # via
185
+ # huggingface-hub
186
+ # qwen-vl-utils
187
+ # transformers
188
+ rich==14.2.0
189
+ # via typer
190
+ ruff==0.14.4
191
+ # via gradio
192
+ safehttpx==0.1.7
193
+ # via gradio
194
+ safetensors==0.6.2
195
+ # via
196
+ # accelerate
197
+ # transformers
198
+ semantic-version==2.10.0
199
+ # via gradio
200
+ setuptools==80.9.0
201
+ # via
202
+ # torch
203
+ # triton
204
+ shellingham==1.5.4
205
+ # via typer
206
+ six==1.17.0
207
+ # via python-dateutil
208
+ sniffio==1.3.1
209
+ # via anyio
210
+ starlette==0.49.3
211
+ # via
212
+ # fastapi
213
+ # gradio
214
+ sympy==1.14.0
215
+ # via torch
216
+ tokenizers==0.22.1
217
+ # via transformers
218
+ tomlkit==0.13.3
219
+ # via gradio
220
+ torch==2.8.0
221
+ # via
222
+ # qwen-vl-localization (pyproject.toml)
223
+ # accelerate
224
+ # torchvision
225
+ # transformers
226
+ torchvision==0.23.0
227
+ # via qwen-vl-localization (pyproject.toml)
228
+ tqdm==4.67.1
229
+ # via
230
+ # huggingface-hub
231
+ # transformers
232
+ transformers==4.57.1
233
+ # via qwen-vl-localization (pyproject.toml)
234
+ triton==3.4.0
235
+ # via torch
236
+ typer==0.20.0
237
+ # via gradio
238
+ typing-extensions==4.15.0
239
+ # via
240
+ # anyio
241
+ # fastapi
242
+ # gradio
243
+ # gradio-client
244
+ # huggingface-hub
245
+ # pydantic
246
+ # pydantic-core
247
+ # starlette
248
+ # torch
249
+ # typer
250
+ # typing-inspection
251
+ typing-inspection==0.4.2
252
+ # via pydantic
253
+ tzdata==2025.2
254
+ # via pandas
255
+ urllib3==2.5.0
256
+ # via requests
257
+ uvicorn==0.38.0
258
+ # via gradio
259
+ websockets==15.0.1
260
+ # via gradio-client
uv.lock ADDED
The diff for this file is too large to render. See raw diff