databricks-tellr-app 0.4.3.dev3__tar.gz → 0.4.3.dev4__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 (167) hide show
  1. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/PKG-INFO +1 -1
  2. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/databricks_tellr_app.egg-info/PKG-INFO +1 -1
  3. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/pyproject.toml +1 -1
  4. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/google_slides.py +94 -47
  5. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/README.md +0 -0
  6. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/databricks_tellr_app/__init__.py +0 -0
  7. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/databricks_tellr_app/run.py +0 -0
  8. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/databricks_tellr_app.egg-info/SOURCES.txt +0 -0
  9. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
  10. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/databricks_tellr_app.egg-info/requires.txt +0 -0
  11. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/databricks_tellr_app.egg-info/top_level.txt +0 -0
  12. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/setup.cfg +0 -0
  13. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/setup.py +0 -0
  14. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/__init__.py +0 -0
  15. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/__init__.py +0 -0
  16. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/_otel_bootstrap.py +0 -0
  17. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/fixtures/tour_demo_deck.json +0 -0
  18. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/main.py +0 -0
  19. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/mcp_auth.py +0 -0
  20. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/mcp_server.py +0 -0
  21. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/middleware/__init__.py +0 -0
  22. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/middleware/csrf.py +0 -0
  23. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/middleware/request_logging.py +0 -0
  24. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/middleware/security_headers.py +0 -0
  25. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/__init__.py +0 -0
  26. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/_authz.py +0 -0
  27. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/admin.py +0 -0
  28. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/admin_usage.py +0 -0
  29. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/agent_config.py +0 -0
  30. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/chat.py +0 -0
  31. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/deck_contributors.py +0 -0
  32. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/export.py +0 -0
  33. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/feedback.py +0 -0
  34. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/images.py +0 -0
  35. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/local_version.py +0 -0
  36. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/profiles.py +0 -0
  37. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/sessions.py +0 -0
  38. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/settings/__init__.py +0 -0
  39. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/settings/contributors.py +0 -0
  40. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/settings/deck_prompts.py +0 -0
  41. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/settings/design_systems.py +0 -0
  42. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/settings/identities.py +0 -0
  43. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/settings/slide_styles.py +0 -0
  44. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/setup.py +0 -0
  45. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/slides.py +0 -0
  46. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/tools.py +0 -0
  47. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/tour.py +0 -0
  48. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/verification.py +0 -0
  49. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/routes/version.py +0 -0
  50. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/__init__.py +0 -0
  51. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/agent_config.py +0 -0
  52. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/feedback.py +0 -0
  53. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/requests.py +0 -0
  54. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/responses.py +0 -0
  55. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/settings/__init__.py +0 -0
  56. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/settings/requests.py +0 -0
  57. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/settings/responses.py +0 -0
  58. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/schemas/streaming.py +0 -0
  59. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/__init__.py +0 -0
  60. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/chat_service.py +0 -0
  61. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/export_job_queue.py +0 -0
  62. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/feedback_service.py +0 -0
  63. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/job_queue.py +0 -0
  64. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/session_manager.py +0 -0
  65. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/session_naming.py +0 -0
  66. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/usage_events.py +0 -0
  67. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/services/usage_service.py +0 -0
  68. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/utils/__init__.py +0 -0
  69. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/api/utils/validation.py +0 -0
  70. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/__init__.py +0 -0
  71. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/config_loader.py +0 -0
  72. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/context_utils.py +0 -0
  73. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/database.py +0 -0
  74. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/databricks_client.py +0 -0
  75. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/defaults.py +0 -0
  76. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/encryption.py +0 -0
  77. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/init_default_profile.py +0 -0
  78. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/lakebase.py +0 -0
  79. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/migrate_profiles_to_agent_config.py +0 -0
  80. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/mlflow_agent_spans.py +0 -0
  81. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/mlflow_tracing.py +0 -0
  82. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/otel_logging.py +0 -0
  83. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/permission_context.py +0 -0
  84. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/prompt_modules.py +0 -0
  85. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/settings_db.py +0 -0
  86. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/core/user_context.py +0 -0
  87. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/__init__.py +0 -0
  88. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/__init__.py +0 -0
  89. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/deck_contributor.py +0 -0
  90. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/design_system.py +0 -0
  91. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/encryption_key.py +0 -0
  92. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/feedback.py +0 -0
  93. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/genie_space.py +0 -0
  94. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/google_global_credentials.py +0 -0
  95. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/google_oauth_token.py +0 -0
  96. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/identity.py +0 -0
  97. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/image.py +0 -0
  98. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/profile.py +0 -0
  99. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/profile_contributor.py +0 -0
  100. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/prompts.py +0 -0
  101. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/request_log.py +0 -0
  102. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/session.py +0 -0
  103. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/slide_deck_prompt.py +0 -0
  104. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/slide_style_library.py +0 -0
  105. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/usage_event.py +0 -0
  106. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/models/user_preference.py +0 -0
  107. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/database/types.py +0 -0
  108. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/domain/__init__.py +0 -0
  109. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/domain/slide.py +0 -0
  110. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/domain/slide_deck.py +0 -0
  111. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/__init__.py +0 -0
  112. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/agent.py +0 -0
  113. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/agent_factory.py +0 -0
  114. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/config_service.py +0 -0
  115. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/config_validator.py +0 -0
  116. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/converter_jail/__init__.py +0 -0
  117. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/converter_jail/ast_guard.py +0 -0
  118. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/converter_jail/codeprep.py +0 -0
  119. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/converter_jail/gslides_runner.py +0 -0
  120. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/converter_jail/jail.py +0 -0
  121. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/converter_jail/pptx_runner.py +0 -0
  122. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/converter_jail/protocol.py +0 -0
  123. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/design_system_compiler.py +0 -0
  124. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/design_system_service.py +0 -0
  125. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/design_system_templates.py +0 -0
  126. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/drive_uploader.py +0 -0
  127. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/evaluation/__init__.py +0 -0
  128. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/evaluation/llm_judge.py +0 -0
  129. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/genie_service.py +0 -0
  130. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/google_slides_auth.py +0 -0
  131. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/google_slides_prompts_defaults.py +0 -0
  132. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/html_to_google_slides.py +0 -0
  133. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/html_to_pptx.py +0 -0
  134. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/identity_provider.py +0 -0
  135. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/identity_providers/__init__.py +0 -0
  136. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/identity_providers/account_provider.py +0 -0
  137. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/identity_providers/local_provider.py +0 -0
  138. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/identity_providers/workspace_provider.py +0 -0
  139. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/image_service.py +0 -0
  140. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/image_tools.py +0 -0
  141. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/permission_service.py +0 -0
  142. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/pptx_from_html_huashu.py +0 -0
  143. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/pptx_from_records.py +0 -0
  144. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/pptx_prompts_defaults.py +0 -0
  145. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/profile_service.py +0 -0
  146. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/streaming_callback.py +0 -0
  147. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/tools/__init__.py +0 -0
  148. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/tools/agent_bricks_tool.py +0 -0
  149. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/tools/ds_asset_tool.py +0 -0
  150. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/tools/genie_tool.py +0 -0
  151. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/tools/mcp_tool.py +0 -0
  152. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/tools/model_endpoint_tool.py +0 -0
  153. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/tools/vector_tool.py +0 -0
  154. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/services/validator.py +0 -0
  155. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/__init__.py +0 -0
  156. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/css_utils.py +0 -0
  157. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/ds_asset_utils.py +0 -0
  158. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/error_handling.py +0 -0
  159. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/html_safety.py +0 -0
  160. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/html_utils.py +0 -0
  161. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/image_utils.py +0 -0
  162. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/js_validator.py +0 -0
  163. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/logging_config.py +0 -0
  164. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/pi_filter.py +0 -0
  165. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/slide_hash.py +0 -0
  166. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/src/utils/spotlight.py +0 -0
  167. {databricks_tellr_app-0.4.3.dev3 → databricks_tellr_app-0.4.3.dev4}/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.dev3
