databricks-tellr-app 0.4.3.dev41__tar.gz → 0.4.3.dev43__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 (168) hide show
  1. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/PKG-INFO +1 -1
  2. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/databricks_tellr_app.egg-info/PKG-INFO +1 -1
  3. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/databricks_tellr_app.egg-info/SOURCES.txt +0 -2
  4. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/pyproject.toml +1 -1
  5. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/export.py +4 -0
  6. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/export_job_queue.py +3 -1
  7. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/design_system_service.py +0 -15
  8. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/image_service.py +31 -17
  9. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/image_tools.py +18 -1
  10. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/image_utils.py +27 -6
  11. databricks_tellr_app-0.4.3.dev41/src/services/svg_sanitizer.py +0 -403
  12. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/README.md +0 -0
  13. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/databricks_tellr_app/__init__.py +0 -0
  14. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/databricks_tellr_app/run.py +0 -0
  15. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
  16. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/databricks_tellr_app.egg-info/requires.txt +0 -0
  17. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/databricks_tellr_app.egg-info/top_level.txt +0 -0
  18. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/setup.cfg +0 -0
  19. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/setup.py +0 -0
  20. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/__init__.py +0 -0
  21. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/__init__.py +0 -0
  22. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/_otel_bootstrap.py +0 -0
  23. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/fixtures/tour_demo_deck.json +0 -0
  24. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/main.py +0 -0
  25. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/mcp_auth.py +0 -0
  26. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/mcp_server.py +0 -0
  27. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/middleware/__init__.py +0 -0
  28. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/middleware/csrf.py +0 -0
  29. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/middleware/request_logging.py +0 -0
  30. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/middleware/security_headers.py +0 -0
  31. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/__init__.py +0 -0
  32. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/_authz.py +0 -0
  33. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/admin.py +0 -0
  34. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/admin_usage.py +0 -0
  35. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/agent_config.py +0 -0
  36. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/chat.py +0 -0
  37. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/deck_contributors.py +0 -0
  38. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/feedback.py +0 -0
  39. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/google_slides.py +0 -0
  40. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/images.py +0 -0
  41. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/local_version.py +0 -0
  42. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/profiles.py +0 -0
  43. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/sessions.py +0 -0
  44. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/settings/__init__.py +0 -0
  45. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/settings/contributors.py +0 -0
  46. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/settings/deck_prompts.py +0 -0
  47. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/settings/design_systems.py +0 -0
  48. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/settings/identities.py +0 -0
  49. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/settings/slide_styles.py +0 -0
  50. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/setup.py +0 -0
  51. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/slides.py +0 -0
  52. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/tools.py +0 -0
  53. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/tour.py +0 -0
  54. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/verification.py +0 -0
  55. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/routes/version.py +0 -0
  56. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/__init__.py +0 -0
  57. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/agent_config.py +0 -0
  58. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/feedback.py +0 -0
  59. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/requests.py +0 -0
  60. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/responses.py +0 -0
  61. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/settings/__init__.py +0 -0
  62. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/settings/requests.py +0 -0
  63. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/settings/responses.py +0 -0
  64. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/schemas/streaming.py +0 -0
  65. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/__init__.py +0 -0
  66. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/chat_service.py +0 -0
  67. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/feedback_service.py +0 -0
  68. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/job_queue.py +0 -0
  69. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/session_manager.py +0 -0
  70. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/session_naming.py +0 -0
  71. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/usage_events.py +0 -0
  72. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/services/usage_service.py +0 -0
  73. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/utils/__init__.py +0 -0
  74. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/api/utils/validation.py +0 -0
  75. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/__init__.py +0 -0
  76. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/config_loader.py +0 -0
  77. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/context_utils.py +0 -0
  78. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/database.py +0 -0
  79. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/databricks_client.py +0 -0
  80. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/defaults.py +0 -0
  81. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/encryption.py +0 -0
  82. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/init_default_profile.py +0 -0
  83. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/lakebase.py +0 -0
  84. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/migrate_profiles_to_agent_config.py +0 -0
  85. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/mlflow_agent_spans.py +0 -0
  86. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/mlflow_tracing.py +0 -0
  87. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/otel_logging.py +0 -0
  88. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/permission_context.py +0 -0
  89. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/prompt_modules.py +0 -0
  90. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/settings_db.py +0 -0
  91. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/core/user_context.py +0 -0
  92. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/__init__.py +0 -0
  93. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/__init__.py +0 -0
  94. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/deck_contributor.py +0 -0
  95. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/design_system.py +0 -0
  96. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/encryption_key.py +0 -0
  97. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/feedback.py +0 -0
  98. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/genie_space.py +0 -0
  99. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/google_global_credentials.py +0 -0
  100. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/google_oauth_token.py +0 -0
  101. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/identity.py +0 -0
  102. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/image.py +0 -0
  103. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/profile.py +0 -0
  104. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/profile_contributor.py +0 -0
  105. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/prompts.py +0 -0
  106. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/request_log.py +0 -0
  107. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/session.py +0 -0
  108. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/slide_deck_prompt.py +0 -0
  109. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/slide_style_library.py +0 -0
  110. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/usage_event.py +0 -0
  111. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/models/user_preference.py +0 -0
  112. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/database/types.py +0 -0
  113. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/domain/__init__.py +0 -0
  114. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/domain/slide.py +0 -0
  115. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/domain/slide_deck.py +0 -0
  116. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/__init__.py +0 -0
  117. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/agent.py +0 -0
  118. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/agent_factory.py +0 -0
  119. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/config_service.py +0 -0
  120. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/config_validator.py +0 -0
  121. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/converter_jail/__init__.py +0 -0
  122. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/converter_jail/ast_guard.py +0 -0
  123. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/converter_jail/codeprep.py +0 -0
  124. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/converter_jail/gslides_runner.py +0 -0
  125. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/converter_jail/jail.py +0 -0
  126. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/converter_jail/pptx_runner.py +0 -0
  127. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/converter_jail/protocol.py +0 -0
  128. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/design_system_compiler.py +0 -0
  129. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/design_system_templates.py +0 -0
  130. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/drive_uploader.py +0 -0
  131. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/evaluation/__init__.py +0 -0
  132. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/evaluation/llm_judge.py +0 -0
  133. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/genie_service.py +0 -0
  134. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/google_slides_auth.py +0 -0
  135. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/google_slides_prompts_defaults.py +0 -0
  136. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/html_to_google_slides.py +0 -0
  137. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/html_to_pptx.py +0 -0
  138. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/identity_provider.py +0 -0
  139. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/identity_providers/__init__.py +0 -0
  140. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/identity_providers/account_provider.py +0 -0
  141. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/identity_providers/local_provider.py +0 -0
  142. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/identity_providers/workspace_provider.py +0 -0
  143. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/permission_service.py +0 -0
  144. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/pptx_from_html_huashu.py +0 -0
  145. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/pptx_from_records.py +0 -0
  146. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/pptx_prompts_defaults.py +0 -0
  147. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/profile_service.py +0 -0
  148. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/streaming_callback.py +0 -0
  149. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/tools/__init__.py +0 -0
  150. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/tools/agent_bricks_tool.py +0 -0
  151. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/tools/ds_asset_tool.py +0 -0
  152. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/tools/genie_tool.py +0 -0
  153. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/tools/mcp_tool.py +0 -0
  154. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/tools/model_endpoint_tool.py +0 -0
  155. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/tools/vector_tool.py +0 -0
  156. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/services/validator.py +0 -0
  157. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/__init__.py +0 -0
  158. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/css_utils.py +0 -0
  159. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/ds_asset_utils.py +0 -0
  160. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/error_handling.py +0 -0
  161. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/html_safety.py +0 -0
  162. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/html_utils.py +0 -0
  163. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/js_validator.py +0 -0
  164. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/logging_config.py +0 -0
  165. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/pi_filter.py +0 -0
  166. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/slide_hash.py +0 -0
  167. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/spotlight.py +0 -0
  168. {databricks_tellr_app-0.4.3.dev41 → databricks_tellr_app-0.4.3.dev43}/src/utils/text_caps.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks-tellr-app
3
- Version: 0.4.3.dev41
3
+ Version: 0.4.3.dev43
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks-tellr-app
3
- Version: 0.4.3.dev41
3
+ Version: 0.4.3.dev43
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -124,7 +124,6 @@ setup.py
124
124
  ./src/services/pptx_prompts_defaults.py
125
125
  ./src/services/profile_service.py
126
126
  ./src/services/streaming_callback.py
127
- ./src/services/svg_sanitizer.py
128
127
  ./src/services/validator.py
129
128
  ./src/services/converter_jail/__init__.py
130
129
  ./src/services/converter_jail/ast_guard.py
@@ -287,7 +286,6 @@ src/services/pptx_from_records.py
287
286
  src/services/pptx_prompts_defaults.py
288
287
  src/services/profile_service.py
289
288
  src/services/streaming_callback.py
290
- src/services/svg_sanitizer.py
291
289
  src/services/validator.py
292
290
  src/services/converter_jail/__init__.py
293
291
  src/services/converter_jail/ast_guard.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "databricks-tellr-app"
7
- version = "0.4.3.dev41"
7
+ version = "0.4.3.dev43"
8
8
  description = "Tellr application package for Databricks Apps"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -702,6 +702,7 @@ async def start_pptx_export_async(request: ExportPPTXRequest):
