aignostics 0.2.52__tar.gz → 0.2.57__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 (208) hide show
  1. {aignostics-0.2.52 → aignostics-0.2.57}/PKG-INFO +10 -15
  2. {aignostics-0.2.52 → aignostics-0.2.57}/examples/notebook.py +1 -1
  3. {aignostics-0.2.52 → aignostics-0.2.57}/pyproject.toml +19 -22
  4. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_cli.py +3 -2
  5. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/_page_builder.py +3 -3
  6. aignostics-0.2.57/src/aignostics/application/_gui/_page_index.py +73 -0
  7. aignostics-0.2.57/src/aignostics/application/_gui/assets/home-card-1.png +0 -0
  8. aignostics-0.2.57/src/aignostics/application/_gui/assets/home-card-2.png +0 -0
  9. aignostics-0.2.57/src/aignostics/application/_gui/assets/home-card-3.png +0 -0
  10. aignostics-0.2.57/src/aignostics/application/_gui/assets/home-card-4.png +0 -0
  11. aignostics-0.2.57/src/aignostics/application/_gui/assets/home-card-5.png +0 -0
  12. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_service.py +20 -1
  13. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/cli.py +3 -2
  14. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/constants.py +1 -1
  15. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/gui/_frame.py +68 -15
  16. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/__init__.py +5 -1
  17. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/_authentication.py +105 -16
  18. aignostics-0.2.57/src/aignostics/platform/_cli.py +89 -0
  19. aignostics-0.2.57/src/aignostics/platform/_service.py +275 -0
  20. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/_settings.py +43 -2
  21. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/_gui.py +11 -0
  22. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/system/_cli.py +0 -6
  23. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/system/_service.py +1 -1
  24. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_log.py +10 -7
  25. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_notebook.py +1 -1
  26. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_sentry.py +3 -3
  27. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/boot.py +0 -3
  28. aignostics-0.2.52/src/aignostics/application/_gui/_page_index.py +0 -49
  29. aignostics-0.2.52/src/aignostics/application/_gui/assets/home-card-1.png +0 -0
  30. aignostics-0.2.52/src/aignostics/application/_gui/assets/home-card-2.png +0 -0
  31. aignostics-0.2.52/src/aignostics/application/_gui/assets/home-card-3.png +0 -0
  32. aignostics-0.2.52/src/aignostics/application/_gui/assets/home-card-4.png +0 -0
  33. aignostics-0.2.52/src/aignostics/application/_gui/assets/home-card-5.png +0 -0
  34. aignostics-0.2.52/src/aignostics/platform/_service.py +0 -101
  35. {aignostics-0.2.52 → aignostics-0.2.57}/.gitignore +0 -0
  36. {aignostics-0.2.52 → aignostics-0.2.57}/LICENSE +0 -0
  37. {aignostics-0.2.52 → aignostics-0.2.57}/README.md +0 -0
  38. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/.openapi-generator/FILES +0 -0
  39. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/.openapi-generator/VERSION +0 -0
  40. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/api/public_api.py +0 -0
  41. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/api_client.py +0 -0
  42. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/api_response.py +0 -0
  43. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/configuration.py +0 -0
  44. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/exceptions.py +0 -0
  45. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/__init__.py +0 -0
  46. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/application_read_response.py +0 -0
  47. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/application_run_status.py +0 -0
  48. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/application_version_read_response.py +0 -0
  49. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/http_validation_error.py +0 -0
  50. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/input_artifact_creation_request.py +0 -0
  51. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/input_artifact_read_response.py +0 -0
  52. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/item_creation_request.py +0 -0
  53. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/item_result_read_response.py +0 -0
  54. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/item_status.py +0 -0
  55. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/output_artifact_read_response.py +0 -0
  56. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/output_artifact_result_read_response.py +0 -0
  57. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/output_artifact_scope.py +0 -0
  58. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/payload_input_artifact.py +0 -0
  59. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/payload_item.py +0 -0
  60. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/payload_output_artifact.py +0 -0
  61. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/run_creation_request.py +0 -0
  62. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/run_creation_response.py +0 -0
  63. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/run_read_response.py +0 -0
  64. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/transfer_urls.py +0 -0
  65. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/user_payload.py +0 -0
  66. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/validation_error.py +0 -0
  67. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/models/validation_error_loc_inner.py +0 -0
  68. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/aignx/codegen/rest.py +0 -0
  69. {aignostics-0.2.52 → aignostics-0.2.57}/codegen/out/docs/PublicApi.md +0 -0
  70. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
  71. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics/_internal/boto3/examples/s3.rst +0 -0
  72. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  73. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  74. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  75. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/boto3/examples/cloudfront.rst +0 -0
  76. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/boto3/examples/s3.rst +0 -0
  77. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  78. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  79. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  80. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/boto3/examples/cloudfront.rst +0 -0
  81. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/boto3/examples/s3.rst +0 -0
  82. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  83. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  84. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  85. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
  86. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics/_internal/boto3/examples/s3.rst +0 -0
  87. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  88. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  89. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  90. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/boto3/examples/cloudfront.rst +0 -0
  91. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/boto3/examples/s3.rst +0 -0
  92. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  93. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  94. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  95. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/boto3/examples/cloudfront.rst +0 -0
  96. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/boto3/examples/s3.rst +0 -0
  97. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  98. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  99. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  100. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
  101. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/boto3/examples/s3.rst +0 -0
  102. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  103. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  104. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  105. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
  106. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/boto3/examples/s3.rst +0 -0
  107. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  108. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  109. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  110. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
  111. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/boto3/examples/s3.rst +0 -0
  112. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  113. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  114. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  115. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-latest/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
  116. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-latest/aignostics/_internal/boto3/examples/s3.rst +0 -0
  117. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
  118. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
  119. {aignostics-0.2.52 → aignostics-0.2.57}/dist_native_all/dist_native-windows-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
  120. {aignostics-0.2.52 → aignostics-0.2.57}/examples/__init__.py +0 -0
  121. {aignostics-0.2.52 → aignostics-0.2.57}/examples/notebook.ipynb +0 -0
  122. {aignostics-0.2.52 → aignostics-0.2.57}/examples/script.py +0 -0
  123. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/__init__.py +0 -0
  124. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/__init__.py +0 -0
  125. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/_frame.py +0 -0
  126. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/_page_application_describe.py +0 -0
  127. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/_page_application_run_describe.py +0 -0
  128. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/_utils.py +0 -0
  129. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/canceled.lottie +0 -0
  130. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/done.lottie +0 -0
  131. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/empty.lottie +0 -0
  132. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/error.lottie +0 -0
  133. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/error_alt.lottie +0 -0
  134. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/image-not-found.png +0 -0
  135. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/pending.lottie +0 -0
  136. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/pending_alt.lottie +0 -0
  137. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/ruo.png +0 -0
  138. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_gui/assets/ruo.svg +0 -0
  139. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_settings.py +0 -0
  140. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/application/_utils.py +0 -0
  141. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/bucket/__init__.py +0 -0
  142. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/bucket/_cli.py +0 -0
  143. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/bucket/_gui.py +0 -0
  144. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/bucket/_service.py +0 -0
  145. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/bucket/_settings.py +0 -0
  146. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/bucket/assets/Google-Cloud-logo.png +0 -0
  147. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/bucket/assets/Google-Cloud-logo.svg +0 -0
  148. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/dataset/__init__.py +0 -0
  149. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/dataset/_cli.py +0 -0
  150. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/dataset/_gui.py +0 -0
  151. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/dataset/_service.py +0 -0
  152. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/dataset/assets/NIH-IDC-logo.svg +0 -0
  153. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/gui/__init__.py +0 -0
  154. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/gui/_theme.py +0 -0
  155. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/gui/assets/cabin-v27-latin-regular.woff2 +0 -0
  156. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/gui/assets/logo.png +0 -0
  157. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/notebook/__init__.py +0 -0
  158. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/notebook/_gui.py +0 -0
  159. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/notebook/_notebook.py +0 -0
  160. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/notebook/_service.py +0 -0
  161. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/notebook/assets/python.lottie +0 -0
  162. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/_client.py +0 -0
  163. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/_constants.py +0 -0
  164. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/_messages.py +0 -0
  165. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/_utils.py +0 -0
  166. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/resources/__init__.py +0 -0
  167. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/resources/applications.py +0 -0
  168. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/resources/runs.py +0 -0
  169. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/platform/resources/utils.py +0 -0
  170. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/__init__.py +0 -0
  171. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/_cli.py +0 -0
  172. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/_service.py +0 -0
  173. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/_settings.py +0 -0
  174. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/assets/download.lottie +0 -0
  175. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/assets/microscope.lottie +0 -0
  176. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/assets/update.lottie +0 -0
  177. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/scripts/add.groovy +0 -0
  178. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/scripts/annotate.groovy +0 -0
  179. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/scripts/inspect.groovy +0 -0
  180. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/qupath/scripts/test.groovy +0 -0
  181. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/system/__init__.py +0 -0
  182. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/system/_exceptions.py +0 -0
  183. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/system/_gui.py +0 -0
  184. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/system/_settings.py +0 -0
  185. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/system/assets/system.lottie +0 -0
  186. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/third_party/bottle.py +0 -0
  187. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/third_party/idc_index.py +0 -0
  188. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/__init__.py +0 -0
  189. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_cli.py +0 -0
  190. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_console.py +0 -0
  191. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_constants.py +0 -0
  192. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_di.py +0 -0
  193. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_fs.py +0 -0
  194. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_gui.py +0 -0
  195. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_health.py +0 -0
  196. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_logfire.py +0 -0
  197. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_process.py +0 -0
  198. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_service.py +0 -0
  199. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/utils/_settings.py +0 -0
  200. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/wsi/__init__.py +0 -0
  201. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/wsi/_cli.py +0 -0
  202. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/wsi/_gui.py +0 -0
  203. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/wsi/_openslide_handler.py +0 -0
  204. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/wsi/_pydicom_handler.py +0 -0
  205. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/wsi/_service.py +0 -0
  206. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/wsi/_utils.py +0 -0
  207. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics/wsi/assets/fallback.png +0 -0
  208. {aignostics-0.2.52 → aignostics-0.2.57}/src/aignostics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aignostics
3
- Version: 0.2.52
3
+ Version: 0.2.57
4
4
  Summary: 🔬 Python SDK providing access to the Aignostics Platform. Includes Aignostics Launchpad (Desktop Application), Aignostics CLI (Command-Line Interface), example notebooks, and Aignostics Client Library.
5
5
  Project-URL: Homepage, https://aignostics.readthedocs.io/en/latest/
6
6
  Project-URL: Documentation, https://aignostics.readthedocs.io/en/latest/
@@ -49,8 +49,8 @@ Classifier: Programming Language :: Python :: 3.13
49
49
  Classifier: Typing :: Typed
50
50
  Requires-Python: <4.0,>=3.11
51
51
  Requires-Dist: appdirs>=1.4.4
52
- Requires-Dist: boto3>=1.38.33
53
- Requires-Dist: click
52
+ Requires-Dist: auth0-python>=4.10.0
53
+ Requires-Dist: boto3>=1.38.36
54
54
  Requires-Dist: dicom-validator>=0.7.1
55
55
  Requires-Dist: dicomweb-client[gcp]>=0.59.2
56
56
  Requires-Dist: duckdb<=1.4.0,>=0.10.0
@@ -61,10 +61,11 @@ Requires-Dist: highdicom>=0.25.1
61
61
  Requires-Dist: httpx>=0.28.1
62
62
  Requires-Dist: humanize>=4.12.3
63
63
  Requires-Dist: idc-index-data==21.0.0
64
+ Requires-Dist: ijson>=3.4.0
64
65
  Requires-Dist: jsf>=0.11.2
65
66
  Requires-Dist: jsonschema>=4.24.0
66
- Requires-Dist: logfire[system-metrics]>=3.17.0
67
- Requires-Dist: nicegui[native]>=2.19.0
67
+ Requires-Dist: logfire[system-metrics]>=3.19.0
68
+ Requires-Dist: nicegui[native]>=2.20.0
68
69
  Requires-Dist: openslide-bin>=4.0.0.8
69
70
  Requires-Dist: openslide-python>=1.4.2
70
71
  Requires-Dist: opentelemetry-instrumentation-fastapi>=0.53b0
@@ -75,27 +76,22 @@ Requires-Dist: opentelemetry-instrumentation-sqlite3>=0.53b0
75
76
  Requires-Dist: opentelemetry-instrumentation-tornado>=0.53b0
76
77
  Requires-Dist: opentelemetry-instrumentation-urllib3>=0.53b0
77
78
  Requires-Dist: opentelemetry-instrumentation-urllib>=0.53b0
78
- Requires-Dist: packaging
79
+ Requires-Dist: packaging>=25.0
79
80
  Requires-Dist: pandas<=2.3.0
80
- Requires-Dist: platformdirs
81
- Requires-Dist: psutil
81
+ Requires-Dist: platformdirs>=4.3.8
82
82
  Requires-Dist: psutil>=7.0.0
83
- Requires-Dist: pyarrow
83
+ Requires-Dist: pyarrow>=20.0.0
84
84
  Requires-Dist: pydantic-settings>=2.9.1
85
85
  Requires-Dist: pyjwt[crypto]>=2.10.1
86
86
  Requires-Dist: python-dateutil>=2.9.0.post0
87
87
  Requires-Dist: pywin32>=310; sys_platform == 'win32'
88
88
  Requires-Dist: pyyaml>=6.0
89
- Requires-Dist: requests
90
89
  Requires-Dist: requests-oauthlib>=2.0.0
91
90
  Requires-Dist: requests>=2.32.3
92
- Requires-Dist: s5cmd
93
91
  Requires-Dist: s5cmd>=0.2.0
