aird 0.4.25.dev1__tar.gz → 0.4.25.dev3__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.
Files changed (256) hide show
  1. aird-0.4.25.dev3/PKG-INFO +315 -0
  2. aird-0.4.25.dev3/README.md +277 -0
  3. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/cli/transfer_http.py +2 -2
  4. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/constants/__init__.py +69 -16
  5. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/compression.py +38 -26
  6. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/events.py +6 -2
  7. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/rate_limit.py +21 -19
  8. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/secret_storage.py +26 -23
  9. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/__init__.py +1 -0
  10. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/config.py +1 -1
  11. aird-0.4.25.dev3/aird/db/sync.py +102 -0
  12. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/event_loop.py +8 -1
  13. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/admin_handlers.py +29 -1
  14. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/auth_handlers.py +35 -26
  15. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/base_handler.py +11 -0
  16. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/file_op_handlers.py +2 -0
  17. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/health_handler.py +19 -0
  18. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/p2p_handlers.py +68 -42
  19. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/ranged_upload_handlers.py +74 -19
  20. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/share_handlers.py +21 -18
  21. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/transfer_ws_handlers.py +17 -1
  22. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/view_handlers.py +4 -0
  23. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/main.py +57 -15
  24. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/config_service.py +13 -8
  25. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/event_subscribers.py +10 -4
  26. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/css/app.css +1 -1
  27. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/browse/app.js +23 -1
  28. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/file-transfer-http.js +282 -93
  29. aird-0.4.25.dev3/aird/static/js/file-transfer-ws.js +410 -0
  30. aird-0.4.25.dev3/aird/static/js/sw-transfer.js +25 -0
  31. aird-0.4.25.dev3/aird/static/js/transfer-engine/compress-worker.js +61 -0
  32. aird-0.4.25.dev3/aird/static/js/transfer-engine/engine.js +245 -0
  33. aird-0.4.25.dev3/aird/static/js/transfer-engine/hasher.js +23 -0
  34. aird-0.4.25.dev3/aird/static/js/transfer-engine/resume-store.js +79 -0
  35. aird-0.4.25.dev3/aird/static/js/transfer-engine/worker-lib.js +393 -0
  36. aird-0.4.25.dev3/aird/static/js/transfer-engine/worker.js +25 -0
  37. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/transfer-tracker.js +158 -39
  38. aird-0.4.25.dev3/aird/static/js/vendor/fflate.js +1190 -0
  39. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin.html +26 -2
  40. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/browse.html +5 -0
  41. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/super_search.html +1 -4
  42. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/utils/util.py +17 -16
  43. aird-0.4.25.dev3/aird.egg-info/PKG-INFO +315 -0
  44. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird.egg-info/SOURCES.txt +11 -0
  45. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird.egg-info/requires.txt +0 -1
  46. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/setup.py +2 -2
  47. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_compression.py +2 -4
  48. aird-0.4.25.dev3/tests/test_free_threading.py +80 -0
  49. aird-0.4.25.dev3/tests/test_ranged_upload_handlers.py +41 -0
  50. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_security_comprehensive.py +2 -0
  51. aird-0.4.25.dev1/PKG-INFO +0 -427
  52. aird-0.4.25.dev1/README.md +0 -388
  53. aird-0.4.25.dev1/aird/static/js/file-transfer-ws.js +0 -349
  54. aird-0.4.25.dev1/aird.egg-info/PKG-INFO +0 -427
  55. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/LICENSE +0 -0
  56. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/MANIFEST.in +0 -0
  57. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/__init__.py +0 -0
  58. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/__main__.py +0 -0
  59. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/app_context.py +0 -0
  60. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/cli/__init__.py +0 -0
  61. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/cli/__main__.py +0 -0
  62. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/cli/authelia.py +0 -0
  63. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/cli/config.py +0 -0
  64. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/cli/main.py +0 -0
  65. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/cli/session.py +0 -0
  66. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/cloud/__init__.py +0 -0
  67. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/config.py +0 -0
  68. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/constants/admin.py +0 -0
  69. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/constants/file_ops.py +0 -0
  70. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/constants/input_limits.py +0 -0
  71. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/constants/media.py +0 -0
  72. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/__init__.py +0 -0
  73. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/file_operations.py +0 -0
  74. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/file_send.py +0 -0
  75. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/filter_expression.py +0 -0
  76. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/folder_size.py +0 -0
  77. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/http_range.py +0 -0
  78. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/input_validation.py +0 -0
  79. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/mmap_handler.py +0 -0
  80. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/security.py +0 -0
  81. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/share_root.py +0 -0
  82. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/webauthn_config.py +0 -0
  83. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/websocket_manager.py +0 -0
  84. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/core/zip_download.py +0 -0
  85. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/database/__init__.py +0 -0
  86. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/database/db.py +0 -0
  87. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/database/feature_flags.py +0 -0
  88. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/database/ldap.py +0 -0
  89. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/audit.py +0 -0
  90. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/favorites.py +0 -0
  91. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/network_shares.py +0 -0
  92. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/policies.py +0 -0
  93. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/policy_decisions.py +0 -0
  94. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/policy_seeds.py +0 -0
  95. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/quota.py +0 -0
  96. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/ranged_uploads.py +0 -0
  97. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/resource_tags.py +0 -0
  98. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/schema.py +0 -0
  99. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/shares.py +0 -0
  100. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/user_attributes.py +0 -0
  101. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/users.py +0 -0
  102. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/db/webauthn.py +0 -0
  103. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/domain/__init__.py +0 -0
  104. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/domain/contracts.py +0 -0
  105. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/domain/models.py +0 -0
  106. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/email/__init__.py +0 -0
  107. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/email/brevo.py +0 -0
  108. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/email/resolve.py +0 -0
  109. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/__init__.py +0 -0
  110. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/abac_handlers.py +0 -0
  111. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/api_handlers.py +0 -0
  112. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/constants.py +0 -0
  113. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/handlers/webauthn_handlers.py +0 -0
  114. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/network_share_manager.py +0 -0
  115. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/server_runtime.py +0 -0
  116. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/__init__.py +0 -0
  117. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/audit_service.py +0 -0
  118. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/email_service.py +0 -0
  119. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/email_subscriber.py +0 -0
  120. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/favorites_service.py +0 -0
  121. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/network_share_service.py +0 -0
  122. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/p2p_service.py +0 -0
  123. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/policy_service.py +0 -0
  124. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/quota_service.py +0 -0
  125. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/share_service.py +0 -0
  126. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/tag_service.py +0 -0
  127. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/services/user_service.py +0 -0
  128. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/sql_identifiers.py +0 -0
  129. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/favicon.png +0 -0
  130. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/favicon.svg +0 -0
  131. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/img/logo-icon.png +0 -0
  132. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/img/logo-mark.svg +0 -0
  133. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/img/logo-text.png +0 -0
  134. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/img/logo.png +0 -0
  135. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/aird-core.js +0 -0
  136. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/bg-canvas.js +0 -0
  137. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/common/command-palette.js +0 -0
  138. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/components/folder-picker.js +0 -0
  139. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/download-manager.js +0 -0
  140. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/feature-flags-live.js +0 -0
  141. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/folder-size-scan.js +0 -0
  142. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/login-ui.js +0 -0
  143. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/media-view.js +0 -0
  144. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/p2p/app.js +0 -0
  145. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/p2p/mediator.js +0 -0
  146. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/p2p/qr-adapter.js +0 -0
  147. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/p2p/signaling-service.js +0 -0
  148. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/p2p/state-machine.js +0 -0
  149. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/p2p/transfer-service.js +0 -0
  150. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/pages/p2p-page.js +0 -0
  151. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/pages/super-search.js +0 -0
  152. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/app.js +0 -0
  153. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/add-files-modal.js +0 -0
  154. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/cloud.js +0 -0
  155. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/create-share.js +0 -0
  156. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/create-users.js +0 -0
  157. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/expiry.js +0 -0
  158. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/file-icons.js +0 -0
  159. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/file-picker.js +0 -0
  160. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/init.js +0 -0
  161. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/main.js +0 -0
  162. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/management-templates.js +0 -0
  163. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/management.js +0 -0
  164. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/selection.js +0 -0
  165. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/share-popup.js +0 -0
  166. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/shares-list.js +0 -0
  167. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/state.js +0 -0
  168. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/share/src/utils.js +0 -0
  169. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/theme.js +0 -0
  170. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/vendor/pdf.min.js +0 -0
  171. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/vendor/pdf.worker.min.js +0 -0
  172. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/vendor/qrcode-browser.js +0 -0
  173. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/static/js/webauthn.js +0 -0
  174. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/_admin_tabs.html +0 -0
  175. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/_app_nav_header.html +0 -0
  176. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/_bg_canvas.html +0 -0
  177. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/_theme_early.html +0 -0
  178. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/_theme_login_corner.html +0 -0
  179. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin_audit.html +0 -0
  180. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin_ldap.html +0 -0
  181. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin_login.html +0 -0
  182. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin_network_shares.html +0 -0
  183. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin_policies.html +0 -0
  184. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin_tags.html +0 -0
  185. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin_user_attributes.html +0 -0
  186. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/admin_users.html +0 -0
  187. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/directory.html +0 -0
  188. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/edit.html +0 -0
  189. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/error.html +0 -0
  190. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/file.html +0 -0
  191. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/ldap_config_create.html +0 -0
  192. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/ldap_config_edit.html +0 -0
  193. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/login.html +0 -0
  194. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/media_view.html +0 -0
  195. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/p2p_transfer.html +0 -0
  196. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/profile.html +0 -0
  197. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/share.html +0 -0
  198. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/shared_list.html +0 -0
  199. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/tagged_files.html +0 -0
  200. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/token_verification.html +0 -0
  201. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/user_create.html +0 -0
  202. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/templates/user_edit.html +0 -0
  203. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird/utils/__init__.py +0 -0
  204. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird.egg-info/dependency_links.txt +0 -0
  205. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird.egg-info/entry_points.txt +0 -0
  206. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/aird.egg-info/top_level.txt +0 -0
  207. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/setup.cfg +0 -0
  208. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/__init__.py +0 -0
  209. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/conftest.py +0 -0
  210. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/handler_helpers.py +0 -0
  211. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_admin_handlers.py +0 -0
  212. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_api_handlers.py +0 -0
  213. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_architecture_conformance.py +0 -0
  214. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_auth_handlers.py +0 -0
  215. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_auth_handlers_extended.py +0 -0
  216. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_base_handler.py +0 -0
  217. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_base_handler_pep.py +0 -0
  218. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_cli.py +0 -0
  219. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_cloud.py +0 -0
  220. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_config.py +0 -0
  221. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_core_file_operations.py +0 -0
  222. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_database_db.py +0 -0
  223. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_database_feature_flags.py +0 -0
  224. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_database_ldap.py +0 -0
  225. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_database_shares.py +0 -0
  226. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_database_users.py +0 -0
  227. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_database_users_hashing.py +0 -0
  228. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_db.py +0 -0
  229. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_email_service.py +0 -0
  230. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_file_op_handlers.py +0 -0
  231. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_filter_expression.py +0 -0
  232. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_folder_size.py +0 -0
  233. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_http_range.py +0 -0
  234. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_main.py +0 -0
  235. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_mmap_handler.py +0 -0
  236. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_multi_user.py +0 -0
  237. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_network_shares.py +0 -0
  238. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_p2p_handlers.py +0 -0
  239. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_password_hashing.py +0 -0
  240. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_policy_service.py +0 -0
  241. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_rate_limit.py +0 -0
  242. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_secret_storage.py +0 -0
  243. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_security.py +0 -0
  244. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_server_runtime.py +0 -0
  245. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_share_handlers.py +0 -0
  246. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_share_ownership.py +0 -0
  247. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_super_search_handler.py +0 -0
  248. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_tag_service.py +0 -0
  249. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_transfer_rate_limit.py +0 -0
  250. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_transfer_ws_handlers.py +0 -0
  251. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_util.py +0 -0
  252. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_view_handlers.py +0 -0
  253. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_webauthn_handlers.py +0 -0
  254. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_websocket_manager.py +0 -0
  255. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_wheel_static_assets.py +0 -0
  256. {aird-0.4.25.dev1 → aird-0.4.25.dev3}/tests/test_zip_download.py +0 -0
@@ -0,0 +1,315 @@
1
+ Metadata-Version: 2.4
2
+ Name: aird
3
+ Version: 0.4.25.dev3
4
+ Summary: Aird - A lightweight web-based file browser, editor, and streamer with real-time capabilities
5
+ Home-page: https://github.com/blinkerbit/aird
6
+ Author: Viswantha Srinivas P
7
+ Author-email: psviswanatha@gmail.com
8
+ License: Custom
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: Other/Proprietary License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: tornado>=6.5.1
16
+ Requires-Dist: uvloop>=0.19.0; sys_platform == "linux"
17
+ Requires-Dist: ldap3>=2.9.1
18
+ Requires-Dist: aiofiles>=23.0.0
19
+ Requires-Dist: argon2-cffi>=23.1.0
20
+ Requires-Dist: requests>=2.31.0
21
+ Requires-Dist: chardet<6.0.0,>=5.0.0
22
+ Requires-Dist: pyasn1>=0.6.2
23
+ Requires-Dist: webauthn>=2.0.0
24
+ Provides-Extra: compress
25
+ Requires-Dist: zstandard>=0.22.0; extra == "compress"
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: license
33
+ Dynamic: license-file
34
+ Dynamic: provides-extra
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
38
+
39
+ # Aird
40
+
41
+ <p align="center">
42
+ <img src="aird/static/img/logo.png" alt="Aird" width="280">
43
+ </p>
44
+
45
+ ![Aird demo](./demo.webp)
46
+
47
+ **Aird** is a self-hosted file browser, editor, and sharing platform built on **Python** and **Tornado**. It targets fast local and LAN use: parallel HTTP transfers for large files, real-time log streaming, content search, secure shares, optional multi-user isolation, and an admin console that applies settings without restarts.
48
+
49
+ ---
50
+
51
+ ## Highlights
52
+
53
+ | Area | What you get |
54
+ |------|----------------|
55
+ | **File manager** | Browse, upload, download, rename, move, copy, bulk ops, in-browser text edit, ZIP download |
56
+ | **Large transfers** | Parallel **HTTP `Content-Range`** uploads/downloads (primary path for big files) |
57
+ | **Search** | **Super Search** — glob + regex content search with live WebSocket progress |
58
+ | **Streaming** | Tail log files over WebSocket with filters |
59
+ | **Sharing** | Token-based public/private shares, static or live folder views |
60
+ | **Security** | CSRF, CSP, path traversal checks, optional **ABAC** policies, WebAuthn, LDAP |
61
+ | **Integrations** | Google Drive / OneDrive browse, P2P WebRTC rooms, optional embedded SMB & WebDAV |
62
+ | **Ops** | SQLite-backed settings, audit log, feature flags, transfer rate limits, health endpoint |
63
+
64
+ ---
65
+
66
+ ## File transfers
67
+
68
+ Large uploads are designed for **high-throughput links** (e.g. gigabit LAN or VPN):
69
+
70
+ 1. **Small files** — single `POST /upload`.
71
+ 2. **Large files** — client opens a range session (`POST /api/upload/range/session`), then sends many parallel **`PUT`** requests with `Content-Range`. Each chunk is written **in place** at the correct byte offset on disk (no separate part files, no concat step at the end).
72
+ 3. **Downloads** — `GET /files/...?download=1` with optional `Range` for parallel fetch.
73
+
74
+ Defaults (all adjustable in **Admin → Upload settings**):
75
+
76
+ | Setting | Default | Notes |
77
+ |---------|---------|--------|
78
+ | Max file size | 10 240 MB (10 GiB) | Hard cap per file |
79
+ | Single-request max | 100 MB | Files **≥** this use parallel HTTP ranges |
80
+ | HTTP chunk size | 90 MB | Per range `PUT` body |
81
+ | HTTP parallelism | 16 | Concurrent upload streams |
82
+
83
+ **Behind nginx/Caddy:** set `client_max_body_size` (or equivalent) to at least your HTTP chunk size. If **Single-request max** is `0`, Aird uses a **100 MB** parallel threshold (proxy-safe), not a single POST for the entire max file size.
84
+
85
+ Optional WebSocket upload (`/ws/file-transfer`) remains for specialized paths; the browser UI uses **HTTP parallel** by default.
86
+
87
+ Transfer progress, cancel, and resume metadata are handled in the browser (`transfer-tracker.js`, `transfer-engine/`, service worker `sw-transfer.js`).
88
+
89
+ ---
90
+
91
+ ## Quick start
92
+
93
+ ### Install
94
+
95
+ ```bash
96
+ pip install aird
97
+
98
+ # Optional: HTTP response compression codecs (gzip is always available)
99
+ pip install "aird[compress]"
100
+
101
+ # From source
102
+ git clone https://github.com/blinkerbit/aird.git
103
+ cd aird
104
+ pip install -e .
105
+ ```
106
+
107
+ **Python:** 3.10+ required. On Linux, **free-threaded** builds (`3.13t` / `3.14t`) are supported and recommended for parallel disk I/O; the server detects nogil at startup and sizes the I/O thread pool accordingly.
108
+
109
+ ### Run
110
+
111
+ ```bash
112
+ # Default: port 8000, current directory as root
113
+ python -m aird
114
+
115
+ # Custom root and port
116
+ python -m aird --root /data --port 8080
117
+
118
+ # Multi-user (per-user home directories under root)
119
+ python -m aird --root /data --multi-user
120
+
121
+ # TLS
122
+ python -m aird --ssl-cert /path/cert.pem --ssl-key /path/key.pem --port 443
123
+
124
+ # Worker processes (Linux; default is auto from CPU topology)
125
+ python -m aird --workers 4
126
+ ```
127
+
128
+ On first start, random **access** and **admin** tokens are printed unless you set them via `--token`, `--admin-token`, `config.json`, or `AIRD_ACCESS_TOKEN`.
129
+
130
+ Open `http://localhost:8000/` → redirects to `/files/`.
131
+
132
+ ### CLI client
133
+
134
+ ```bash
135
+ pip install aird # includes aird-cli
136
+ aird-cli config set server https://your-host
137
+ aird-cli login
138
+ aird-cli ls /
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Configuration
144
+
145
+ ### `config.json`
146
+
147
+ ```json
148
+ {
149
+ "port": 8000,
150
+ "root": "/srv/files",
151
+ "hostname": "files.example.com",
152
+ "token": "your-access-token",
153
+ "admin_token": "your-admin-token",
154
+ "multi_user": false,
155
+ "workers": 2,
156
+ "ldap": {
157
+ "enabled": false,
158
+ "server": "ldap://ldap.example.com",
159
+ "base_dn": "dc=example,dc=com"
160
+ },
161
+ "feature_flags": {
162
+ "file_upload": true,
163
+ "super_search": true,
164
+ "abac_engine": false
165
+ }
166
+ }
167
+ ```
168
+
169
+ ```bash
170
+ python -m aird --config /etc/aird/config.json
171
+ ```
172
+
173
+ ### Environment variables (common)
174
+
175
+ | Variable | Purpose |
176
+ |----------|---------|
177
+ | `AIRD_ACCESS_TOKEN` | Login token |
178
+ | `AIRD_COOKIE_SECRET` | Persistent session signing (set in production) |
179
+ | `AIRD_CORPORATE_IP_CIDRS` | Comma-separated CIDRs for ABAC / WAN compression rules |
180
+ | `AIRD_GDRIVE_ACCESS_TOKEN` / `AIRD_ONEDRIVE_ACCESS_TOKEN` | Cloud providers |
181
+
182
+ ### Admin console
183
+
184
+ `GET /admin` — feature flags, upload limits, extension allow-list, WebSocket pool limits, LDAP, network shares, ABAC policies/tags, users, audit. Changes persist to SQLite and apply without restart (feature-flag subscribers refresh over `/features` WebSocket).
185
+
186
+ ---
187
+
188
+ ## Production deployment
189
+
190
+ ### Reverse proxy
191
+
192
+ Aird listens on one port (default **8000**). Terminate TLS at **Caddy**, **nginx**, or similar.
193
+
194
+ **nginx example** (adjust chunk size to match Admin → HTTP chunk):
195
+
196
+ ```nginx
197
+ client_max_body_size 128m;
198
+
199
+ location / {
200
+ proxy_pass http://127.0.0.1:8000;
201
+ proxy_http_version 1.1;
202
+ proxy_set_header Host $host;
203
+ proxy_set_header X-Real-IP $remote_addr;
204
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
205
+ proxy_set_header X-Forwarded-Proto $scheme;
206
+ }
207
+ ```
208
+
209
+ WebSocket routes (`/stream/`, `/search/ws`, `/features`, `/ws/…`) need `Upgrade` and `Connection` headers if you proxy them.
210
+
211
+ ### Ubuntu deploy script
212
+
213
+ `deploy_local.ps1` (run from Windows) syncs source or a wheel to a remote host, creates a **uv** venv with **Python 3.14t**, and installs the package. See `docs/wireguard-deploy.md` for VPN-only TLS layouts.
214
+
215
+ ### Systemd
216
+
217
+ Run `python -m aird` (or the venv equivalent) as a service user with `--config` pointing at your JSON file. Logs go to the data directory (`aird.log` under the platform app data path).
218
+
219
+ ---
220
+
221
+ ## API overview
222
+
223
+ Authentication: session cookie after `/login`, bearer token, or `Authorization` header where supported. Mutating requests require the `_xsrf` cookie + `X-XSRFToken` header.
224
+
225
+ | Operation | Method / path |
226
+ |-----------|----------------|
227
+ | List directory | `GET /api/files/{path}` |
228
+ | Upload (small) | `POST /upload` |
229
+ | Upload (large) | `POST /api/upload/range/session` then `PUT /api/upload/range/{id}` |
230
+ | Upload status | `GET /api/upload/range/{id}/status` |
231
+ | Download | `GET /files/{path}?download=1` |
232
+ | Edit | `GET /edit/{path}`, `POST /edit` |
233
+ | Delete / rename / mkdir | `POST /delete`, `POST /rename`, `POST /mkdir` |
234
+ | Search UI | `GET /search` |
235
+ | Search (live) | WebSocket `/search/ws` |
236
+ | Log stream | WebSocket `/stream/{path}` |
237
+ | Shares | `POST /share/create`, `GET /share/list`, … |
238
+ | Health | `GET /health` |
239
+
240
+ Page-level UI contracts and routes are documented under [`docs/`](docs/README.md).
241
+
242
+ ---
243
+
244
+ ## Architecture notes
245
+
246
+ - **Async I/O:** Tornado event loop; on Linux optionally **uvloop**.
247
+ - **Free-threaded Python:** SQLite access is wrapped (`aird/db/sync.py`); upload chunk writes use `asyncio.to_thread` / `os.pwrite` so parallel range PUTs do not block the loop.
248
+ - **HTTP compression:** `gzip` by default; optional `zstandard` via `pip install aird[compress]` (loaded only on builds where the extension is nogil-safe).
249
+ - **Security headers:** COOP/COEP/CORP for transfer workers; strict CSP on HTML pages.
250
+ - **ABAC:** Optional policy engine (`abac_engine` flag) with admin-defined policies, tags, and user attributes.
251
+
252
+ ---
253
+
254
+ ## Development
255
+
256
+ ### Frontend assets
257
+
258
+ ```bash
259
+ npm install
260
+ npm run css:build # Tailwind → aird/static/css/app.css
261
+ npm run js:share # Bundle share UI
262
+ npm run vendor:fflate # Compression worker dependency
263
+ ```
264
+
265
+ ### Tests
266
+
267
+ ```bash
268
+ python -m pytest tests/
269
+ ```
270
+
271
+ ### Project layout
272
+
273
+ ```
274
+ aird/
275
+ handlers/ # HTTP & WebSocket handlers
276
+ services/ # Config, quota, share, audit, …
277
+ static/js/ # Browser UI & transfer engine
278
+ templates/ # Jinja2 pages
279
+ core/ # Compression, mmap, rate limits, …
280
+ docs/ # Per-page UI & admin documentation
281
+ ```
282
+
283
+ ---
284
+
285
+ ## Security
286
+
287
+ - Path traversal and symlink checks on file access
288
+ - Argon2 password hashing for local users
289
+ - CSRF on state-changing requests
290
+ - Upload extension allow-list (or allow-all) with max size enforced server-side
291
+ - Optional storage quotas (multi-user)
292
+ - Audit trail and live policy-decision stream for ABAC
293
+
294
+ Report issues via GitHub. For production, set `AIRD_COOKIE_SECRET`, use TLS, and restrict admin routes.
295
+
296
+ ---
297
+
298
+ ## License
299
+
300
+ **Business Source License 1.1 (BSL)** — see [LICENSE](LICENSE). Converts to **Apache 2.0** after the change date in the license file.
301
+
302
+ Commercial **File-Management-as-a-Service** use requires a separate license. Contact **Viswanatha Srinivas P**.
303
+
304
+ ---
305
+
306
+ ## Links
307
+
308
+ - **Repository:** https://github.com/blinkerbit/aird
309
+ - **PyPI:** https://pypi.org/project/aird/
310
+ - **UI / admin docs:** [docs/README.md](docs/README.md) · [docs/transfers.md](docs/transfers.md)
311
+ - **Issues:** https://github.com/blinkerbit/aird/issues
312
+
313
+ ---
314
+
315
+ Made by **Viswanatha Srinivas P**
@@ -0,0 +1,277 @@
1
+ # Aird
2
+
3
+ <p align="center">
4
+ <img src="aird/static/img/logo.png" alt="Aird" width="280">
5
+ </p>
6
+
7
+ ![Aird demo](./demo.webp)
8
+
9
+ **Aird** is a self-hosted file browser, editor, and sharing platform built on **Python** and **Tornado**. It targets fast local and LAN use: parallel HTTP transfers for large files, real-time log streaming, content search, secure shares, optional multi-user isolation, and an admin console that applies settings without restarts.
10
+
11
+ ---
12
+
13
+ ## Highlights
14
+
15
+ | Area | What you get |
16
+ |------|----------------|
17
+ | **File manager** | Browse, upload, download, rename, move, copy, bulk ops, in-browser text edit, ZIP download |
18
+ | **Large transfers** | Parallel **HTTP `Content-Range`** uploads/downloads (primary path for big files) |
19
+ | **Search** | **Super Search** — glob + regex content search with live WebSocket progress |
20
+ | **Streaming** | Tail log files over WebSocket with filters |
21
+ | **Sharing** | Token-based public/private shares, static or live folder views |
22
+ | **Security** | CSRF, CSP, path traversal checks, optional **ABAC** policies, WebAuthn, LDAP |
23
+ | **Integrations** | Google Drive / OneDrive browse, P2P WebRTC rooms, optional embedded SMB & WebDAV |
24
+ | **Ops** | SQLite-backed settings, audit log, feature flags, transfer rate limits, health endpoint |
25
+
26
+ ---
27
+
28
+ ## File transfers
29
+
30
+ Large uploads are designed for **high-throughput links** (e.g. gigabit LAN or VPN):
31
+
32
+ 1. **Small files** — single `POST /upload`.
33
+ 2. **Large files** — client opens a range session (`POST /api/upload/range/session`), then sends many parallel **`PUT`** requests with `Content-Range`. Each chunk is written **in place** at the correct byte offset on disk (no separate part files, no concat step at the end).
34
+ 3. **Downloads** — `GET /files/...?download=1` with optional `Range` for parallel fetch.
35
+
36
+ Defaults (all adjustable in **Admin → Upload settings**):
37
+
38
+ | Setting | Default | Notes |
39
+ |---------|---------|--------|
40
+ | Max file size | 10 240 MB (10 GiB) | Hard cap per file |
41
+ | Single-request max | 100 MB | Files **≥** this use parallel HTTP ranges |
42
+ | HTTP chunk size | 90 MB | Per range `PUT` body |
43
+ | HTTP parallelism | 16 | Concurrent upload streams |
44
+
45
+ **Behind nginx/Caddy:** set `client_max_body_size` (or equivalent) to at least your HTTP chunk size. If **Single-request max** is `0`, Aird uses a **100 MB** parallel threshold (proxy-safe), not a single POST for the entire max file size.
46
+
47
+ Optional WebSocket upload (`/ws/file-transfer`) remains for specialized paths; the browser UI uses **HTTP parallel** by default.
48
+
49
+ Transfer progress, cancel, and resume metadata are handled in the browser (`transfer-tracker.js`, `transfer-engine/`, service worker `sw-transfer.js`).
50
+
51
+ ---
52
+
53
+ ## Quick start
54
+
55
+ ### Install
56
+
57
+ ```bash
58
+ pip install aird
59
+
60
+ # Optional: HTTP response compression codecs (gzip is always available)
61
+ pip install "aird[compress]"
62
+
63
+ # From source
64
+ git clone https://github.com/blinkerbit/aird.git
65
+ cd aird
66
+ pip install -e .
67
+ ```
68
+
69
+ **Python:** 3.10+ required. On Linux, **free-threaded** builds (`3.13t` / `3.14t`) are supported and recommended for parallel disk I/O; the server detects nogil at startup and sizes the I/O thread pool accordingly.
70
+
71
+ ### Run
72
+
73
+ ```bash
74
+ # Default: port 8000, current directory as root
75
+ python -m aird
76
+
77
+ # Custom root and port
78
+ python -m aird --root /data --port 8080
79
+
80
+ # Multi-user (per-user home directories under root)
81
+ python -m aird --root /data --multi-user
82
+
83
+ # TLS
84
+ python -m aird --ssl-cert /path/cert.pem --ssl-key /path/key.pem --port 443
85
+
86
+ # Worker processes (Linux; default is auto from CPU topology)
87
+ python -m aird --workers 4
88
+ ```
89
+
90
+ On first start, random **access** and **admin** tokens are printed unless you set them via `--token`, `--admin-token`, `config.json`, or `AIRD_ACCESS_TOKEN`.
91
+
92
+ Open `http://localhost:8000/` → redirects to `/files/`.
93
+
94
+ ### CLI client
95
+
96
+ ```bash
97
+ pip install aird # includes aird-cli
98
+ aird-cli config set server https://your-host
99
+ aird-cli login
100
+ aird-cli ls /
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Configuration
106
+
107
+ ### `config.json`
108
+
109
+ ```json
110
+ {
111
+ "port": 8000,
112
+ "root": "/srv/files",
113
+ "hostname": "files.example.com",
114
+ "token": "your-access-token",
115
+ "admin_token": "your-admin-token",
116
+ "multi_user": false,
117
+ "workers": 2,
118
+ "ldap": {
119
+ "enabled": false,
120
+ "server": "ldap://ldap.example.com",
121
+ "base_dn": "dc=example,dc=com"
122
+ },
123
+ "feature_flags": {
124
+ "file_upload": true,
125
+ "super_search": true,
126
+ "abac_engine": false
127
+ }
128
+ }
129
+ ```
130
+
131
+ ```bash
132
+ python -m aird --config /etc/aird/config.json
133
+ ```
134
+
135
+ ### Environment variables (common)
136
+
137
+ | Variable | Purpose |
138
+ |----------|---------|
139
+ | `AIRD_ACCESS_TOKEN` | Login token |
140
+ | `AIRD_COOKIE_SECRET` | Persistent session signing (set in production) |
141
+ | `AIRD_CORPORATE_IP_CIDRS` | Comma-separated CIDRs for ABAC / WAN compression rules |
142
+ | `AIRD_GDRIVE_ACCESS_TOKEN` / `AIRD_ONEDRIVE_ACCESS_TOKEN` | Cloud providers |
143
+
144
+ ### Admin console
145
+
146
+ `GET /admin` — feature flags, upload limits, extension allow-list, WebSocket pool limits, LDAP, network shares, ABAC policies/tags, users, audit. Changes persist to SQLite and apply without restart (feature-flag subscribers refresh over `/features` WebSocket).
147
+
148
+ ---
149
+
150
+ ## Production deployment
151
+
152
+ ### Reverse proxy
153
+
154
+ Aird listens on one port (default **8000**). Terminate TLS at **Caddy**, **nginx**, or similar.
155
+
156
+ **nginx example** (adjust chunk size to match Admin → HTTP chunk):
157
+
158
+ ```nginx
159
+ client_max_body_size 128m;
160
+
161
+ location / {
162
+ proxy_pass http://127.0.0.1:8000;
163
+ proxy_http_version 1.1;
164
+ proxy_set_header Host $host;
165
+ proxy_set_header X-Real-IP $remote_addr;
166
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
167
+ proxy_set_header X-Forwarded-Proto $scheme;
168
+ }
169
+ ```
170
+
171
+ WebSocket routes (`/stream/`, `/search/ws`, `/features`, `/ws/…`) need `Upgrade` and `Connection` headers if you proxy them.
172
+
173
+ ### Ubuntu deploy script
174
+
175
+ `deploy_local.ps1` (run from Windows) syncs source or a wheel to a remote host, creates a **uv** venv with **Python 3.14t**, and installs the package. See `docs/wireguard-deploy.md` for VPN-only TLS layouts.
176
+
177
+ ### Systemd
178
+
179
+ Run `python -m aird` (or the venv equivalent) as a service user with `--config` pointing at your JSON file. Logs go to the data directory (`aird.log` under the platform app data path).
180
+
181
+ ---
182
+
183
+ ## API overview
184
+
185
+ Authentication: session cookie after `/login`, bearer token, or `Authorization` header where supported. Mutating requests require the `_xsrf` cookie + `X-XSRFToken` header.
186
+
187
+ | Operation | Method / path |
188
+ |-----------|----------------|
189
+ | List directory | `GET /api/files/{path}` |
190
+ | Upload (small) | `POST /upload` |
191
+ | Upload (large) | `POST /api/upload/range/session` then `PUT /api/upload/range/{id}` |
192
+ | Upload status | `GET /api/upload/range/{id}/status` |
193
+ | Download | `GET /files/{path}?download=1` |
194
+ | Edit | `GET /edit/{path}`, `POST /edit` |
195
+ | Delete / rename / mkdir | `POST /delete`, `POST /rename`, `POST /mkdir` |
196
+ | Search UI | `GET /search` |
197
+ | Search (live) | WebSocket `/search/ws` |
198
+ | Log stream | WebSocket `/stream/{path}` |
199
+ | Shares | `POST /share/create`, `GET /share/list`, … |
200
+ | Health | `GET /health` |
201
+
202
+ Page-level UI contracts and routes are documented under [`docs/`](docs/README.md).
203
+
204
+ ---
205
+
206
+ ## Architecture notes
207
+
208
+ - **Async I/O:** Tornado event loop; on Linux optionally **uvloop**.
209
+ - **Free-threaded Python:** SQLite access is wrapped (`aird/db/sync.py`); upload chunk writes use `asyncio.to_thread` / `os.pwrite` so parallel range PUTs do not block the loop.
210
+ - **HTTP compression:** `gzip` by default; optional `zstandard` via `pip install aird[compress]` (loaded only on builds where the extension is nogil-safe).
211
+ - **Security headers:** COOP/COEP/CORP for transfer workers; strict CSP on HTML pages.
212
+ - **ABAC:** Optional policy engine (`abac_engine` flag) with admin-defined policies, tags, and user attributes.
213
+
214
+ ---
215
+
216
+ ## Development
217
+
218
+ ### Frontend assets
219
+
220
+ ```bash
221
+ npm install
222
+ npm run css:build # Tailwind → aird/static/css/app.css
223
+ npm run js:share # Bundle share UI
224
+ npm run vendor:fflate # Compression worker dependency
225
+ ```
226
+
227
+ ### Tests
228
+
229
+ ```bash
230
+ python -m pytest tests/
231
+ ```
232
+
233
+ ### Project layout
234
+
235
+ ```
236
+ aird/
237
+ handlers/ # HTTP & WebSocket handlers
238
+ services/ # Config, quota, share, audit, …
239
+ static/js/ # Browser UI & transfer engine
240
+ templates/ # Jinja2 pages
241
+ core/ # Compression, mmap, rate limits, …
242
+ docs/ # Per-page UI & admin documentation
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Security
248
+
249
+ - Path traversal and symlink checks on file access
250
+ - Argon2 password hashing for local users
251
+ - CSRF on state-changing requests
252
+ - Upload extension allow-list (or allow-all) with max size enforced server-side
253
+ - Optional storage quotas (multi-user)
254
+ - Audit trail and live policy-decision stream for ABAC
255
+
256
+ Report issues via GitHub. For production, set `AIRD_COOKIE_SECRET`, use TLS, and restrict admin routes.
257
+
258
+ ---
259
+
260
+ ## License
261
+
262
+ **Business Source License 1.1 (BSL)** — see [LICENSE](LICENSE). Converts to **Apache 2.0** after the change date in the license file.
263
+
264
+ Commercial **File-Management-as-a-Service** use requires a separate license. Contact **Viswanatha Srinivas P**.
265
+
266
+ ---
267
+
268
+ ## Links
269
+
270
+ - **Repository:** https://github.com/blinkerbit/aird
271
+ - **PyPI:** https://pypi.org/project/aird/
272
+ - **UI / admin docs:** [docs/README.md](docs/README.md) · [docs/transfers.md](docs/transfers.md)
273
+ - **Issues:** https://github.com/blinkerbit/aird/issues
274
+
275
+ ---
276
+
277
+ Made by **Viswanatha Srinivas P**
@@ -10,8 +10,8 @@ from typing import Any, Callable
10
10
  import requests
11
11
 
12
12
 
13
- DEFAULT_CHUNK = 32 * 1024 * 1024
14
- DEFAULT_CONCURRENCY = 4
13
+ DEFAULT_CHUNK = 16 * 1024 * 1024
14
+ DEFAULT_CONCURRENCY = 12
15
15
 
16
16
 
17
17
  def _clone_session(http: requests.Session) -> requests.Session: