ldaca-web-app 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ldaca_web_app-0.1.0/.gitignore +10 -0
- ldaca_web_app-0.1.0/PKG-INFO +56 -0
- ldaca_web_app-0.1.0/README.md +22 -0
- ldaca_web_app-0.1.0/pyproject.toml +79 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/__init__.py +14 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/__init__.py +8 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/implementations/concordance.py +58 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/implementations/quotation.py +69 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/implementations/sequential_analysis.py +58 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/implementations/token_frequency.py +37 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/implementations/topic_modeling.py +39 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/manager.py +148 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/models.py +83 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/analysis/results.py +40 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/admin.py +99 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/auth.py +277 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/config.py +56 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/feedback.py +145 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/files.py +818 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/tasks.py +164 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/text.py +66 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/__init__.py +44 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/__init__.py +10 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/ai_annotation.py +617 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/ai_annotation_core.py +185 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/concordance.py +455 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/concordance_core.py +632 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/current_tasks.py +35 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/generated_columns.py +130 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/quotation.py +567 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/quotation_core.py +557 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/sequential_analysis.py +550 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/token_frequencies.py +538 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/analyses/topic_modeling.py +619 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/base.py +813 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/lifecycle.py +524 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/nodes.py +1362 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/api/workspaces/utils.py +275 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/cli.py +440 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/__init__.py +8 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/analysis_admin.py +174 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/analysis_helpers.py +32 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/api_models.py +70 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/auth.py +93 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/docworkspace_data_types.py +92 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/expression_parser.py +422 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/services/quotation_client.py +129 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/utils.py +468 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/worker.py +297 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/worker_task_manager.py +883 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/worker_tasks_concordance.py +141 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/worker_tasks_download.py +121 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/worker_tasks_import.py +120 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/worker_tasks_quotation.py +120 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/worker_tasks_token.py +175 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/worker_tasks_topic.py +445 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/core/workspace.py +366 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/db.py +327 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/deploy.py +262 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/main.py +353 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/models/__init__.py +1035 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/__init__.py +8 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/configs/.env.example +43 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/configs/nginx.conf.template +43 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/__init__.py +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/LDaCAFavicon_Dark.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/LDaCA_logo_Dark.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/LDaCA_logo_Light.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AiAnnotatorFeature-CyjfDOzo.js +5 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AiAnnotatorFeature-CyjfDOzo.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AnalysisCardLayout-BflyP8wr.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AnalysisCardLayout-BflyP8wr.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AnalysisLockedNotice-CMXFv34D.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AnalysisLockedNotice-CMXFv34D.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AnalysisRunningStateCard-DEDAHtuC.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AnalysisRunningStateCard-DEDAHtuC.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AnalysisTaskBanner-BrjeYTEy.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/AnalysisTaskBanner-BrjeYTEy.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/ConcordanceFeature-DXmwcUTs.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/ConcordanceFeature-DXmwcUTs.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/DataLoaderFeature-B0xN9AdD.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/DataLoaderFeature-B0xN9AdD.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/DataPreprocessingFeature-CDSt7ytv.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/DataPreprocessingFeature-CDSt7ytv.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/DetachColumnsDialog-CGutpQZw.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/DetachColumnsDialog-CGutpQZw.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/ExportFeature-C40farmf.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/ExportFeature-C40farmf.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/FeedbackPanel-CZKoNQwv.js +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/FeedbackPanel-Djf3vgqc.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/FeedbackPanel-Djf3vgqc.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/GroupedResultsPageSizeSummary-BY4_OKA8.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/GroupedResultsPageSizeSummary-BY4_OKA8.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/HelpIcon-C9nQVC3q.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/HelpIcon-C9nQVC3q.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/MetadataColumnSelector-XaYmSTLR.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/MetadataColumnSelector-XaYmSTLR.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/NodeSelectionPanel--TdNQTeL.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/NodeSelectionPanel--TdNQTeL.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/Pagination-022XSKeg.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/Pagination-022XSKeg.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/QuotationFeature-rDJ3XMRV.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/QuotationFeature-rDJ3XMRV.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/SequentialAnalysisFeature-ORc5tSB1.js +34 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/SequentialAnalysisFeature-ORc5tSB1.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/TokenFrequencyFeature-BaLW8o0h.js +6 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/TokenFrequencyFeature-BaLW8o0h.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/TopicModelingFeature-BvJMJx_e.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/TopicModelingFeature-BvJMJx_e.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/TutorialView-CyM6LC5M.js +269 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/TutorialView-CyM6LC5M.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/TutorialView-DoM7Y3CM.css +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/WorkspaceView-BZV40eAE.css +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/WorkspaceView-DqiBn1ni.js +17 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/WorkspaceView-DqiBn1ni.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/alert-dialog-DBXqHvoA.js +8 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/alert-dialog-DBXqHvoA.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/analysisStore-JIRlH42w.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/analysisStore-JIRlH42w.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/badge-CfQjRH7S.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/badge-CfQjRH7S.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/card-uRMKEvvf.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/card-uRMKEvvf.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/checklistSearch-PYRpK4o1.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/checklistSearch-PYRpK4o1.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/common-DzdICCkd.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/common-DzdICCkd.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/confirm-dialog-DGgr3Nvt.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/confirm-dialog-DGgr3Nvt.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/core-C4EYlNVf.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/core-C4EYlNVf.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/datetimeFormatInfer-B_pAB07m.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/datetimeFormatInfer-B_pAB07m.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/dist-B_SwfAgn.js +6 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/dist-B_SwfAgn.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/dist-CnC55jT2.js +7 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/dist-CnC55jT2.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/dist-js-Cs9d7qNF.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/dist-js-Cs9d7qNF.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/dist-jzM4BAQk.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/dist-jzM4BAQk.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/download-D4uSHjro.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/download-D4uSHjro.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/ellipsis-BieMHHvV.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/ellipsis-BieMHHvV.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/es2015-CZrWoLMe.js +42 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/es2015-CZrWoLMe.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/http-D-viG9Gl.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/http-D-viG9Gl.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/index-BKb1u1EE.css +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/index-QVmGxAfm.js +16 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/index-QVmGxAfm.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/jsx-runtime-DmD3As1j.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/jsx-runtime-DmD3As1j.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/lib-DQQFfvUa.js +30 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/lib-DQQFfvUa.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/loader-circle-CO1R4-15.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/loader-circle-CO1R4-15.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/logo-KvETMJyX.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/memoize-DKbAxBGj.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/memoize-DKbAxBGj.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/plus-Csg8SDjp.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/plus-Csg8SDjp.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/scroll-area-BbpTnRgH.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/scroll-area-BbpTnRgH.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/table-CfiYNsrb.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/table-CfiYNsrb.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/tabs-BTywRTNQ.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/tabs-BTywRTNQ.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/trash-2-BDVHinmn.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/trash-2-BDVHinmn.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/useWorkspaceData-BWaXP_IC.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/useWorkspaceData-BWaXP_IC.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/useWorkspaceStatus-CycQ30mN.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/useWorkspaceStatus-CycQ30mN.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/value-DAIuyc3J.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/value-DAIuyc3J.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/workspaceName-DNGZsANb.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/workspaceName-DNGZsANb.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/x-HsIUsI7s.js +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/assets/x-HsIUsI7s.js.map +1 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/favicon.ico +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/index.html +22 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/concordance.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/data_loader.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/data_loader_active_workspace.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/data_loader_files_section.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/data_loader_workspace_manager.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/export.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_concat.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_concat_schema_status.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_create.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_create_expression.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_filter.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_filter_conditions.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_filter_new_node_name.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_join.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_join_column_picker.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/preprocessing_slice.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/quotation_extraction.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/sequential_analysis.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/token_frequency.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/token_frequency_statistical_measures.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/token_frequency_stop_words.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/token_frequency_unified_word_cloud.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/assets/topic_modeling.png +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/concordance.md +50 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/data-loader.md +108 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/export.md +38 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/index.md +58 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/preprocessing.md +198 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/quotation.md +46 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/sequential-analysis.md +46 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/token-frequency.md +79 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/frontend/build/tutorials/topic-modeling.md +42 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/ADO/README.md +6 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/ADO/candidate_info_gender.csv +134 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/ADO/qldelection2020_candidate_tweets.csv +6048 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/Hansard/README.md +6 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/Hansard/economy_agenda.csv +5873 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/Hansard/housing_agenda.csv +2281 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/example.txt +2 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/example_quotations/sample_texts.xlsx +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/sample_data/zip_example/data.zip +0 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/stopwords_de.txt +131 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/stopwords_en.txt +175 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/stopwords_es.txt +151 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/resources/stopwords_fr.txt +146 -0
- ldaca_web_app-0.1.0/src/ldaca_web_app/settings.py +207 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ldaca-web-app
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LDaCA Web App - FastAPI backend with bundled production frontend for the Language Data Commons of Australia
|
|
5
|
+
Author: Australian Text Analytics Platform
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: corpus,fastapi,ldaca,linguistics,text-analytics,web-app
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Science/Research
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
14
|
+
Requires-Python: >=3.14
|
|
15
|
+
Requires-Dist: aiosqlite>=0.21.0
|
|
16
|
+
Requires-Dist: bertopic>=0.17.3
|
|
17
|
+
Requires-Dist: docworkspace>=0.2.1
|
|
18
|
+
Requires-Dist: fastapi-users[sqlalchemy]>=14.0.1
|
|
19
|
+
Requires-Dist: fastapi[standard]>=0.135.0
|
|
20
|
+
Requires-Dist: fastexcel>=0.18.0
|
|
21
|
+
Requires-Dist: google-auth-oauthlib>=1.2.2
|
|
22
|
+
Requires-Dist: httpx>=0.27.0
|
|
23
|
+
Requires-Dist: ldaca-loader
|
|
24
|
+
Requires-Dist: openai>=2.26.0
|
|
25
|
+
Requires-Dist: psutil>=6.1.0
|
|
26
|
+
Requires-Dist: pyairtable>=3.3.0
|
|
27
|
+
Requires-Dist: pyarrow>=16.0.0
|
|
28
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
29
|
+
Requires-Dist: tbb>=2022.3.1; sys_platform != 'darwin'
|
|
30
|
+
Provides-Extra: deploy
|
|
31
|
+
Requires-Dist: ipython>=9.5.0; extra == 'deploy'
|
|
32
|
+
Requires-Dist: jupyter-server-proxy>=4.4.0; extra == 'deploy'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# LDaCA Web App
|
|
36
|
+
|
|
37
|
+
All-in-one Python package for the LDaCA platform: a FastAPI backend with a bundled production React frontend. Install once, run with a single command.
|
|
38
|
+
|
|
39
|
+
## Quick start
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Install and run (backend + frontend on one port)
|
|
43
|
+
uvx ldaca-web-app
|
|
44
|
+
|
|
45
|
+
# Or run only the backend API
|
|
46
|
+
uvx ldaca-web-app --backend
|
|
47
|
+
|
|
48
|
+
# Custom port
|
|
49
|
+
uvx ldaca-web-app --port 9000
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Start here
|
|
53
|
+
|
|
54
|
+
- Full docs: `docs/index.md`
|
|
55
|
+
- Run locally: `docs/user-guide/running-locally.md`
|
|
56
|
+
- Configuration: `docs/reference/configuration.md`
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# LDaCA Web App
|
|
2
|
+
|
|
3
|
+
All-in-one Python package for the LDaCA platform: a FastAPI backend with a bundled production React frontend. Install once, run with a single command.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install and run (backend + frontend on one port)
|
|
9
|
+
uvx ldaca-web-app
|
|
10
|
+
|
|
11
|
+
# Or run only the backend API
|
|
12
|
+
uvx ldaca-web-app --backend
|
|
13
|
+
|
|
14
|
+
# Custom port
|
|
15
|
+
uvx ldaca-web-app --port 9000
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Start here
|
|
19
|
+
|
|
20
|
+
- Full docs: `docs/index.md`
|
|
21
|
+
- Run locally: `docs/user-guide/running-locally.md`
|
|
22
|
+
- Configuration: `docs/reference/configuration.md`
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ldaca-web-app"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "LDaCA Web App - FastAPI backend with bundled production frontend for the Language Data Commons of Australia"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.14"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [{ name = "Australian Text Analytics Platform" }]
|
|
9
|
+
keywords = [
|
|
10
|
+
"ldaca",
|
|
11
|
+
"text-analytics",
|
|
12
|
+
"corpus",
|
|
13
|
+
"linguistics",
|
|
14
|
+
"fastapi",
|
|
15
|
+
"web-app",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Science/Research",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Topic :: Scientific/Engineering :: Information Analysis",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"aiosqlite>=0.21.0",
|
|
27
|
+
"bertopic>=0.17.3",
|
|
28
|
+
"fastapi-users[sqlalchemy]>=14.0.1", # Includes fastapi, python-multipart, sqlalchemy
|
|
29
|
+
"fastapi[standard]>=0.135.0", # Includes uvicorn, pydantic, starlette
|
|
30
|
+
"fastexcel>=0.18.0",
|
|
31
|
+
"google-auth-oauthlib>=1.2.2", # Includes google-auth
|
|
32
|
+
"httpx>=0.27.0",
|
|
33
|
+
"pydantic-settings>=2.0.0",
|
|
34
|
+
"psutil>=6.1.0", # Process management for proper cleanup of child processes
|
|
35
|
+
"docworkspace>=0.2.1",
|
|
36
|
+
"ldaca-loader",
|
|
37
|
+
"pyarrow>=16.0.0",
|
|
38
|
+
"tbb>=2022.3.1 ; sys_platform != 'darwin'",
|
|
39
|
+
"openai>=2.26.0",
|
|
40
|
+
"pyairtable>=3.3.0",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.optional-dependencies]
|
|
44
|
+
deploy = ["jupyter-server-proxy>=4.4.0", "ipython>=9.5.0"]
|
|
45
|
+
|
|
46
|
+
[project.scripts]
|
|
47
|
+
ldaca-web-app = "ldaca_web_app.cli:main"
|
|
48
|
+
ldaca_web_app = "ldaca_web_app.cli:main"
|
|
49
|
+
|
|
50
|
+
[tool.pytest.ini_options]
|
|
51
|
+
addopts = ["-ra", "--strict-markers", "--strict-config"]
|
|
52
|
+
pythonpath = ["src"]
|
|
53
|
+
testpaths = ["tests"]
|
|
54
|
+
asyncio_mode = "auto"
|
|
55
|
+
markers = [
|
|
56
|
+
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
|
57
|
+
"integration: marks tests as integration tests",
|
|
58
|
+
"workspace: marks tests related to workspace functionality",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[build-system]
|
|
62
|
+
requires = ["hatchling"]
|
|
63
|
+
build-backend = "hatchling.build"
|
|
64
|
+
|
|
65
|
+
[dependency-groups]
|
|
66
|
+
dev = ["twine>=6.2.0", "pytest-asyncio>=0.23.0"]
|
|
67
|
+
|
|
68
|
+
[tool.hatch.build.targets.sdist]
|
|
69
|
+
include = ["/src", "/src/ldaca_web_app/resources/**"]
|
|
70
|
+
|
|
71
|
+
[tool.hatch.build.targets.wheel]
|
|
72
|
+
packages = ["src/ldaca_web_app"]
|
|
73
|
+
include = ["src/ldaca_web_app/resources/**"]
|
|
74
|
+
|
|
75
|
+
[tool.hatch.build.targets.wheel.sources]
|
|
76
|
+
"src" = ""
|
|
77
|
+
|
|
78
|
+
[tool.uv.sources]
|
|
79
|
+
ldaca-loader = { git = "https://github.com/Australian-Text-Analytics-Platform/ldaca-tabulator", branch = "ldaca_web_app_integration" }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Public package exports for backend app entrypoints.
|
|
2
|
+
|
|
3
|
+
Used by:
|
|
4
|
+
- desktop/runtime launchers and external embedding contexts
|
|
5
|
+
|
|
6
|
+
Why:
|
|
7
|
+
- Provides stable import surface for app object and startup helpers.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .core.workspace import workspace_manager
|
|
11
|
+
from .deploy import start_backend, start_frontend
|
|
12
|
+
from .main import app
|
|
13
|
+
|
|
14
|
+
__all__ = ["app", "workspace_manager", "start_backend", "start_frontend"]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Concordance analysis request/result schema module.
|
|
2
|
+
|
|
3
|
+
Used by:
|
|
4
|
+
- concordance analysis API routes and task persistence payloads
|
|
5
|
+
|
|
6
|
+
Why:
|
|
7
|
+
- Keeps concordance-specific request/result contracts separated from route logic.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
from pydantic import Field
|
|
13
|
+
|
|
14
|
+
from ..models import BaseAnalysisRequest
|
|
15
|
+
from ..results import BaseAnalysisResult
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ConcordanceRequest(BaseAnalysisRequest):
|
|
19
|
+
"""Request payload schema for concordance runs.
|
|
20
|
+
|
|
21
|
+
Used by:
|
|
22
|
+
- concordance route/task creation flows
|
|
23
|
+
|
|
24
|
+
Why:
|
|
25
|
+
- Validates all search/context/pagination-related analysis inputs.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
node_ids: List[str]
|
|
29
|
+
node_columns: Optional[Dict[str, str]] = None
|
|
30
|
+
search_word: str
|
|
31
|
+
num_left_tokens: int = 50
|
|
32
|
+
num_right_tokens: int = 50
|
|
33
|
+
regex: bool = False
|
|
34
|
+
whole_word: bool = False
|
|
35
|
+
case_sensitive: bool = False
|
|
36
|
+
combined: bool = False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ConcordanceResult(BaseAnalysisResult):
|
|
40
|
+
"""Serializable concordance result wrapper.
|
|
41
|
+
|
|
42
|
+
Used by:
|
|
43
|
+
- analysis task result serialization helpers
|
|
44
|
+
|
|
45
|
+
Why:
|
|
46
|
+
- Provides a consistent JSON output shape for concordance payloads.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(self, results: List[Dict[str, Any]], total_hits: int):
|
|
50
|
+
self.results = results
|
|
51
|
+
self.total_hits = total_hits
|
|
52
|
+
|
|
53
|
+
def to_json(self, **kwargs: Any) -> Dict[str, Any]:
|
|
54
|
+
"""Return JSON-serializable concordance payload."""
|
|
55
|
+
return {
|
|
56
|
+
"results": self.results,
|
|
57
|
+
"total_hits": self.total_hits,
|
|
58
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Quotation analysis request/result schema module.
|
|
2
|
+
|
|
3
|
+
Used by:
|
|
4
|
+
- quotation analysis API routes and worker task payload marshalling
|
|
5
|
+
|
|
6
|
+
Why:
|
|
7
|
+
- Encapsulates quotation-specific request/result contracts.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
from ..models import BaseAnalysisRequest
|
|
15
|
+
from ..results import BaseAnalysisResult
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class QuotationEngineConfig(BaseModel):
|
|
19
|
+
"""Configuration schema for quotation extraction engines.
|
|
20
|
+
|
|
21
|
+
Used by:
|
|
22
|
+
- `QuotationRequest`
|
|
23
|
+
|
|
24
|
+
Why:
|
|
25
|
+
- Supports local and remote engine selection with optional model/auth fields.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
type: str = "local" # "local" or "remote"
|
|
29
|
+
model: Optional[str] = None
|
|
30
|
+
url: Optional[str] = None
|
|
31
|
+
api_key: Optional[str] = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class QuotationRequest(BaseAnalysisRequest):
|
|
35
|
+
"""Request payload schema for quotation analysis.
|
|
36
|
+
|
|
37
|
+
Used by:
|
|
38
|
+
- quotation run/update endpoints
|
|
39
|
+
|
|
40
|
+
Why:
|
|
41
|
+
- Validates node/column/engine/paging options for quotation workflows.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
node_id: str
|
|
45
|
+
column: str
|
|
46
|
+
engine: Optional[QuotationEngineConfig] = None
|
|
47
|
+
page: Optional[int] = 1
|
|
48
|
+
page_size: Optional[int] = 50
|
|
49
|
+
sort_by: Optional[str] = None
|
|
50
|
+
descending: Optional[bool] = True
|
|
51
|
+
context_length: Optional[int] = None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class QuotationResult(BaseAnalysisResult):
|
|
55
|
+
"""Serializable quotation result wrapper.
|
|
56
|
+
|
|
57
|
+
Used by:
|
|
58
|
+
- analysis task result persistence/rehydration paths
|
|
59
|
+
|
|
60
|
+
Why:
|
|
61
|
+
- Preserves arbitrary quotation payloads behind unified result interface.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, data: Dict[str, Any]):
|
|
65
|
+
self.data = data
|
|
66
|
+
|
|
67
|
+
def to_json(self, **kwargs: Any) -> Dict[str, Any]:
|
|
68
|
+
"""Return JSON-serializable quotation payload."""
|
|
69
|
+
return self.data
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Sequential analysis request schema module.
|
|
2
|
+
|
|
3
|
+
Used by:
|
|
4
|
+
- sequential analysis routes and task persistence models
|
|
5
|
+
|
|
6
|
+
Why:
|
|
7
|
+
- Keeps sequential-analysis specific request fields versioned in one place.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import List, Optional
|
|
11
|
+
|
|
12
|
+
from pydantic import Field
|
|
13
|
+
|
|
14
|
+
from ..models import BaseAnalysisRequest
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SequentialAnalysisRequest(BaseAnalysisRequest):
|
|
18
|
+
"""
|
|
19
|
+
Request model for sequential analysis.
|
|
20
|
+
|
|
21
|
+
Used by:
|
|
22
|
+
- sequential analysis run/update endpoints
|
|
23
|
+
|
|
24
|
+
Why:
|
|
25
|
+
- Validates temporal grouping and binning parameters.
|
|
26
|
+
|
|
27
|
+
Refactor note:
|
|
28
|
+
- `column_type`, `numeric_origin`, and `numeric_interval` are declared twice;
|
|
29
|
+
remove duplicated declarations to reduce schema ambiguity.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
node_id: Optional[str] = Field(None, description="Node ID to analyze")
|
|
33
|
+
time_column: str = Field(..., description="Column containing time/numeric data")
|
|
34
|
+
group_by_columns: Optional[List[str]] = Field(
|
|
35
|
+
None, description="Columns to group by"
|
|
36
|
+
)
|
|
37
|
+
frequency: str = Field(
|
|
38
|
+
"monthly", description="Frequency (daily, weekly, monthly, yearly)"
|
|
39
|
+
)
|
|
40
|
+
sort_by_time: bool = Field(True, description="Whether to sort by time")
|
|
41
|
+
column_type: str = Field(
|
|
42
|
+
"datetime", description="Column type (datetime or numeric)"
|
|
43
|
+
)
|
|
44
|
+
numeric_origin: Optional[float] = Field(
|
|
45
|
+
None, description="Origin for numeric binning"
|
|
46
|
+
)
|
|
47
|
+
numeric_interval: Optional[float] = Field(
|
|
48
|
+
None, description="Interval for numeric binning"
|
|
49
|
+
)
|
|
50
|
+
column_type: str = Field(
|
|
51
|
+
"datetime", description="Column type (datetime or numeric)"
|
|
52
|
+
)
|
|
53
|
+
numeric_origin: Optional[float] = Field(
|
|
54
|
+
None, description="Origin for numeric binning"
|
|
55
|
+
)
|
|
56
|
+
numeric_interval: Optional[float] = Field(
|
|
57
|
+
None, description="Interval for numeric binning"
|
|
58
|
+
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Token-frequency analysis request schema module.
|
|
2
|
+
|
|
3
|
+
Used by:
|
|
4
|
+
- token-frequency routes and worker task request validation
|
|
5
|
+
|
|
6
|
+
Why:
|
|
7
|
+
- Keeps token-frequency analysis input contract centralized.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
from pydantic import Field
|
|
13
|
+
|
|
14
|
+
from ..models import BaseAnalysisRequest
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TokenFrequencyRequest(BaseAnalysisRequest):
|
|
18
|
+
"""
|
|
19
|
+
Request model for token-frequency analysis.
|
|
20
|
+
|
|
21
|
+
Used by:
|
|
22
|
+
- token-frequency run/update endpoints
|
|
23
|
+
|
|
24
|
+
Why:
|
|
25
|
+
- Validates node selection, stop-word, and token-limit parameters.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
node_ids: List[str] = Field(..., description="List of node IDs to analyze (1 or 2)")
|
|
29
|
+
node_columns: Optional[Dict[str, str]] = Field(
|
|
30
|
+
None, description="Map of node_id to column name"
|
|
31
|
+
)
|
|
32
|
+
stop_words: Optional[List[str]] = Field(
|
|
33
|
+
None, description="List of stop words to exclude"
|
|
34
|
+
)
|
|
35
|
+
token_limit: Optional[int] = Field(
|
|
36
|
+
None, description="Limit on number of tokens returned"
|
|
37
|
+
)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Topic-modeling analysis request schema module.
|
|
2
|
+
|
|
3
|
+
Used by:
|
|
4
|
+
- topic-modeling routes and worker task request validation
|
|
5
|
+
|
|
6
|
+
Why:
|
|
7
|
+
- Keeps topic-modeling specific input contract centralized.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from pydantic import Field
|
|
11
|
+
|
|
12
|
+
from ..models import BaseAnalysisRequest
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TopicModelingRequest(BaseAnalysisRequest):
|
|
16
|
+
"""
|
|
17
|
+
Request model for topic-modeling analysis.
|
|
18
|
+
|
|
19
|
+
Used by:
|
|
20
|
+
- topic-modeling run/update endpoints
|
|
21
|
+
|
|
22
|
+
Why:
|
|
23
|
+
- Validates node selection and clustering configuration inputs.
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
node_ids: list[str] = Field(..., description="List of node IDs to analyze")
|
|
28
|
+
node_columns: dict[str, str] | None = Field(
|
|
29
|
+
None, description="Map of node_id to column name"
|
|
30
|
+
)
|
|
31
|
+
min_topic_size: int = Field(
|
|
32
|
+
5, description="DBSCAN min_points (minimum cluster size)"
|
|
33
|
+
)
|
|
34
|
+
random_seed: int = Field(
|
|
35
|
+
42, description="Random seed used for reproducible topic-modeling runs"
|
|
36
|
+
)
|
|
37
|
+
representative_words_count: int = Field(
|
|
38
|
+
5, description="Number of representative words to keep per topic"
|
|
39
|
+
)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""Analysis storage manager.
|
|
2
|
+
|
|
3
|
+
Provides per-user in-memory storage for analysis task records. Each
|
|
4
|
+
``AnalysisTask`` tracks the ``workspace_id`` it was created for, so
|
|
5
|
+
tasks can be bulk-cleared when a workspace is unloaded.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
|
+
from uuid import uuid4
|
|
13
|
+
|
|
14
|
+
from .models import AnalysisStatus, AnalysisTask, BaseAnalysisRequest
|
|
15
|
+
|
|
16
|
+
# In-memory storage: user_id -> TaskManagerStore
|
|
17
|
+
_TASK_MANAGER_STORE: Dict[str, TaskManagerStore] = {}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TaskManagerStore:
|
|
21
|
+
"""Per-user in-memory storage for analysis task records."""
|
|
22
|
+
|
|
23
|
+
def __init__(self) -> None:
|
|
24
|
+
self.tasks: Dict[str, AnalysisTask] = {}
|
|
25
|
+
self.current_task_ids: Dict[str, str] = {}
|
|
26
|
+
|
|
27
|
+
def get_task(self, task_id: str) -> Optional[AnalysisTask]:
|
|
28
|
+
return self.tasks.get(task_id)
|
|
29
|
+
|
|
30
|
+
def save_task(self, task: AnalysisTask) -> None:
|
|
31
|
+
self.tasks[task.task_id] = task
|
|
32
|
+
|
|
33
|
+
def get_all_tasks(self) -> List[AnalysisTask]:
|
|
34
|
+
return list(self.tasks.values())
|
|
35
|
+
|
|
36
|
+
def set_current_task(self, tab: str, task_id: str) -> None:
|
|
37
|
+
self.current_task_ids[tab] = task_id
|
|
38
|
+
|
|
39
|
+
def get_current_task_ids(self, tab: str) -> List[str]:
|
|
40
|
+
task_id = self.current_task_ids.get(tab)
|
|
41
|
+
return [task_id] if task_id else []
|
|
42
|
+
|
|
43
|
+
def clear_task(self, task_id: str) -> None:
|
|
44
|
+
if task_id in self.tasks:
|
|
45
|
+
del self.tasks[task_id]
|
|
46
|
+
for tab, current_id in list(self.current_task_ids.items()):
|
|
47
|
+
if current_id == task_id:
|
|
48
|
+
del self.current_task_ids[tab]
|
|
49
|
+
|
|
50
|
+
def clear_all(self) -> List[str]:
|
|
51
|
+
ids = list(self.tasks.keys())
|
|
52
|
+
self.tasks.clear()
|
|
53
|
+
self.current_task_ids.clear()
|
|
54
|
+
return ids
|
|
55
|
+
|
|
56
|
+
def clear_workspace(self, workspace_id: str) -> List[str]:
|
|
57
|
+
"""Remove all tasks belonging to *workspace_id* and return their IDs."""
|
|
58
|
+
to_remove = [
|
|
59
|
+
tid for tid, task in self.tasks.items() if task.workspace_id == workspace_id
|
|
60
|
+
]
|
|
61
|
+
for tid in to_remove:
|
|
62
|
+
self.clear_task(tid)
|
|
63
|
+
return to_remove
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class TaskManager:
|
|
67
|
+
"""Per-user task storage keyed by task_id with per-tab current mapping."""
|
|
68
|
+
|
|
69
|
+
def __init__(self, user_id: str) -> None:
|
|
70
|
+
self.user_id = user_id
|
|
71
|
+
if user_id not in _TASK_MANAGER_STORE:
|
|
72
|
+
_TASK_MANAGER_STORE[user_id] = TaskManagerStore()
|
|
73
|
+
self.store = _TASK_MANAGER_STORE[user_id]
|
|
74
|
+
|
|
75
|
+
def create_task(
|
|
76
|
+
self,
|
|
77
|
+
request: BaseAnalysisRequest | dict[str, Any],
|
|
78
|
+
) -> str:
|
|
79
|
+
"""Create and store a new pending analysis task.
|
|
80
|
+
|
|
81
|
+
The current workspace is resolved automatically from
|
|
82
|
+
``workspace_manager`` so callers don't need to pass it.
|
|
83
|
+
"""
|
|
84
|
+
from ..core.workspace import workspace_manager
|
|
85
|
+
|
|
86
|
+
workspace_id = workspace_manager.get_current_workspace_id(self.user_id) or ""
|
|
87
|
+
task_id = str(uuid4())
|
|
88
|
+
normalized_request = self._normalize_request(request)
|
|
89
|
+
task = AnalysisTask(
|
|
90
|
+
task_id=task_id,
|
|
91
|
+
user_id=self.user_id,
|
|
92
|
+
workspace_id=workspace_id,
|
|
93
|
+
request=normalized_request,
|
|
94
|
+
status=AnalysisStatus.PENDING,
|
|
95
|
+
)
|
|
96
|
+
self.store.save_task(task)
|
|
97
|
+
return task_id
|
|
98
|
+
|
|
99
|
+
def get_task(self, task_id: str) -> Optional[AnalysisTask]:
|
|
100
|
+
return self.store.get_task(task_id)
|
|
101
|
+
|
|
102
|
+
def save_task(self, task: AnalysisTask) -> None:
|
|
103
|
+
self.store.save_task(task)
|
|
104
|
+
|
|
105
|
+
def set_current_task(self, tab: str, task_id: str) -> None:
|
|
106
|
+
self.store.set_current_task(tab, task_id)
|
|
107
|
+
|
|
108
|
+
def get_current_task_ids(self, tab: str) -> List[str]:
|
|
109
|
+
return self.store.get_current_task_ids(tab)
|
|
110
|
+
|
|
111
|
+
def update_task(self, task_id: str, result: Any) -> None:
|
|
112
|
+
task = self.store.get_task(task_id)
|
|
113
|
+
if task is None:
|
|
114
|
+
return
|
|
115
|
+
task.result = result
|
|
116
|
+
task.status = AnalysisStatus.COMPLETED
|
|
117
|
+
task.updated_at = datetime.now()
|
|
118
|
+
self.store.save_task(task)
|
|
119
|
+
|
|
120
|
+
def clear_task(self, task_id: str) -> None:
|
|
121
|
+
self.store.clear_task(task_id)
|
|
122
|
+
|
|
123
|
+
def clear_all(self) -> List[str]:
|
|
124
|
+
return self.store.clear_all()
|
|
125
|
+
|
|
126
|
+
def clear_workspace(self, workspace_id: str) -> List[str]:
|
|
127
|
+
"""Clear all tasks belonging to *workspace_id*."""
|
|
128
|
+
return self.store.clear_workspace(workspace_id)
|
|
129
|
+
|
|
130
|
+
def get_all_tasks(self) -> List[AnalysisTask]:
|
|
131
|
+
return self.store.get_all_tasks()
|
|
132
|
+
|
|
133
|
+
def _normalize_request(
|
|
134
|
+
self, request: BaseAnalysisRequest | dict[str, Any]
|
|
135
|
+
) -> BaseAnalysisRequest:
|
|
136
|
+
if isinstance(request, BaseAnalysisRequest):
|
|
137
|
+
return request
|
|
138
|
+
return BaseAnalysisRequest.model_validate(request)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def get_task_manager(user_id: str) -> TaskManager:
|
|
142
|
+
"""Return the analysis task manager for a user.
|
|
143
|
+
|
|
144
|
+
A single user can only have one workspace loaded at a time, so the
|
|
145
|
+
manager is keyed by *user_id* only. Individual tasks track their
|
|
146
|
+
``workspace_id`` internally.
|
|
147
|
+
"""
|
|
148
|
+
return TaskManager(user_id)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Analysis data models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Any, Dict, Generic, Optional, TypeVar
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
10
|
+
|
|
11
|
+
from .results import BaseAnalysisResult
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AnalysisStatus(str, Enum):
|
|
15
|
+
"""Lifecycle states for analysis tasks.
|
|
16
|
+
|
|
17
|
+
Used by:
|
|
18
|
+
- `AnalysisTask`
|
|
19
|
+
- analysis/task APIs and worker sync helpers
|
|
20
|
+
|
|
21
|
+
Why:
|
|
22
|
+
- Keeps task status values consistent across storage and API responses.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
PENDING = "pending"
|
|
26
|
+
RUNNING = "running"
|
|
27
|
+
COMPLETED = "completed"
|
|
28
|
+
FAILED = "failed"
|
|
29
|
+
CANCELLED = "cancelled"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class BaseAnalysisRequest(BaseModel):
|
|
33
|
+
"""Base request model for all analyses."""
|
|
34
|
+
|
|
35
|
+
model_config = ConfigDict(extra="allow")
|
|
36
|
+
# Additional common fields can go here
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
TRequest = TypeVar("TRequest", bound=BaseAnalysisRequest)
|
|
40
|
+
TResult = TypeVar("TResult", bound=BaseAnalysisResult)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class AnalysisTask(BaseModel, Generic[TRequest, TResult]):
|
|
44
|
+
"""Container for a single analysis task."""
|
|
45
|
+
|
|
46
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
47
|
+
|
|
48
|
+
task_id: str
|
|
49
|
+
user_id: str
|
|
50
|
+
workspace_id: str
|
|
51
|
+
status: AnalysisStatus = AnalysisStatus.PENDING
|
|
52
|
+
created_at: datetime = Field(default_factory=datetime.now)
|
|
53
|
+
updated_at: datetime = Field(default_factory=datetime.now)
|
|
54
|
+
request: TRequest
|
|
55
|
+
result: Optional[TResult] = None
|
|
56
|
+
error: Optional[str] = None
|
|
57
|
+
|
|
58
|
+
def complete(self, result: TResult) -> None:
|
|
59
|
+
"""Mark task completed and attach result payload.
|
|
60
|
+
|
|
61
|
+
Used by:
|
|
62
|
+
- `analysis.manager.TaskManager.update_task`
|
|
63
|
+
- worker sync paths that finalize memory tasks
|
|
64
|
+
|
|
65
|
+
Why:
|
|
66
|
+
- Provides one canonical status transition to `COMPLETED`.
|
|
67
|
+
"""
|
|
68
|
+
self.result = result
|
|
69
|
+
self.status = AnalysisStatus.COMPLETED
|
|
70
|
+
self.updated_at = datetime.now()
|
|
71
|
+
|
|
72
|
+
def fail(self, error: str) -> None:
|
|
73
|
+
"""Mark task failed with error details.
|
|
74
|
+
|
|
75
|
+
Used by:
|
|
76
|
+
- worker sync and error propagation paths
|
|
77
|
+
|
|
78
|
+
Why:
|
|
79
|
+
- Standardizes failure transition metadata for UI/task APIs.
|
|
80
|
+
"""
|
|
81
|
+
self.error = error
|
|
82
|
+
self.status = AnalysisStatus.FAILED
|
|
83
|
+
self.updated_at = datetime.now()
|