94
- Requires-Dist: sentry-sdk>=2.29.1
92
+ Requires-Dist: sentry-sdk>=2.30.0
95
93
  Requires-Dist: shapely>=2.1.1
96
94
  Requires-Dist: show-in-file-manager>=1.1.5
97
- Requires-Dist: sphinx-click
98
- Requires-Dist: tqdm
99
95
  Requires-Dist: tqdm>=4.67.1
100
96
  Requires-Dist: typer>=0.16.0
101
97
  Requires-Dist: uptime>=3.0.1
@@ -109,7 +105,6 @@ Requires-Dist: marimo>=0.13.15; extra == 'marimo'
109
105
  Requires-Dist: matplotlib>=3.10.3; extra == 'marimo'
110
106
  Requires-Dist: shapely>=2.1.0; extra == 'marimo'
111
107
  Provides-Extra: qupath
112
- Requires-Dist: ijson>=3.4.0; extra == 'qupath'
113
108
  Description-Content-Type: text/markdown
114
109
 
115
110
 
@@ -2,7 +2,7 @@
2
2
  # requires-python = ">=3.13"
3
3
  # dependencies = [
4
4
  # "marimo",
5
- # "aignostics==0.2.52",
5
+ # "aignostics==0.2.57",
6
6
  # ]
7
7
  # ///
8
8
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aignostics"
3
- version = "0.2.52"
3
+ version = "0.2.57"
4
4
  description = "🔬 Python SDK providing access to the Aignostics Platform. Includes Aignostics Launchpad (Desktop Application), Aignostics CLI (Command-Line Interface), example notebooks, and Aignostics Client Library."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -75,8 +75,8 @@ requires-python = ">=3.11, <4.0"
