databricks-tellr-app 0.4.2.dev10__tar.gz → 0.4.2.dev11__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.
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/PKG-INFO +1 -1
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/databricks_tellr_app.egg-info/PKG-INFO +1 -1
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/pyproject.toml +1 -1
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/settings/design_systems.py +37 -2
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/design_system_service.py +160 -45
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/design_system_templates.py +10 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/README.md +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/databricks_tellr_app/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/databricks_tellr_app/run.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/databricks_tellr_app.egg-info/SOURCES.txt +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/databricks_tellr_app.egg-info/requires.txt +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/databricks_tellr_app.egg-info/top_level.txt +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/setup.cfg +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/setup.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/_otel_bootstrap.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/fixtures/tour_demo_deck.json +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/main.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/mcp_auth.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/mcp_server.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/middleware/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/middleware/csrf.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/middleware/request_logging.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/middleware/security_headers.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/_authz.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/admin.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/admin_usage.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/agent_config.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/chat.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/deck_contributors.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/export.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/feedback.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/google_slides.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/images.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/local_version.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/profiles.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/sessions.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/settings/contributors.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/settings/deck_prompts.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/settings/identities.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/settings/slide_styles.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/setup.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/slides.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/tools.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/tour.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/verification.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/version.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/agent_config.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/feedback.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/requests.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/responses.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/settings/requests.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/settings/responses.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/streaming.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/chat_service.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/export_job_queue.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/feedback_service.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/job_queue.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/session_manager.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/session_naming.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/usage_events.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/usage_service.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/utils/validation.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/config_loader.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/context_utils.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/database.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/databricks_client.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/defaults.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/encryption.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/init_default_profile.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/lakebase.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/migrate_profiles_to_agent_config.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/mlflow_agent_spans.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/mlflow_tracing.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/otel_logging.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/permission_context.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/prompt_modules.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/settings_db.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/user_context.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/deck_contributor.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/design_system.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/encryption_key.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/feedback.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/genie_space.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/google_global_credentials.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/google_oauth_token.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/identity.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/image.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/profile.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/profile_contributor.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/prompts.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/request_log.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/session.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/slide_deck_prompt.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/slide_style_library.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/usage_event.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/user_preference.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/types.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/domain/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/domain/slide.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/domain/slide_deck.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/agent.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/agent_factory.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/config_service.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/config_validator.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/converter_jail/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/converter_jail/ast_guard.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/converter_jail/codeprep.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/converter_jail/gslides_runner.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/converter_jail/jail.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/converter_jail/pptx_runner.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/converter_jail/protocol.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/design_system_compiler.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/drive_uploader.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/evaluation/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/evaluation/llm_judge.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/genie_service.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/google_slides_auth.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/google_slides_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/html_to_google_slides.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/html_to_pptx.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/identity_provider.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/identity_providers/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/identity_providers/account_provider.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/identity_providers/local_provider.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/identity_providers/workspace_provider.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/image_service.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/image_tools.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/permission_service.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/pptx_from_html_huashu.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/pptx_from_records.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/pptx_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/profile_service.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/streaming_callback.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/agent_bricks_tool.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/ds_asset_tool.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/genie_tool.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/mcp_tool.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/model_endpoint_tool.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/vector_tool.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/validator.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/css_utils.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/ds_asset_utils.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/error_handling.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/html_safety.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/html_utils.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/image_utils.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/js_validator.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/logging_config.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/pi_filter.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/slide_hash.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/spotlight.py +0 -0
- {databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/text_caps.py +0 -0
|
@@ -172,6 +172,28 @@ class DesignSystemDetail(DesignSystemSummary):
|
|
|
172
172
|
assets: List[AssetOut]
|
|
173
173
|
|
|
174
174
|
|
|
175
|
+
class ImportWarningOut(BaseModel):
|
|
176
|
+
"""One bundle entry the import ignored, and why."""
|
|
177
|
+
path: str
|
|
178
|
+
reason: str
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class DesignSystemImportResult(DesignSystemDetail):
|
|
182
|
+
"""The /import response: the imported detail PLUS anything that was ignored.
|
|
183
|
+
|
|
184
|
+
Additive by design. Some entries are individually unusable without making the
|
|
185
|
+
bundle unusable (an unsniffable template screenshot, a non-UTF-8 token source);
|
|
186
|
+
those are dropped so one junk file cannot cost the whole upload. Reporting them
|
|
187
|
+
only to the server log told the user the import had succeeded and left them to
|
|
188
|
+
discover a missing thumbnail themselves.
|
|
189
|
+
|
|
190
|
+
A NON-FATAL list on a 201, and its own model rather than a field on
|
|
191
|
+
:class:`DesignSystemDetail`, so the GET/create/update responses are byte-for-byte
|
|
192
|
+
unchanged and an existing /import client simply ignores a field it does not read.
|
|
193
|
+
"""
|
|
194
|
+
warnings: List[ImportWarningOut] = []
|
|
195
|
+
|
|
196
|
+
|
|
175
197
|
class DesignSystemCreate(BaseModel):
|
|
176
198
|
"""Structured (in-app) create — thin. Assets arrive via /import."""
|
|
177
199
|
# UNCAPPED, matching the unbounded ``design_system.name`` column; ``min_length``
|
|
@@ -496,7 +518,11 @@ def list_design_systems(
|
|
|
496
518
|
)
|
|
497
519
|
|
|
498
520
|
|
|
499
|
-
@router.post(
|
|
521
|
+
@router.post(
|
|
522
|
+
"/import",
|
|
523
|
+
response_model=DesignSystemImportResult,
|
|
524
|
+
status_code=status.HTTP_201_CREATED,
|
|
525
|
+
)
|
|
500
526
|
async def import_design_system(
|
|
501
527
|
file: UploadFile = File(...),
|
|
502
528
|
name: Optional[str] = Form(None),
|
|
@@ -517,14 +543,23 @@ async def import_design_system(
|
|
|
517
543
|
detail=f"Upload exceeds the maximum bundle size of {MAX_BUNDLE_SIZE_BYTES} bytes",
|
|
518
544
|
)
|
|
519
545
|
try:
|
|
546
|
+
# Filled with the entries the import dropped without failing, so the caller
|
|
547
|
+
# learns about them instead of only the server log doing so.
|
|
548
|
+
dropped: list[design_system_service.BundleImportWarning] = []
|
|
520
549
|
ds = design_system_service.import_bundle(
|
|
521
550
|
db,
|
|
522
551
|
zip_bytes=content,
|
|
523
552
|
user=_current_user(),
|
|
524
553
|
name_override=name,
|
|
525
554
|
source_filename=file.filename,
|
|
555
|
+
warnings=dropped,
|
|
556
|
+
)
|
|
557
|
+
return DesignSystemImportResult(
|
|
558
|
+
**_detail(ds).model_dump(),
|
|
559
|
+
warnings=[
|
|
560
|
+
ImportWarningOut(path=w.path, reason=w.reason) for w in dropped
|
|
561
|
+
],
|
|
526
562
|
)
|
|
527
|
-
return _detail(ds)
|
|
528
563
|
except DesignSystemNameConflictError as e:
|
|
529
564
|
db.rollback()
|
|
530
565
|
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(e))
|
|
@@ -59,7 +59,7 @@ import logging
|
|
|
59
59
|
import mimetypes
|
|
60
60
|
import re
|
|
61
61
|
import zipfile
|
|
62
|
-
from typing import Any, Optional
|
|
62
|
+
from typing import Any, NamedTuple, Optional
|
|
63
63
|
|
|
64
64
|
from sqlalchemy.orm import Session, defer
|
|
65
65
|
|
|
@@ -78,6 +78,22 @@ logger = logging.getLogger(__name__)
|
|
|
78
78
|
MANIFEST_FILENAME = "_ds_manifest.json"
|
|
79
79
|
DEFAULT_CSS_TOKEN_SOURCE = "colors_and_type.css"
|
|
80
80
|
|
|
81
|
+
|
|
82
|
+
class BundleImportWarning(NamedTuple):
|
|
83
|
+
"""A bundle entry the import DROPPED without failing the upload.
|
|
84
|
+
|
|
85
|
+
Some entries are individually unusable without making the bundle unusable — an
|
|
86
|
+
unsniffable template screenshot, a CSS token source that is not UTF-8. Dropping
|
|
87
|
+
just that entry is right (one junk file must not cost the whole upload), but the
|
|
88
|
+
caller was then told the import succeeded with nothing to say a file had been
|
|
89
|
+
ignored, so the only record was a server-side log the user cannot see. These ride
|
|
90
|
+
back on the import response instead.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
path: str
|
|
94
|
+
reason: str
|
|
95
|
+
|
|
96
|
+
|
|
81
97
|
# Color sub-groups the compiler renders as :root vars. A token name whose first
|
|
82
98
|
# segment is one of these carries its group in the name (e.g. --brand-accents-lava).
|
|
83
99
|
_COLOR_SUBGROUPS = frozenset(("core", "accents", "ink", "tints"))
|
|
@@ -280,8 +296,14 @@ def _infer_asset_kind(rel_path: str) -> str:
|
|
|
280
296
|
# raster-image extension) — stored as a ``template_shot`` asset so the Phase 4
|
|
281
297
|
# template picker can serve thumbnails. Checked BEFORE ``_should_skip`` (which
|
|
282
298
|
# excludes ``templates/**`` from generic asset storage).
|
|
299
|
+
#
|
|
300
|
+
# Anchored with ``\Z``, NOT ``$``: in Python ``$`` matches at the end of the string
|
|
301
|
+
# OR immediately before a single trailing newline, so a ``$``-anchored allowlist on
|
|
302
|
+
# a PATH accepts ``<allowed shape>\n`` — ``templates/x/preview.png\n`` was matched,
|
|
303
|
+
# stored, and served. ``\Z`` is the true end of string. Applies to every allowlist
|
|
304
|
+
# regex in this module that judges a path or a filename.
|
|
283
305
|
_TEMPLATE_PREVIEW_RE = re.compile(
|
|
284
|
-
r"^templates/[^/]+/preview[^/]*\.(png|jpe?g|gif|webp)
|
|
306
|
+
r"^templates/[^/]+/preview[^/]*\.(png|jpe?g|gif|webp)\Z", re.IGNORECASE
|
|
285
307
|
)
|
|
286
308
|
|
|
287
309
|
# The SAME screenshot as it actually ships in a real export: DOT-PREFIXED, named
|
|
@@ -296,8 +318,11 @@ _TEMPLATE_PREVIEW_RE = re.compile(
|
|
|
296
318
|
# from the general dotfile skip; a dotfile anywhere else stays skipped. Because
|
|
297
319
|
# a match carries no extension, its media type is NOT guessable from the name and
|
|
298
320
|
# is sniffed from the content instead (:func:`_sniff_raster_mime`).
|
|
321
|
+
# ``\Z`` for the same reason as _TEMPLATE_PREVIEW_RE: with ``$`` this accepted
|
|
322
|
+
# ``templates/x/.thumbnail\n``, which was then stored AND linked as a template's
|
|
323
|
+
# thumbnail_url.
|
|
299
324
|
_TEMPLATE_THUMBNAIL_RE = re.compile(
|
|
300
|
-
r"^templates/[^/]+/\.?(thumbnail|preview)
|
|
325
|
+
r"^templates/[^/]+/\.?(thumbnail|preview)\Z", re.IGNORECASE
|
|
301
326
|
)
|
|
302
327
|
|
|
303
328
|
# Magic-byte signatures for the raster formats a template thumbnail may be. An
|
|
@@ -563,12 +588,20 @@ def import_bundle(
|
|
|
563
588
|
user: Optional[str],
|
|
564
589
|
name_override: Optional[str] = None,
|
|
565
590
|
source_filename: Optional[str] = None,
|
|
591
|
+
warnings: Optional[list[BundleImportWarning]] = None,
|
|
566
592
|
) -> DesignSystem:
|
|
567
593
|
"""Import a ``.zip`` design-system bundle into Lakebase and compile it.
|
|
568
594
|
|
|
569
595
|
Returns the persisted :class:`DesignSystem` (committed, with tokens + assets +
|
|
570
596
|
``compiled_style_content``).
|
|
571
597
|
|
|
598
|
+
Args:
|
|
599
|
+
warnings: optional collector. Pass a list to receive an
|
|
600
|
+
:class:`BundleImportWarning` for every entry the import DROPPED without
|
|
601
|
+
failing — the caller can then tell the user which files were ignored and
|
|
602
|
+
why. Omitting it keeps the previous signature working for the many
|
|
603
|
+
callers that only want the design system.
|
|
604
|
+
|
|
572
605
|
Raises:
|
|
573
606
|
DesignSystemImportError: bundle is not a zip, missing/invalid manifest, or
|
|
574
607
|
violates a size limit (HTTP 400).
|
|
@@ -626,8 +659,10 @@ def import_bundle(
|
|
|
626
659
|
# Read the DECLARED CSS token sources ONCE (budgeted); the same bytes are
|
|
627
660
|
# reused for both token parsing and source-file retention (no double-charge).
|
|
628
661
|
css_sources = _read_css_sources(zf, root_prefix, manifest, budget)
|
|
629
|
-
tokens = _collect_tokens(manifest, _decode_css_texts(css_sources))
|
|
630
|
-
assets, files = _collect_assets_and_files(
|
|
662
|
+
tokens = _collect_tokens(manifest, _decode_css_texts(css_sources, warnings))
|
|
663
|
+
assets, files = _collect_assets_and_files(
|
|
664
|
+
zf, root_prefix, budget, css_sources, warnings
|
|
665
|
+
)
|
|
631
666
|
|
|
632
667
|
# Stored VERBATIM; the strip decides only whether the brand wrote a description
|
|
633
668
|
# at all (a whitespace-only one describes nothing, so it stays NULL). Same split
|
|
@@ -976,7 +1011,10 @@ def _read_css_sources(
|
|
|
976
1011
|
return result
|
|
977
1012
|
|
|
978
1013
|
|
|
979
|
-
def _decode_css_texts(
|
|
1014
|
+
def _decode_css_texts(
|
|
1015
|
+
css_sources: "dict[str, bytes]",
|
|
1016
|
+
warnings: "Optional[list[BundleImportWarning]]" = None,
|
|
1017
|
+
) -> list[str]:
|
|
980
1018
|
"""Decode the pre-read CSS source bytes to UTF-8 text (skip undecodable)."""
|
|
981
1019
|
texts: list[str] = []
|
|
982
1020
|
for path, raw in css_sources.items():
|
|
@@ -984,31 +1022,98 @@ def _decode_css_texts(css_sources: "dict[str, bytes]") -> list[str]:
|
|
|
984
1022
|
texts.append(raw.decode("utf-8"))
|
|
985
1023
|
except UnicodeDecodeError:
|
|
986
1024
|
logger.warning("Skipping non-UTF-8 CSS token source: %s", path)
|
|
1025
|
+
if warnings is not None:
|
|
1026
|
+
warnings.append(
|
|
1027
|
+
BundleImportWarning(
|
|
1028
|
+
path,
|
|
1029
|
+
"not valid UTF-8; its design tokens were not read.",
|
|
1030
|
+
)
|
|
1031
|
+
)
|
|
987
1032
|
return texts
|
|
988
1033
|
|
|
989
1034
|
|
|
990
1035
|
def _safe_relpath(rel_path: str) -> Optional[str]:
|
|
991
|
-
"""
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1036
|
+
"""The CANONICAL form of a bundle-relative FILE path, or ``None`` to REFUSE it.
|
|
1037
|
+
|
|
1038
|
+
VALIDATION, not laundering: a path is already canonical or it is refused. It is
|
|
1039
|
+
never rewritten into an acceptable form, because rewriting changes the very
|
|
1040
|
+
thing later rules are about to judge. ``assets/innocent/.`` used to normalize to
|
|
1041
|
+
``assets/innocent`` — losing the ``.`` basename that made it junk — and the
|
|
1042
|
+
entry was stored under a path that was not its own name. Two entries could also
|
|
1043
|
+
collapse onto ONE identity (``assets/./x``, ``assets//x`` and ``assets/x`` all
|
|
1044
|
+
became ``assets/x``), leaving which bytes win to zip ordering.
|
|
1045
|
+
|
|
1046
|
+
Refused: an empty name, a C0/DEL control character (``\\n`` and NUL among them,
|
|
1047
|
+
so no rule downstream has to cope with one), an absolute path (POSIX ``/`` or a
|
|
1048
|
+
Windows drive), and any ``.``, ``..`` or EMPTY segment. Backslashes are still
|
|
1049
|
+
folded to ``/`` first, which is the one tolerance kept deliberately: zips written
|
|
1050
|
+
on Windows use them as separators, and folding cannot erase a segment or change a
|
|
1051
|
+
basename's junk-ness the way the collapses above did.
|
|
1052
|
+
|
|
1053
|
+
A trailing-slash DIRECTORY marker is not a file path and is refused here; callers
|
|
1054
|
+
reach the directory case through :func:`_classify_bundle_entry`, which strips the
|
|
1055
|
+
marker and validates the path it names.
|
|
1056
|
+
|
|
1057
|
+
This is the contract the file browser already relies on: stored
|
|
1058
|
+
``design_system_file.path`` values are canonical by construction, so
|
|
1059
|
+
``_validated_file_path`` can reject a non-canonical REQUEST instead of
|
|
1060
|
+
normalizing it into an accepted one.
|
|
998
1061
|
"""
|
|
999
1062
|
if not rel_path:
|
|
1000
1063
|
return None
|
|
1001
1064
|
normalized = rel_path.replace("\\", "/")
|
|
1065
|
+
if any(ord(ch) < 0x20 or ord(ch) == 0x7F for ch in normalized):
|
|
1066
|
+
return None
|
|
1002
1067
|
if normalized.startswith("/") or re.match(r"^[A-Za-z]:", normalized):
|
|
1003
1068
|
return None
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1069
|
+
if any(segment in ("", ".", "..") for segment in normalized.split("/")):
|
|
1070
|
+
return None
|
|
1071
|
+
return normalized
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
# The verdict :func:`_classify_bundle_entry` reaches for one zip entry.
|
|
1075
|
+
_ENTRY_REFUSE = "refuse" # unsafe — reject the whole bundle
|
|
1076
|
+
_ENTRY_SKIP = "skip" # legitimate but never stored (directory, OS junk, dotfile)
|
|
1077
|
+
_ENTRY_FILE = "file" # store it, under the canonical path returned alongside
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
def _classify_bundle_entry(rel_path: str) -> tuple[str, Optional[str]]:
|
|
1081
|
+
"""THE decision for one bundle entry: refuse it, skip it, or store it.
|
|
1082
|
+
|
|
1083
|
+
ONE place that canonicalizes and then applies EVERY rule. Both gates that judge
|
|
1084
|
+
bundle paths call this — the up-front whole-bundle scan
|
|
1085
|
+
(:func:`_assert_bundle_paths_safe`) and the per-entry iterator
|
|
1086
|
+
(:func:`_iter_safe_entries`) — so they cannot disagree about a path shape, and a
|
|
1087
|
+
new rule cannot be added to one and forgotten in the other. They used to decide
|
|
1088
|
+
separately and DID disagree: the scan refused ``assets/innocent/.`` on its raw
|
|
1089
|
+
basename while the iterator accepted the same entry on its normalized one, and
|
|
1090
|
+
the permissive gate was the one that reached storage.
|
|
1091
|
+
|
|
1092
|
+
Returns ``(verdict, canonical_path)``; the path is set only for ``_ENTRY_FILE``.
|
|
1093
|
+
"""
|
|
1094
|
+
if rel_path.endswith("/"):
|
|
1095
|
+
# A directory marker. It is never stored, but the path it NAMES still has to
|
|
1096
|
+
# be canonical, so '../evil/' is refused rather than skipped.
|
|
1097
|
+
return (
|
|
1098
|
+
(_ENTRY_SKIP, None)
|
|
1099
|
+
if _safe_relpath(rel_path[:-1]) is not None
|
|
1100
|
+
else (_ENTRY_REFUSE, None)
|
|
1101
|
+
)
|
|
1102
|
+
canonical = _safe_relpath(rel_path)
|
|
1103
|
+
if canonical is None:
|
|
1104
|
+
return _ENTRY_REFUSE, None
|
|
1105
|
+
low = canonical.lower()
|
|
1106
|
+
if low.startswith("__macosx/") or "/__macosx/" in low:
|
|
1107
|
+
return _ENTRY_SKIP, None
|
|
1108
|
+
base = _basename(low)
|
|
1109
|
+
# The ONE dot-prefixed shape the importer stores is a template folder's
|
|
1110
|
+
# screenshot; every other dotfile stays skipped. Tested against the CANONICAL
|
|
1111
|
+
# path — the same string the recognizer sees downstream.
|
|
1112
|
+
if (base == ".ds_store" or base.startswith(".")) and not _is_template_preview(
|
|
1113
|
+
canonical
|
|
1114
|
+
):
|
|
1115
|
+
return _ENTRY_SKIP, None
|
|
1116
|
+
return _ENTRY_FILE, canonical
|
|
1012
1117
|
|
|
1013
1118
|
|
|
1014
1119
|
def _is_symlink(info: zipfile.ZipInfo) -> bool:
|
|
@@ -1029,8 +1134,11 @@ def _assert_bundle_paths_safe(zf: zipfile.ZipFile) -> None:
|
|
|
1029
1134
|
root-prefix scoping — so a malicious entry that falls OUTSIDE the bundle root
|
|
1030
1135
|
(e.g. ``../evil.png`` when the manifest sits under ``safe/``) is REJECTED, not
|
|
1031
1136
|
silently skipped. EVERY entry is checked (no exemption for empty or ``.``-only
|
|
1032
|
-
names): absolute paths, ``..`` traversal, and empty/invalid
|
|
1033
|
-
and symlink entries are refused before any bytes are read.
|
|
1137
|
+
names): absolute paths, ``..`` traversal, control characters, and empty/invalid
|
|
1138
|
+
names are refused, and symlink entries are refused before any bytes are read.
|
|
1139
|
+
|
|
1140
|
+
The path verdict comes from :func:`_classify_bundle_entry`, the SAME classifier
|
|
1141
|
+
:func:`_iter_safe_entries` uses, so the two gates cannot disagree about a shape.
|
|
1034
1142
|
"""
|
|
1035
1143
|
for info in zf.infolist():
|
|
1036
1144
|
name = info.filename
|
|
@@ -1038,12 +1146,12 @@ def _assert_bundle_paths_safe(zf: zipfile.ZipFile) -> None:
|
|
|
1038
1146
|
raise DesignSystemImportError(
|
|
1039
1147
|
f"Bundle entry '{name}' is a symlink; refusing to import."
|
|
1040
1148
|
)
|
|
1041
|
-
# No ``if name`` guard: an empty (or ``.``-only) name also
|
|
1042
|
-
#
|
|
1043
|
-
if
|
|
1149
|
+
# No ``if name`` guard: an empty (or ``.``-only) name is also refused, not
|
|
1150
|
+
# skipped.
|
|
1151
|
+
if _classify_bundle_entry(name)[0] == _ENTRY_REFUSE:
|
|
1044
1152
|
raise DesignSystemImportError(
|
|
1045
|
-
f"Bundle contains an unsafe path '{name}' (empty, absolute,
|
|
1046
|
-
"parent-directory traversal); refusing to import."
|
|
1153
|
+
f"Bundle contains an unsafe path '{name}' (empty, absolute, "
|
|
1154
|
+
"non-canonical, or parent-directory traversal); refusing to import."
|
|
1047
1155
|
)
|
|
1048
1156
|
|
|
1049
1157
|
|
|
@@ -1060,31 +1168,26 @@ def _iter_safe_entries(zf: zipfile.ZipFile, root_prefix: str):
|
|
|
1060
1168
|
the recognizer alone reads as working in a unit test and still drops every real
|
|
1061
1169
|
thumbnail, because the entry never reaches the recognizer.
|
|
1062
1170
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1171
|
+
Every path rule lives in :func:`_classify_bundle_entry` — the same classifier the
|
|
1172
|
+
up-front scan uses — so an entry is judged on its CANONICAL path and neither gate
|
|
1173
|
+
can be patched into disagreeing with the other. Stripping ``root_prefix`` is the
|
|
1174
|
+
only work done here, and it is bookkeeping rather than a path rule.
|
|
1067
1175
|
"""
|
|
1068
1176
|
for info in zf.infolist():
|
|
1069
1177
|
name = info.filename
|
|
1070
1178
|
if not name.startswith(root_prefix):
|
|
1071
1179
|
continue
|
|
1072
1180
|
rel_raw = name[len(root_prefix):]
|
|
1073
|
-
if not rel_raw
|
|
1074
|
-
continue # directory entry
|
|
1075
|
-
|
|
1076
|
-
if
|
|
1077
|
-
continue
|
|
1078
|
-
safe = _safe_relpath(rel_raw)
|
|
1079
|
-
if safe is None:
|
|
1181
|
+
if not rel_raw:
|
|
1182
|
+
continue # the root-prefix directory entry itself
|
|
1183
|
+
verdict, safe = _classify_bundle_entry(rel_raw)
|
|
1184
|
+
if verdict == _ENTRY_REFUSE:
|
|
1080
1185
|
raise DesignSystemImportError(
|
|
1081
|
-
f"Bundle contains an unsafe path '{rel_raw}' (absolute path
|
|
1082
|
-
"parent-directory traversal); refusing to
|
|
1186
|
+
f"Bundle contains an unsafe path '{rel_raw}' (absolute path, "
|
|
1187
|
+
"non-canonical path, or parent-directory traversal); refusing to "
|
|
1188
|
+
"import."
|
|
1083
1189
|
)
|
|
1084
|
-
|
|
1085
|
-
if (base == ".ds_store" or base.startswith(".")) and not _is_template_preview(
|
|
1086
|
-
safe
|
|
1087
|
-
):
|
|
1190
|
+
if safe is None: # _ENTRY_SKIP
|
|
1088
1191
|
continue
|
|
1089
1192
|
yield info, safe
|
|
1090
1193
|
|
|
@@ -1204,6 +1307,7 @@ def _collect_assets_and_files(
|
|
|
1204
1307
|
root_prefix: str,
|
|
1205
1308
|
budget: "_SizeBudget",
|
|
1206
1309
|
css_sources: "dict[str, bytes]",
|
|
1310
|
+
warnings: "Optional[list[BundleImportWarning]]" = None,
|
|
1207
1311
|
) -> tuple[list[DesignSystemAsset], list[DesignSystemFile]]:
|
|
1208
1312
|
"""Read a bundle into asset rows + file rows in one safety-checked pass.
|
|
1209
1313
|
|
|
@@ -1268,6 +1372,17 @@ def _collect_assets_and_files(
|
|
|
1268
1372
|
rel,
|
|
1269
1373
|
len(data),
|
|
1270
1374
|
)
|
|
1375
|
+
# A server-side log alone left the user believing the import was
|
|
1376
|
+
# complete; the same fact rides back on the response.
|
|
1377
|
+
if warnings is not None:
|
|
1378
|
+
warnings.append(
|
|
1379
|
+
BundleImportWarning(
|
|
1380
|
+
rel,
|
|
1381
|
+
"not a PNG, JPEG, GIF or WebP image "
|
|
1382
|
+
f"({len(data)} bytes); this template's thumbnail "
|
|
1383
|
+
"was not stored.",
|
|
1384
|
+
)
|
|
1385
|
+
)
|
|
1271
1386
|
continue
|
|
1272
1387
|
mime = sniffed
|
|
1273
1388
|
else:
|
|
@@ -615,6 +615,16 @@ _THUMBNAIL_BASENAME_PREFIXES = ("preview", "thumbnail")
|
|
|
615
615
|
|
|
616
616
|
|
|
617
617
|
def _is_thumbnail_basename(basename: str) -> bool:
|
|
618
|
+
"""True for a screenshot basename, with or without a leading dot.
|
|
619
|
+
|
|
620
|
+
A PREFIX match on purpose, matching the breadth of the importer's
|
|
621
|
+
``preview[^/]*\\.<ext>`` shape. A C0/DEL control character is refused outright:
|
|
622
|
+
the prefix test alone says nothing about what TRAILS the basename, and this is
|
|
623
|
+
the third gate on the same file — the importer now refuses such a path, so this
|
|
624
|
+
is defence in depth that no longer depends on the importer for the property.
|
|
625
|
+
"""
|
|
626
|
+
if any(ord(ch) < 0x20 or ord(ch) == 0x7F for ch in basename):
|
|
627
|
+
return False
|
|
618
628
|
return basename.lstrip(".").startswith(_THUMBNAIL_BASENAME_PREFIXES)
|
|
619
629
|
|
|
620
630
|
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/databricks_tellr_app/run.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/_otel_bootstrap.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/middleware/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/middleware/csrf.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/_authz.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/admin.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/admin_usage.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/agent_config.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/chat.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/export.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/feedback.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/images.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/profiles.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/sessions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/setup.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/slides.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/tools.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/tour.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/verification.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/routes/version.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/feedback.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/requests.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/responses.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/schemas/streaming.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/services/job_queue.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/utils/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/api/utils/validation.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/config_loader.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/context_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/databricks_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/encryption.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/mlflow_agent_spans.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/mlflow_tracing.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/otel_logging.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/permission_context.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/prompt_modules.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/settings_db.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/core/user_context.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/image.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/profile.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/prompts.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/database/models/session.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/domain/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/domain/slide_deck.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/agent_factory.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/config_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/drive_uploader.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/genie_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/html_to_pptx.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/image_service.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/image_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/tools/mcp_tool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/services/validator.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/css_utils.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/ds_asset_utils.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/error_handling.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/html_safety.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/html_utils.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/image_utils.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/js_validator.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/logging_config.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/pi_filter.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/slide_hash.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/spotlight.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.2.dev10 → databricks_tellr_app-0.4.2.dev11}/src/utils/text_caps.py
RENAMED
|
File without changes
|