3
+ Version: 0.4.3.dev4
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.dev3
3
+ Version: 0.4.3.dev4
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -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.dev3"
7
+ version = "0.4.3.dev4"
8
8
  description = "Tellr application package for Databricks Apps"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -10,9 +10,10 @@ user tokens are stored per-user in the ``google_oauth_tokens`` table.
10
10
  import json
11
11
  import logging
12
12
  import os
13
+ import secrets
13
14
  from typing import Any, Optional
14
15
 
15
- from fastapi import APIRouter, Depends, HTTPException, Query, Request
16
+ from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response
16
17
  from fastapi.responses import HTMLResponse
17
18
  from pydantic import BaseModel
18
19
  from sqlalchemy.orm import Session
@@ -33,6 +34,12 @@ logger = logging.getLogger(__name__)
33
34
 
34
35
  router = APIRouter(prefix="/api/export/google-slides", tags=["google-slides"])
35
36
 
37
+ # F-CR-3 (SDR-4437): the OAuth "state" carries an unguessable nonce that is also
38
+ # stored in this short-lived cookie; the callback requires them to match before
39
+ # exchanging the authorization code (anti-CSRF / anti-login-CSRF double-submit).
40
+ _OAUTH_STATE_COOKIE = "g_oauth_state"
41
+ _OAUTH_COOKIE_PATH = "/api/export/google-slides"
42
+
36
43
 
37
44
  # -------------------------------------------------------------------------
38
45
  # Helpers
@@ -98,32 +105,76 @@ class AuthUrlResponse(BaseModel):
98
105
  # -------------------------------------------------------------------------
99
106
 
100
107
 
101
- def _build_redirect_uri(request: Request) -> str:
102
- """Build the OAuth callback redirect URI from the current request.
103
-
104
- Google requires redirect URIs to match *exactly* what's registered in GCP,
105
- with no query parameters.
108
+ def _build_app_origin(request: Request) -> str:
109
+ """Return the public origin (``scheme://host``) serving the app.
106
110
 
107
111
  Behind a reverse proxy (e.g. Databricks Apps), ``request.base_url``
108
112
  returns the internal address (``http://localhost:8000``). We use the
109
113
  ``X-Forwarded-Host`` / ``X-Forwarded-Proto`` headers set by the proxy
110
- to reconstruct the public URL instead.
111
-
112
- For localhost, Google only allows ``http``.
114
+ to reconstruct the public URL instead. For localhost, force ``http``.
113
115
  """
114
116
  forwarded_host = request.headers.get("x-forwarded-host")
115
117
  forwarded_proto = request.headers.get("x-forwarded-proto")
116
118
 
117
119
  if forwarded_host:
118
120
  scheme = forwarded_proto or "https"
119
- base = f"{scheme}://{forwarded_host.split(',')[0].strip()}"
120
- else:
121
- base = str(request.base_url).rstrip("/")
122
- # Force http for localhost (Google rejects https://localhost)
123
- if "://localhost" in base or "://127.0.0.1" in base:
124
- base = base.replace("https://", "http://")
121
+ return f"{scheme}://{forwarded_host.split(',')[0].strip()}"
125
122
 
126
- return f"{base}/api/export/google-slides/auth/callback"
123
+ base = str(request.base_url).rstrip("/")
124
+ if "://localhost" in base or "://127.0.0.1" in base:
125
+ base = base.replace("https://", "http://")
126
+ return base
127
+
128
+
129
+ def _build_redirect_uri(request: Request) -> str:
130
+ """Build the OAuth callback redirect URI from the current request.
131
+
132
+ Google requires redirect URIs to match *exactly* what's registered in GCP,
133
+ with no query parameters.
134
+ """
135
+ return f"{_build_app_origin(request)}/api/export/google-slides/auth/callback"
136
+
137
+
138
+ # Callback page template. The JS object braces are intentionally literal; the
139
+ # %TOKENS% are substituted below so the postMessage targets the explicit app
140
+ # origin (F-CR-3) instead of the wildcard '*'.
141
+ _CALLBACK_TEMPLATE = """
142
+ <html><body>
143
+ <h2>%TITLE%</h2>
144
+ <p>%MESSAGE%</p>
145
+ <script>
146
+ if (window.opener) {
147
+ window.opener.postMessage({ type: 'google-slides-auth', success: %SUCCESS% }, %ORIGIN%);
148
+ }
149
+ setTimeout(() => window.close(), %DELAY%);
150
+ </script>
151
+ </body></html>
152
+ """
153
+
154
+
155
+ def _callback_response(app_origin: str, *, success: bool) -> HTMLResponse:
156
+ """Render the popup callback page and clear the anti-CSRF state cookie.
157
+
158
+ ``postMessage`` targets ``app_origin`` explicitly (F-CR-3); ``json.dumps``
159
+ yields a safely-quoted JS string literal for the origin.
160
+ """
161
+ if success:
162
+ title, message, delay = "Authorization Successful", "You can close this window.", "1500"
163
+ else:
164
+ title = "Authorization Failed"
165
+ message = "Authorization could not be completed. Please close this window and try again."
166
+ delay = "3000"
167
+ body = (
168
+ _CALLBACK_TEMPLATE
169
+ .replace("%TITLE%", title)
170
+ .replace("%MESSAGE%", message)
171
+ .replace("%SUCCESS%", "true" if success else "false")
172
+ .replace("%ORIGIN%", json.dumps(app_origin))
173
+ .replace("%DELAY%", delay)
174
+ )
175
+ resp = HTMLResponse(content=body, status_code=200)
176
+ resp.delete_cookie(_OAUTH_STATE_COOKIE, path=_OAUTH_COOKIE_PATH)
177
+ return resp
127
178
 
128
179
 
129
180
  @router.get("/auth/status", response_model=AuthStatusResponse)
@@ -141,6 +192,7 @@ async def auth_status(db: Session = Depends(get_db)):
141
192
  @router.get("/auth/url", response_model=AuthUrlResponse)
142
193
  async def auth_url(
143
194
  request: Request,
195
+ response: Response,
144
196
  db: Session = Depends(get_db),
145
197
  ):
146
198
  """Generate the Google OAuth consent URL.
@@ -149,13 +201,26 @@ async def auth_url(
149
201
  passed via the OAuth ``state`` parameter so the callback can persist the
150
202
  token for the correct user — the redirect URI itself stays clean
151
203
  (no query params) to satisfy Google's exact-match requirement.
204
+
205
+ F-CR-3: an unguessable nonce is bound into both the ``state`` and a
206
+ short-lived cookie; the callback requires them to match.
152
207
  """
153
208
  try:
154
209
  auth = _get_auth(db)
155
210
  redirect_uri = _build_redirect_uri(request)
156
- state = json.dumps({"user": _get_user_identity()})
211
+ nonce = secrets.token_urlsafe(32)
212
+ state = json.dumps({"user": _get_user_identity(), "nonce": nonce})
157
213
  url = auth.get_auth_url(redirect_uri=redirect_uri, state=state)
158
214
 
215
+ response.set_cookie(
216
+ key=_OAUTH_STATE_COOKIE,
217
+ value=nonce,
218
+ max_age=600,
219
+ httponly=True,
220
+ secure=True,
221
+ samesite="lax", # sent on Google's top-level redirect back to us
222
+ path=_OAUTH_COOKIE_PATH,
223
+ )
159
224
  return AuthUrlResponse(url=url)
160
225
  except GoogleSlidesAuthError as exc:
161
226
  raise HTTPException(status_code=400, detail=str(exc)) from exc
@@ -184,12 +249,22 @@ async def auth_callback(
184
249
  them in the ``google_oauth_tokens`` table. Returns a small HTML page
185
250
  that notifies the opener window and closes itself.
186
251
  """
252
+ app_origin = _build_app_origin(request)
253
+ cookie_nonce = request.cookies.get(_OAUTH_STATE_COOKIE)
187
254
  try:
188
255
  state_data = json.loads(state) if state else {}
189
256
  user = state_data.get("user")
190
257
  if not user:
191
258
  raise ValueError("Missing user in OAuth state")
192
259
 
260
+ # F-CR-3: verify the anti-CSRF nonce BEFORE exchanging the code. The
261
+ # state nonce must match the cookie set when the auth URL was issued.
262
+ state_nonce = state_data.get("nonce")
263
+ if not cookie_nonce or not state_nonce or not secrets.compare_digest(
264
+ str(cookie_nonce), str(state_nonce)
265
+ ):
266
+ raise ValueError("OAuth state nonce mismatch")
267
+
193
268
  auth = _get_auth(db)
194
269
  redirect_uri = _build_redirect_uri(request)
195
270
  code_verifier = state_data.get("code_verifier")
@@ -202,37 +277,9 @@ async def auth_callback(
202
277
  # F-CR-2 (SDR-4437): never reflect the raw exception into the HTML page —
203
278
  # it is logged server-side above. Show a static, generic failure message.
204
279
  logger.error("OAuth callback failed", exc_info=True)
205
- return HTMLResponse(
206
- content="""
207
- <html><body>
208
- <h2>Authorization Failed</h2>
209
- <p>Authorization could not be completed. Please close this window and try again.</p>
210
- <script>
211
- if (window.opener) {
212
- window.opener.postMessage({ type: 'google-slides-auth', success: false }, '*');
213
- }
214
- setTimeout(() => window.close(), 3000);
215
- </script>
216
- </body></html>
217
- """,
218
- status_code=200,
219
- )
280
+ return _callback_response(app_origin, success=False)
220
281
 
221
- return HTMLResponse(
222
- content="""
223
- <html><body>
224
- <h2>Authorization Successful</h2>
225
- <p>You can close this window.</p>
226
- <script>
227
- if (window.opener) {
228
- window.opener.postMessage({ type: 'google-slides-auth', success: true }, '*');
229
- }
230
- setTimeout(() => window.close(), 1500);
231
- </script>
232
- </body></html>
233
- """,
234
- status_code=200,
235
- )
282
+ return _callback_response(app_origin, success=True)
236
283
 
237
284
 
238
285
  # -------------------------------------------------------------------------