75
75
  dependencies = [
76
76
  # From Template
77
77
  "fastapi[standard,all]>=0.115.12",
78
- "logfire[system-metrics]>=3.17.0",
79
- "nicegui[native]>=2.19.0",
78
+ "logfire[system-metrics]>=3.19.0",
79
+ "nicegui[native]>=2.20.0",
80
80
  "opentelemetry-instrumentation-fastapi>=0.53b0",
81
81
  "opentelemetry-instrumentation-httpx>=0.53b0",
82
82
  "opentelemetry-instrumentation-jinja2>=0.53b0",
@@ -88,48 +88,44 @@ dependencies = [
88
88
  "psutil>=7.0.0",
89
89
  "pydantic-settings>=2.9.1",
90
90
  "pywin32>=310 ; sys_platform == 'win32'",
91
- "sentry-sdk>=2.29.1",
91
+ "sentry-sdk>=2.30.0",
92
92
  "typer>=0.16.0",
93
93
  "uptime>=3.0.1",
94
94
  # Custom
95
95
  "appdirs>=1.4.4",
96
- "boto3>=1.38.33",
96
+ "auth0-python>=4.10.0",
97
+ "boto3>=1.38.36",
97
98
  "dicom-validator>=0.7.1",
98
99
  "dicomweb-client[gcp]>=0.59.2",
100
+ "duckdb>=0.10.0,<=1.4.0",
99
101
  "google-cloud-storage>=2.12.0",
100
102
  "google-crc32c>=1.7.1",
101
103
  "highdicom>=0.25.1",
102
104
  "httpx>=0.28.1",
103
105
  "humanize>=4.12.3",
106
+ "idc-index-data==21.0.0",
107
+ "ijson>=3.4.0",
104
108
  "jsf>=0.11.2",
105
109
  "jsonschema>=4.24.0",
106
110
  "openslide-bin>=4.0.0.8",
107
111
  "openslide-python>=1.4.2",
112
+ "packaging>=25.0",
113
+ "pandas<=2.3.0",
114
+ "platformdirs>=4.3.8",
115
+ "psutil>=7.0.0",
116
+ "pyarrow>=20.0.0",
108
117
  "pyjwt[crypto]>=2.10.1",
109
118
  "python-dateutil>=2.9.0.post0",
119
+ # "pywebview[qt6]>=5.4; sys_platform == 'linux'",
110
120
  "pyyaml>=6.0",
111
121
  "requests>=2.32.3",
112
122
  "requests-oauthlib>=2.0.0",
113
123
  "s5cmd>=0.2.0",
124
+ "shapely>=2.1.1",
114
125
  "show-in-file-manager>=1.1.5",
115
126
  "tqdm>=4.67.1",
116
127
  "urllib3>=2.2.3",
117
- "shapely>=2.1.1",
118
128
  "wsidicom>=0.27.1",
119
- # "pywebview[qt6]>=5.4; sys_platform == 'linux'",
120
- # idc-index
121
- "click",
122
- 'duckdb>=0.10.0,<=1.4.0',
123
- "idc-index-data==21.0.0",
124
- "packaging",
125
- "pandas<=2.3.0",
126
- "platformdirs",
127
- "psutil",
128
- "pyarrow",
129
- "requests",
130
- "s5cmd",
131
- "sphinx-click",
132
- "tqdm",
133
129
  ]
134
130
 
135
131
  [project.optional-dependencies]
@@ -140,7 +136,7 @@ marimo = [
140
136
  "matplotlib>=3.10.3",
141
137
  "shapely>=2.1.0",
142
138
  ]
143
- qupath = ["ijson>=3.4.0"]
139
+ qupath = [] # Making this a default extra
144
140
  [dependency-groups]
145
141
  dev = [
146
142
  "autodoc-pydantic>=2.2.0",
@@ -175,6 +171,7 @@ dev = [
175
171
  "scalene>=1.5.51",
176
172
  "sphinx>=8.2.3",
177
173
  "sphinx-autobuild>=2024.10.3",
174
+ "sphinx-click>=6.0.0",
178
175
  "sphinx-copybutton>=0.5.2",
179
176
  "sphinx-inline-tabs>=2023.4.21",
180
177
  "sphinx-mdinclude>=0.6.2",
@@ -355,7 +352,7 @@ source = ["src/"]
355
352
 
356
353
 
357
354
  [tool.bumpversion]
358
- current_version = "0.2.52"
355
+ current_version = "0.2.57"
359
356
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
360
357
  serialize = ["{major}.{minor}.{patch}"]
361
358
  search = "{current_version}"
@@ -281,10 +281,11 @@ def run_execute( # noqa: PLR0913, PLR0917
281
281
  list[str],
282
282
  typer.Argument(
283
283
  help="Mapping to use for amending metadata CSV file. "
284
- "Each mapping is of the form '<regexp>:<key>:<value>,<key>:<value>,...'. "
284
+ "Each mapping is of the form '<regexp>:<key>:<value>,<key>:<value>,...'."
285
285
  "The regular expression is matched against the reference attribute of the entry. "
286
286
  "The key/value pairs are applied to the entry if the pattern matches. "
287
- "You can use the mapping option multiple times to set values for multiple files. ",
287
+ "You can use the mapping option multiple times to set values for multiple files. "
288
+ 'Example: ".*:staining_method:H&E,tissue:LIVER,disease:LIVER_CANCER"',
288
289
  ),
289
290
  ],
290
291
  create_subdirectory_for_run: Annotated[
@@ -8,16 +8,16 @@ from aignostics.utils import BasePageBuilder
8
8
  class PageBuilder(BasePageBuilder):
9
9
  @staticmethod
10
10
  def register_pages() -> None:
11
- from nicegui import app, ui # noq # noqa: PLC0415
11
+ from nicegui import Client, app, ui # noq # noqa: PLC0415
12
12
 
13
13
  app.add_static_files("/application_assets", Path(__file__).parent / "assets")
14
14
 
15
15
  @ui.page("/")
16
- async def page_index() -> None:
16
+ async def page_index(client: Client) -> None:
17
17
  """Index page of application module, serving as the homepage of Aignostics Launchpad."""
18
18
  from ._page_index import _page_index # noqa: PLC0415
19
19
 
20
- await _page_index()
20
+ await _page_index(client)
21
21
 
22
22
  @ui.page("/application/{application_id}")
23
23
  async def page_application_describe(application_id: str) -> None:
@@ -0,0 +1,73 @@
1
+ """GUI of application module including homepage of Aignostics Launchpad."""
2
+
3
+ from importlib.util import find_spec
4
+
5
+ from nicegui import Client, app, ui # noq
6
+
7
+ from aignostics.utils import get_logger
8
+
9
+ from ._frame import _frame
10
+
11
+ logger = get_logger(__name__)
12
+
13
+
14
+ async def _page_index(client: Client) -> None:
15
+ """Homepage of Applications."""
16
+ client.content.classes(remove="nicegui-content")
17
+ client.content.classes(add="pl-5 pt-5")
18
+
19
+ await _frame("Analyze your Whole Slide Images with AI", left_sidebar=True)
20
+
21
+ with ui.row().classes("p-4 pt-2 pr-0"), ui.column():
22
+ await ui.context.client.connected()
23
+ ui.label("Welcome to the Aignostics Launchpad").bind_text_from(
24
+ app.storage.tab,
25
+ "user_info",
26
+ lambda user_info: (
27
+ f"Welcome {user_info.profile.given_name if user_info.profile else ''} to the Aignostics Launchpad"
28
+ ),
29
+ ).classes("text-4xl mb-2")
30
+ ui.label(
31
+ "Using the Launchpad, you can run Aignostics Atlas applications on your whole slide images, "
32
+ "monitor progress, and download results for analysis."
33
+ ).classes("text-2xl")
34
+ with ui.row().classes("w-full h-screen flex"):
35
+ with ui.column().classes("flex-1 pr-0"):
36
+ ui.label("Have your slides ready to go?").classes("text-xl")
37
+ ui.label(
38
+ "Select the relevant application from the left sidebar to upload your images to get started."
39
+ ).classes("text")
40
+ ui.label("Looking to test with public data first?").classes("text-xl")
41
+ ui.label(
42
+ 'Open ☰ menu and click "Download Datasets" to select a dataset '
43
+ "from Image Data Commons by the National Cancer Institute to test with."
44
+ ).classes("text")
45
+ ui.label("Already submitted your slides?").classes("text-xl")
46
+ ui.label(
47
+ "Select your run on the left to monitor progress, cancel while pending, or download results."
48
+ ).classes("text")
49
+
50
+ if find_spec("ijson"):
51
+ from aignostics.qupath import Service as QuPathService # noqa: PLC0415
52
+
53
+ ui.label("Visualize results in QuPath Microscopy Viewer?").classes("text-xl")
54
+ if QuPathService.is_installed():
55
+ ui.label('Select a completed run and click "QuPath" to visualize results.').classes("text")
56
+ else:
57
+ ui.label(
58
+ "To visualize results with one click the QuPath application must be installed. "
59
+ 'Select "QuPath extension" in the ☰ menu to install.'
60
+ ).classes("text")
61
+
62
+ if find_spec("marimo"):
63
+ ui.label("Analyze results in Python Notebooks?").classes("text-xl")
64
+ ui.label('On completed runs click "Marimo" to directly open the notebook.').classes("text")
65
+
66
+ with (
67
+ ui.carousel(animated=True, arrows=True, navigation=True)
68
+ .classes("flex-1 h-full m-0 p-0 self-end bg-[#423D6B] ")
69
+ .props("infinite autoplay=1000 control-color=transparent")
70
+ ):
71
+ for i in range(1, 5): # Loop from 1 to 4
72
+ with ui.carousel_slide().classes("p-0 m-0"):
73
+ ui.image(f"/application_assets/home-card-{i}.png").classes("w-full h-auto object-contain")
@@ -32,6 +32,9 @@ from aignostics.platform import (
32
32
  NotFoundException,
33
33
  OutputArtifactElement,
34
34
  )
35
+ from aignostics.platform import (
36
+ Service as PlatformService,
37
+ )
35
38
  from aignostics.utils import UNHIDE_SENSITIVE_INFO, BaseService, Health, get_logger, sanitize_path_component
36
39
  from aignostics.wsi import Service as WSIService
37
40
 
@@ -47,7 +50,6 @@ if has_qupath_extra:
47
50
 
48
51
  logger = get_logger(__name__)
49
52
 
50
-
51
53
  APPLICATION_RUN_DOWNLOAD_SLEEP_SECONDS = 5
52
54
  APPLICATION_RUN_FILE_READ_CHUNK_SIZE = 1024 * 1024 * 1024 # 1GB
53
55
  APPLICATION_RUN_DOWNLOAD_CHUNK_SIZE = 1024 * 1024 # 1MB
@@ -150,6 +152,7 @@ class Service(BaseService):
150
152
 
151
153
  _settings: Settings
152
154
  _client: Client | None = None
155
+ _platform_service: PlatformService | None = None
153
156
 
154
157
  def __init__(self) -> None:
155
158
  """Initialize service."""
@@ -192,6 +195,22 @@ class Service(BaseService):
192
195
  logger.debug("Reusing platform client.")
193
196
  return self._client
194
197
 
198
+ def _get_platform_service(self) -> PlatformService:
199
+ """Get the platform service.
200
+
201
+ Returns:
202
+ PlatformService: The platform service.
203
+
204
+ Raises:
205
+ Exception: If the client cannot be created.
206
+ """
207
+ if self._platform_service is None:
208
+ logger.debug("Creating platform service.")
209
+ self._platform_service = PlatformService()
210
+ else:
211
+ logger.debug("Reusing platform service.")
212
+ return self._platform_service
213
+
195
214
  def applications(self) -> list[Application]:
196
215
  """Get a list of all applications.
197
216
 
@@ -66,6 +66,7 @@ if __name__ == "__main__": # pragma: no cover
66
66
  try:
67
67
  cli()
68
68
  except Exception as e: # noqa: BLE001
69
- logger.critical("Fatal error occurred: %s", e)
70
- console.print(f"Fatal error occurred: {e}", style="error")
69
+ message = f"An error occurred while running the CLI: {e!s}"
70
+ logger.critical(message)
71
+ console.print(message, style="error")
71
72
  sys.exit(1)
@@ -5,7 +5,7 @@ from pathlib import Path
5
5
 
6
6
  # Configuration required by oe-python-template
7
7
  API_VERSIONS: dict[str, str] = {"v1": "1.0.0"}
8
- MODULES_TO_INSTRUMENT: list[str] = ["aignostics.platform", "aignostics.application"]
8
+ MODULES_TO_INSTRUMENT: list[str] = ["aignostics.qupath"]
9
9
  NOTEBOOK_DEFAULT = Path(__file__).parent / "notebook" / "_notebook.py"
10
10
 
11
11
  # Project specific configuration
@@ -1,11 +1,15 @@
1
1
  """Layout including sidebar and menu."""
2
2
 
3
3
  import contextlib
4
+ import platform
4
5
  from collections.abc import Generator
5
6
  from contextlib import contextmanager
6
7
  from importlib.util import find_spec
7
8
  from typing import Any
8
9
 
10
+ from humanize import naturaldelta
11
+ from nicegui import app, ui
12
+
9
13
  from aignostics.utils import __version__, open_user_data_directory
10
14
 
11
15
  from ._theme import theme
@@ -13,6 +17,7 @@ from ._theme import theme
13
17
  FLAT_COLOR_WHITE = "flat color=white"
14
18
 
15
19
  HEALTH_UPDATE_INTERVAL = 30
20
+ USERINFO_UPDATE_INTERVAL = 60
16
21
 
17
22
 
18
23
  @contextmanager
@@ -35,14 +40,61 @@ def frame( # noqa: C901, PLR0915
35
40
  Yields:
36
41
  Generator[Any, Any, Any]: The context manager for the page frame.
37
42
  """
38
- from nicegui import app, background_tasks, context, run, ui # noqa: PLC0415
43
+ from nicegui import background_tasks, context, run # noqa: PLC0415
39
44
 
45
+ from aignostics.platform import Service as PlatformService # noqa: PLC0415
46
+ from aignostics.platform import UserInfo # noqa: PLC0415
40
47
  from aignostics.system import Service as SystemService # noqa: PLC0415
41
48
 
42
49
  theme()
43
50
 
51
+ user_info: UserInfo | None = None
44
52
  launchpad_healthy: bool | None = None
45
53
 
54
+ @ui.refreshable
55
+ def _user_info_ui() -> None:
56
+ spinner = ui.spinner().props("flat color=purple-400")
57
+ if user_info and user_info.profile:
58
+ spinner.set_visibility(False)
59
+ icon = "img:" + user_info.profile.picture if user_info.profile.picture else "account_circle"
60
+ with (
61
+ ui.dropdown_button(icon=icon)
62
+ .style("width: 30px; height: 30px; border-radius: 50%")
63
+ .props(FLAT_COLOR_WHITE),
64
+ ui.card(),
65
+ ):
66
+ ui.label(f"{user_info.profile.name} ({user_info.profile.email})")
67
+ ui.label(f"Organisation: {user_info.org_name or user_info.org_id}")
68
+ ui.label(f"Role: {user_info.role}")
69
+ ui.label(f"Token Expiry: {naturaldelta(user_info.token.expires_in)}")
70
+ ui.separator()
71
+ with ui.row().classes("items-center justify-between"):
72
+ ui.button("Re-authenticate", icon="switch_account", on_click=_user_info_ui_relogin).props(
73
+ add="style=fab-mini"
74
+ )
75
+
76
+ async def _user_info_ui_load() -> None:
77
+ nonlocal user_info
78
+ with contextlib.suppress(Exception):
79
+ user_info = await run.cpu_bound(PlatformService.get_user_info)
80
+ await ui.context.client.connected()
81
+ app.storage.tab["user_info"] = user_info
82
+ _user_info_ui.refresh()
83
+
84
+ ui.timer(interval=USERINFO_UPDATE_INTERVAL, callback=_user_info_ui_load, immediate=True)
85
+
86
+ async def _user_info_ui_relogin() -> None:
87
+ """Relogin to the platform."""
88
+ nonlocal user_info
89
+ user_info = None
90
+ await ui.context.client.connected()
91
+ app.storage.tab["user_info"] = user_info
92
+ _user_info_ui.refresh()
93
+ with contextlib.suppress(Exception):
94
+ user_info = await run.cpu_bound(PlatformService.get_user_info, relogin=True)
95
+ app.storage.tab["user_info"] = user_info
96
+ _user_info_ui.refresh()
97
+
46
98
  @ui.refreshable
47
99
  def health_icon() -> None:
48
100
  if launchpad_healthy:
@@ -123,12 +175,12 @@ def frame( # noqa: C901, PLR0915
123
175
  icon="dark_mode",
124
176
  ).set_visibility(False)
125
177
 
126
- ui.button(icon="folder_special", on_click=lambda _: open_user_data_directory()).props("flat color=purple-400")
127
- ui.tooltip("Open data directory of Launchpad")
178
+ _user_info_ui()
128
179
 
129
- with ui.link(target="https://aignostics.readthedocs.org/", new_tab=True):
130
- ui.button(icon="local_library").props(FLAT_COLOR_WHITE)
131
- ui.tooltip("Open manual")
180
+ with ui.button(icon="folder_special", on_click=lambda _: open_user_data_directory()).props(
181
+ "flat color=purple-400"
182
+ ):
183
+ ui.tooltip("Open data directory of Launchpad")
132
184
 
133
185
  with ui.button(on_click=lambda _: right_drawer.toggle(), icon="menu").props(FLAT_COLOR_WHITE):
134
186
  ui.tooltip("Open menu")
@@ -140,7 +192,7 @@ def frame( # noqa: C901, PLR0915
140
192
  yield
141
193
 
142
194
  # Populate the right_drawer we created earlier
143
- with right_drawer, ui.column(align_items="stretch").classes("h-full"):
195
+ with right_drawer, ui.column(align_items="stretch").classes("h-full"): # noqa: PLR1702
144
196
  with ui.list():
145
197
  with ui.item(on_click=lambda _: ui.navigate.to("/")).props("clickable"):
146
198
  with ui.item_section().props("avatar"):
@@ -158,14 +210,15 @@ def frame( # noqa: C901, PLR0915
158
210
  )
159
211
  ui.space()
160
212
  with ui.list():
161
- if find_spec("ijson"):
162
- with ui.item(on_click=lambda _: ui.navigate.to("/qupath")).props("clickable"):
163
- with ui.item_section().props("avatar"):
164
- ui.icon("visibility", color="primary")
165
- with ui.item_section():
166
- ui.label("QuPath Extension").tailwind.font_weight(
167
- "bold" if context.client.page.path == "/qupath" else "normal"
168
- )
213
+ if find_spec("ijson"): # noqa: SIM102
214
+ if not (platform.system() == "Linux" and platform.machine() == "aarch64"):
215
+ with ui.item(on_click=lambda _: ui.navigate.to("/qupath")).props("clickable"):
216
+ with ui.item_section().props("avatar"):
217
+ ui.icon("visibility", color="primary")
218
+ with ui.item_section():
219
+ ui.label("QuPath Extension").tailwind.font_weight(
220
+ "bold" if context.client.page.path == "/qupath" else "normal"
221
+ )
169
222
  if find_spec("marimo"):
170
223
  with ui.item(on_click=lambda _: ui.navigate.to("/notebook")).props("clickable"):
171
224
  with ui.item_section().props("avatar"):
@@ -18,6 +18,7 @@ from aignx.codegen.models import OutputArtifactReadResponse as OutputArtifactDat
18
18
  from aignx.codegen.models import OutputArtifactResultReadResponse as OutputArtifactElement
19
19
  from aignx.codegen.models import RunReadResponse as ApplicationRunData
20
20
 
21
+ from ._cli import cli
21
22
  from ._client import Client
22
23
  from ._constants import (
23
24
  API_ROOT_DEV,
@@ -43,7 +44,7 @@ from ._constants import (
43
44
  TOKEN_URL_STAGING,
44
45
  )
45
46
  from ._messages import AUTHENTICATION_FAILED, NOT_YET_IMPLEMENTED, UNKNOWN_ENDPOINT_URL
46
- from ._service import Service
47
+ from ._service import Service, TokenInfo, UserInfo
47
48
  from ._settings import Settings, settings
48
49
  from ._utils import calculate_file_crc32c, download_file, generate_signed_url, mime_type_to_file_ending
49
50
  from .resources.runs import LIST_APPLICATION_RUNS_MAX_PAGE_SIZE, LIST_APPLICATION_RUNS_MIN_PAGE_SIZE, ApplicationRun
@@ -94,7 +95,10 @@ __all__ = [
94
95
  "OutputArtifactElement",
95
96
  "Service",
96
97
  "Settings",
98
+ "TokenInfo",
99
+ "UserInfo",
97
100
  "calculate_file_crc32c",
101
+ "cli",
98
102
  "download_file",
99
103
  "generate_signed_url",
100
104
  "mime_type_to_file_ending",