702
702
  enqueue_export_job,
703
703
  generate_job_id,
704
704
  )
705
+ from src.services.image_service import resolve_requesting_user
705
706
 
706
707
  import time
707
708
  start_time = time.time()
@@ -759,6 +760,9 @@ async def start_pptx_export_async(request: ExportPPTXRequest):
759
760
  job_id,
760
761
  {
761
762
  "session_id": request.session_id,
763
+ # Acting user for {{image:ID}} ownership checks (F-CR-27): the
764
+ # worker runs outside this request's user context.
765
+ "user_identity": resolve_requesting_user(),
762
766
  "chart_images_per_slide": chart_images_per_slide,
763
767
  "title": slide_deck.get("title", "slides"),
764
768
  "total_slides": total_slides,
@@ -212,7 +212,9 @@ async def process_export_job(job_id: str, payload: dict) -> None:
212
212
  from src.core.database import get_db_session
213
213
  ds_id = resolve_active_design_system_id(session_id)
214
214
  with get_db_session() as db:
215
- substitute_deck_dict_images(slide_deck, db)
215
+ substitute_deck_dict_images(
216
+ slide_deck, db, requesting_user=payload.get("user_identity")
217
+ )
216
218
  substitute_deck_dict_ds_assets(slide_deck, db, design_system_id=ds_id)
217
219
 
218
220
  slides = slide_deck.get("slides", [])
@@ -74,7 +74,6 @@ from src.database.models.design_system import (
74
74
  DesignSystemToken,
75
75
  )
76
76
  from src.services.design_system_compiler import recompute_compiled_style_content
77
- from src.services.svg_sanitizer import looks_like_svg, sanitize_svg
78
77
 
79
78
  logger = logging.getLogger(__name__)
80
79
 
@@ -2165,20 +2164,6 @@ def _collect_assets_and_files(
2165
2164
  mime = sniffed
2166
2165
  else:
2167
2166
  mime = _guess_mime(rel)
2168
- if mime == "image/svg+xml":
2169
- try:
2170
- data = sanitize_svg(data)
2171
- except ValueError as exc:
2172
- raise DesignSystemImportError(
2173
- f"Bundle entry '{rel}' is not a valid SVG: {exc}"
2174
- ) from exc
2175
- elif looks_like_svg(data):
2176
- # Extension says raster/font/etc. but the bytes are SVG:
2177
- # never trust the name to skip sanitization.
2178
- raise DesignSystemImportError(
2179
- f"Bundle entry '{rel}' contains SVG content but does not "
2180
- "have an .svg extension"
2181
- )
2182
2167
  width, height = _image_dimensions(data, mime)
2183
2168
  asset = DesignSystemAsset(
2184
2169
  kind=kind,
@@ -1,6 +1,7 @@
1
1
  """Image upload, thumbnail generation, and retrieval service."""
2
2
  import base64
3
3
  import logging
4
+ import os
4
5
  import uuid
5
6
  from io import BytesIO
6
7
  from typing import List, Optional
@@ -11,7 +12,6 @@ from sqlalchemy.dialects.postgresql import JSONB
11
12
  from sqlalchemy.orm import Query, Session
12
13
 
13
14
  from src.database.models.image import ImageAsset
14
- from src.services.svg_sanitizer import looks_like_svg, sanitize_svg
15
15
 
16
16
  logger = logging.getLogger(__name__)
17
17
 
@@ -42,20 +42,6 @@ def upload_image(
42
42
  if len(file_content) > MAX_FILE_SIZE:
43
43
  raise ValueError(f"File too large: {len(file_content)} bytes (max {MAX_FILE_SIZE})")
44
44
 
45
- # The client-declared MIME type is untrusted: decide on the CONTENT.
46
- # SVG can carry script, so it is always sanitized; SVG bytes declared as
47
- # any other type are rejected rather than stored under a raster label.
48
- if mime_type == "image/svg+xml":
49
- try:
50
- file_content = sanitize_svg(file_content)
51
- except ValueError as exc:
52
- raise ValueError(f"Invalid SVG upload: {exc}") from exc
53
- elif looks_like_svg(file_content):
54
- raise ValueError(
55
- f"File content is SVG but was declared as {mime_type}; "
56
- "upload it as image/svg+xml."
57
- )
58
-
59
45
  # Check for duplicate original_filename among active images (case-insensitive).
60
46
  # Ephemeral images (paste-to-chat) skip this check — they use throwaway names
61
47
  # and should never block each other.
@@ -101,10 +87,35 @@ def upload_image(
101
87
  return image
102
88
 
103
89
 
104
- def get_image_base64(db: Session, token: str) -> tuple[str, str]:
90
+ def resolve_requesting_user() -> Optional[str]:
91
+ """Identity to check image ownership against on non-route fetch paths.
92
+
93
+ Mirrors ``routes.images._get_current_user`` (the identity ``upload_image``
94
+ stamps into ``uploaded_by``) without an extra API call: the dev/test
95
+ ``"system"`` fallback, otherwise the request-scoped username set by the auth
96
+ middleware / MCP auth. ``None`` when no identity is bound (fail-closed for
97
+ ephemeral images).
98
+ """
99
+ if os.getenv("ENVIRONMENT") in ("development", "test"):
100
+ return "system"
101
+ from src.core.user_context import get_current_user
102
+
103
+ return get_current_user()
104
+
105
+
106
+ def get_image_base64(
107
+ db: Session, token: str, *, requesting_user: Optional[str]
108
+ ) -> tuple[str, str]:
105
109
  """
106
110
  Get full image as base64 string, keyed by the opaque token (SDR-4437 F-TM-7).
107
111
 
112
+ Applies the same privacy guard as the ``GET /api/images/{token}`` routes
113
+ (F-CR-27): chat-pasted ("ephemeral") images are private to their uploader,
114
+ so a token for another user's ephemeral image is reported not-found. Library
115
+ images stay open-read. ``requesting_user`` is mandatory and keyword-only so
116
+ every caller makes the acting identity explicit; ``None`` fails closed for
117
+ ephemeral images.
118
+
108
119
  Returns:
109
120
  Tuple of (base64_data, mime_type)
110
121
  """
@@ -112,7 +123,10 @@ def get_image_base64(db: Session, token: str) -> tuple[str, str]:
112
123
  ImageAsset.token == token,
113
124
  ImageAsset.is_active == True,
114
125
  ).first()
115
- if not image:
126
+ if not image or (
127
+ image.category == "ephemeral"
128
+ and (requesting_user is None or image.uploaded_by != requesting_user)
129
+ ):
116
130
  raise ValueError(f"Image {token} not found")
117
131
 
118
132
  b64 = base64.b64encode(image.image_data).decode("utf-8")
@@ -10,6 +10,8 @@ from src.services import image_service
10
10
 
11
11
  logger = logging.getLogger(__name__)
12
12
 
13
+ _NO_IMAGES_MESSAGE = "No images found matching your criteria."
14
+
13
15
 
14
16
  class SearchImagesInput(BaseModel):
15
17
  """Input schema for image search tool."""
@@ -41,12 +43,27 @@ def search_images(
41
43
  Returns:
42
44
  JSON list of matching images with id, filename, description, and tags
43
45
  """
46
+ # F-CR-27: chat-pasted ("ephemeral") images are private to their uploader and
47
+ # are never discoverable through the agent tool. The user's own pastes reach
48
+ # the agent via their message, not via search.
49
+ if category is not None and category.strip().lower() == "ephemeral":
50
+ logger.warning("search_images: refusing category='ephemeral' (private images)")
51
+ return json.dumps({"message": _NO_IMAGES_MESSAGE, "images": []})
52
+
53
+ # Scope the listing to the caller (same as GET /api/images). Fail closed when
54
+ # no identity is bound rather than listing every user's images.
55
+ requesting_user = image_service.resolve_requesting_user()
56
+ if requesting_user is None:
57
+ logger.warning("search_images: no requesting user bound; returning no images")
58
+ return json.dumps({"message": _NO_IMAGES_MESSAGE, "images": []})
59
+
44
60
  with get_db_session() as db:
45
61
  images = image_service.search_images(
46
62
  db=db,
47
63
  query=query,
48
64
  category=category,
49
65
  tags=tags,
66
+ uploaded_by=requesting_user,
50
67
  )
51
68
 
52
69
  # Return metadata only - NEVER base64
@@ -65,6 +82,6 @@ def search_images(
65
82
  ]
66
83
 
67
84
  if not results:
68
- return json.dumps({"message": "No images found matching your criteria.", "images": []})
85
+ return json.dumps({"message": _NO_IMAGES_MESSAGE, "images": []})
69
86
 
70
87
  return json.dumps({"message": f"Found {len(results)} image(s).", "images": results})
@@ -1,6 +1,7 @@
1
1
  """Image placeholder substitution for generated slides."""
2
2
  import logging
3
3
  import re
4
+ from typing import Optional
4
5
 
5
6
  from sqlalchemy.orm import Session
6
7
 
@@ -12,20 +13,31 @@ logger = logging.getLogger(__name__)
12
13
  IMAGE_PLACEHOLDER_PATTERN = re.compile(r"\{\{image:([A-Za-z0-9_-]+)\}\}")
13
14
 
14
15
 
15
- def substitute_image_placeholders(html: str, db: Session) -> str:
16
+ def substitute_image_placeholders(
17
+ html: str, db: Session, *, requesting_user: Optional[str] = None
18
+ ) -> str:
16
19
  """
17
20
  Replace {{image:ID}} placeholders with base64 data URIs.
18
21
 
19
22
  Called after agent generates HTML, before returning to frontend.
20
23
  Works in both HTML img src and CSS url() contexts.
24
+
25
+ Resolution is scoped to the acting user (F-CR-27): another user's ephemeral
26
+ image is left as an unresolved placeholder. ``requesting_user`` defaults to
27
+ the request-scoped identity (``image_service.resolve_requesting_user``);
28
+ background callers without a request context must pass it explicitly.
21
29
  """
22
30
  if not html or "{{image:" not in html:
23
31
  return html
32
+ if requesting_user is None:
33
+ requesting_user = image_service.resolve_requesting_user()
24
34
 
25
35
  def replace_match(match):
26
36
  image_token = match.group(1)
27
37
  try:
28
- b64_data, mime_type = image_service.get_image_base64(db, image_token)
38
+ b64_data, mime_type = image_service.get_image_base64(
39
+ db, image_token, requesting_user=requesting_user
40
+ )
29
41
  return f"data:{mime_type};base64,{b64_data}"
30
42
  except Exception as e:
31
43
  logger.warning(f"Failed to resolve image placeholder {{{{image:{image_token}}}}}: {e}")
@@ -41,23 +53,32 @@ def substitute_image_placeholders(html: str, db: Session) -> str:
41
53
  _DECK_IMAGE_FIELDS = ("html_content", "css")
42
54
 
43
55
 
44
- def substitute_deck_dict_images(deck_dict: dict, db: Session) -> dict:
56
+ def substitute_deck_dict_images(
57
+ deck_dict: dict, db: Session, *, requesting_user: Optional[str] = None
58
+ ) -> dict:
45
59
  """Substitute {{image:ID}} placeholders across a deck dict.
46
60
 
47
61
  Covers every field that can carry the placeholder: each slide's ``html``,
48
62
  the deck's ``html_content`` (full knitted HTML) and its top-level ``css``
49
63
  (backgrounds). Deck-level fields are resolved independently of the slides
50
64
  array, mirroring ``substitute_deck_dict_ds_assets`` — the css gap fixed
51
- there existed here too.
65
+ there existed here too. ``requesting_user`` is as for
66
+ ``substitute_image_placeholders``.
52
67
  """
53
68
  if not deck_dict:
54
69
  return deck_dict
70
+ if requesting_user is None:
71
+ requesting_user = image_service.resolve_requesting_user()
55
72
  for slide in deck_dict.get("slides") or []:
56
73
  html = slide.get("html", "")
57
74
  if "{{image:" in html:
58
- slide["html"] = substitute_image_placeholders(html, db)
75
+ slide["html"] = substitute_image_placeholders(
76
+ html, db, requesting_user=requesting_user
77
+ )
59
78
  for field in _DECK_IMAGE_FIELDS:
60
79
  value = deck_dict.get(field)
61
80
  if value and "{{image:" in value:
62
- deck_dict[field] = substitute_image_placeholders(value, db)
81
+ deck_dict[field] = substitute_image_placeholders(
82
+ value, db, requesting_user=requesting_user
83
+ )
63
84
  return deck_dict