Skip to content

fix: pass integration env vars to Streamlit apps#102

Closed
robertlacok wants to merge 3 commits into
mainfrom
fix/sal-64-streamlit-integration-env-vars
Closed

fix: pass integration env vars to Streamlit apps#102
robertlacok wants to merge 3 commits into
mainfrom
fix/sal-64-streamlit-integration-env-vars

Conversation

@robertlacok
Copy link
Copy Markdown
Contributor

@robertlacok robertlacok commented May 21, 2026

Summary

Fixes an issue where Streamlit apps couldn't access environment variables from integrations.

Root Cause

Streamlit processes are started by the installer during bootstrap (Phase 12 of installer/__main__.py). At that point, integration env vars haven't been fetched yet — they're only fetched later by the Jupyter kernel's init_deepnote_runtime()set_integration_env(), which runs in a separate process. The Streamlit subprocess snapshots os.environ at start time (ServerProcess._start() calls os.environ.copy()), so it never sees the integration env vars.

Fix

Before starting Streamlit processes in the installer, fetch integration env vars from the existing webapp endpoint (/integrations/environment-variables) and set them in os.environ. This way Streamlit subprocesses inherit the vars.

Input validation covers:

  • Type checks (isinstance for both name/value as str)
  • Non-dict list entries are skipped with a warning
  • Empty names, names containing =, and null bytes in names/values are rejected
  • logger.exception used in the top-level catch block for full traceback

Files Changed

  • installer/module/streamlit.py: Added fetch_integration_env_vars() and set_integration_env_vars() functions with input validation
  • installer/__main__.py: Call set_integration_env_vars() before starting Streamlit apps
  • tests/unit/test_streamlit.py: Unit tests for fetch, set, validation, and error handling (including non-dict entries and null-byte values)

Summary by CodeRabbit

  • New Features

    • Installer fetches and applies integration environment variables so Streamlit subprocesses inherit configured settings at startup.
  • Improvements

    • Fetching/parsing is resilient: errors, malformed payloads, or invalid entries are logged and skipped without interrupting startup or app discovery.
  • Tests

    • Added unit tests covering retrieval, handling of empty/non-list responses, network failures, and safe application/skipping of invalid entries.

Review Change Stack

Streamlit processes are started by the installer during bootstrap, before
integration env vars are fetched by the Jupyter kernel (in a separate
process). The Streamlit subprocess snapshots os.environ at start time, so it
never sees the integration env vars.

Fetch integration env vars from the webapp endpoint
(/integrations/environment-variables) and set them in os.environ before
starting Streamlit processes, so the subprocesses inherit them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@linear
Copy link
Copy Markdown

linear Bot commented May 21, 2026

SAL-64

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: abd0f33d-f78f-46d8-bfe7-61d024c71867

📥 Commits

Reviewing files that changed from the base of the PR and between aeb9149 and d008beb.

📒 Files selected for processing (2)
  • installer/module/streamlit.py
  • tests/unit/test_streamlit.py

📝 Walkthrough

Walkthrough

This PR fetches integration environment variables from the WebApp /integrations/environment-variables endpoint with retries, validates the JSON list response, and writes validated name/value pairs into os.environ. The Streamlit bootstrap now calls set_integration_env_vars() before discovering Streamlit apps and logs failures without stopping discovery. Unit tests cover fetch success/empty/error/non-list cases and validate setter behavior and skipping of invalid entries.

Sequence Diagram

sequenceDiagram
  participant StreamlitBootstrap as Streamlit Bootstrap
  participant WebApp as WebApp Endpoint
  participant Installer as Installer
  participant OSEnviron as os.environ
  participant Subprocess as Streamlit Subprocess
  StreamlitBootstrap->>WebApp: GET /integrations/environment-variables (retries)
  WebApp-->>Installer: JSON list of {name, value} entries
  Installer->>Installer: parse & validate entries
  Installer->>OSEnviron: set valid NAME=VALUE pairs
  StreamlitBootstrap->>Subprocess: spawn Streamlit subprocess (inherits env)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Updates Docs ⚠️ Warning Feature implementation lacks documentation. No updates to docs/user/ or docs/dev/ explaining how integration environment variables are fetched and passed to Streamlit apps. Add documentation to docs/user/configuration.md or docs/dev/ explaining the integration env vars feature, when it runs, and which config/env vars control it.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding integration environment variable passing to Streamlit apps before subprocess startup.
Docstring Coverage ✅ Passed Docstring coverage is 91.67% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 21, 2026

📦 Python package built successfully!

  • Version: 2.3.0.dev4+505ddf0
  • Wheel: deepnote_toolkit-2.3.0.dev4+505ddf0-py3-none-any.whl
  • Install:
    pip install "deepnote-toolkit @ https://deepnote-staging-runtime-artifactory.s3.amazonaws.com/deepnote-toolkit-packages/2.3.0.dev4%2B505ddf0/deepnote_toolkit-2.3.0.dev4%2B505ddf0-py3-none-any.whl"

@robertlacok robertlacok changed the title fix: pass integration env vars to Streamlit apps (SAL-64) fix: pass integration env vars to Streamlit apps May 21, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

❌ Patch coverage is 89.47368% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.06%. Comparing base (8bb3cef) to head (d008beb).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
installer/module/streamlit.py 89.47% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #102      +/-   ##
==========================================
+ Coverage   73.96%   74.06%   +0.10%     
==========================================
  Files          95       95              
  Lines        5669     5707      +38     
  Branches      843      849       +6     
==========================================
+ Hits         4193     4227      +34     
- Misses       1200     1204       +4     
  Partials      276      276              
Flag Coverage Δ
combined 74.06% <89.47%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@installer/module/streamlit.py`:
- Around line 98-105: Replace the logger.error calls in the exception handlers
with logger.exception so stack traces are recorded: in the except blocks
catching urllib.error.URLError (the handler referencing variable e),
json.JSONDecodeError (handler referencing e), and the generic except Exception
(handler referencing e) used in the Streamlit integration env-var fetch code,
change the logger.error(...) calls to logger.exception(...) while keeping the
existing message strings.
- Around line 93-97: After calling json.loads(json_content) and assigning to
variables, validate that variables is a list before returning; if it's not a
list, log a clear warning via logger (including the unexpected type/value) and
return an empty list so downstream iteration (where variables is used) doesn't
silently drop everything. Reference the variables variable, json_content, and
the existing logger in your change.

In `@tests/unit/test_streamlit.py`:
- Around line 54-55: Add docstrings and explicit return type hints for the new
test class and its methods: update class TestFetchIntegrationEnvVars to include
a one-line class docstring and change def test_fetch_integration_env_vars(self):
to def test_fetch_integration_env_vars(self) -> None: with a one-line docstring
for the test; apply the same pattern (add class/function docstrings and -> None
return hints) to the other new test classes/methods referenced in the review
(the blocks at 79-80, 91-92, 105-106, and 130-131) so all tests follow
repository conventions.
- Around line 126-129: Replace the ad-hoc os.environ.pop cleanup that only runs
after assertions with a failure-safe registration: before invoking the code
under test, register environment teardown using self.addCleanup(lambda:
(os.environ.pop("TEST_INT_VAR_A", None), os.environ.pop("TEST_INT_VAR_B",
None))) or alternatively use unittest.mock.patch.dict to set the test env values
(e.g., patch.dict(os.environ, {"TEST_INT_VAR_A": "...", "TEST_INT_VAR_B":
"..."}, clear=False)) so TEST_INT_VAR_A and TEST_INT_VAR_B are always restored
even if the test fails; update the test method(s) that currently call
os.environ.pop("TEST_INT_VAR_A", None) / os.environ.pop("TEST_INT_VAR_B", None)
to use one of these approaches.
- Around line 131-142: Add a test entry to the mock_data list that includes a
null byte in the name so set_integration_env_vars exercises the name-rejection
branch; specifically add an item like {"name": "BAD\0NAME", "value":
"some_value"} alongside the existing cases in tests/unit/test_streamlit.py so
the set_integration_env_vars function is validated for null bytes in the name
field.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6f85937f-c987-41cf-adf4-9a44420d664a

📥 Commits

Reviewing files that changed from the base of the PR and between 8bb3cef and 05912d3.

📒 Files selected for processing (3)
  • installer/__main__.py
  • installer/module/streamlit.py
  • tests/unit/test_streamlit.py

Comment thread installer/module/streamlit.py
Comment thread installer/module/streamlit.py Outdated
Comment thread tests/unit/test_streamlit.py Outdated
Comment thread tests/unit/test_streamlit.py Outdated
Comment thread tests/unit/test_streamlit.py
robertlacok and others added 2 commits May 21, 2026 16:54
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Validate fetched payload is a list; return [] otherwise
- Use logger.exception in fetch handlers for full tracebacks
- Make test env cleanup failure-safe via addCleanup
- Add docstrings and -> None hints to new tests
- Add null-byte-in-name and non-list-payload test cases

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@deepnote-bot
Copy link
Copy Markdown

🚀 Review App Deployment Started

📝 Description 🌐 Link / Info
🌍 Review application ra-102
🔑 Sign-in URL Click to sign-in
📊 Application logs View logs
🔄 Actions Click to redeploy
🚀 ArgoCD deployment View deployment
Last deployed 2026-05-21 15:13:36 (UTC)
📜 Deployed commit a8acc03bcf2f38d30d302d589ad6c1f921457155
🛠️ Toolkit version 505ddf0

@robertlacok robertlacok marked this pull request as ready for review May 22, 2026 12:24
@robertlacok robertlacok requested a review from a team as a code owner May 22, 2026 12:24
@robertlacok robertlacok requested a review from m1so May 22, 2026 12:24
@robertlacok
Copy link
Copy Markdown
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants