Repository navigation
Description
Problem
When rsconnect-python (or posit-cli) is installed with uv tool install, it runs in its own isolated environment. Without --python, rsconnect-python inspects whichever interpreter is running the CLI (which_python() falls back to sys.executable, rsconnect/environment.py:252). So it inspects the tool environment instead of the project's:
| Feature | Result under uv tool install |
|---|---|
--force-generate |
requirements.txt lists the CLI's own dependencies (click, PyJWT, semver, uv, ...) and none of the project's. |
Manifest python.version |
Records the tool's Python (e.g. 3.13) instead of the project's (e.g. 3.11). |
--python .venv/bin/python |
Fails with No module named 'rsconnect', because the inspector runs as python -m rsconnect.subprocesses.inspect_environment (rsconnect/environment.py:227). |
deploy notebook --static |
Runs <python> -m nbconvert with the same interpreter (rsconnect/main.py:1879), so nbconvert must be in the tool environment. |
Running under uv run (which sets VIRTUAL_ENV) doesn't help; the tool environment is still used.
The CLI shouldn't have to share a Python environment with the content it deploys.
Dependencies
- Fix dependency filtering and require pip 20.3 for inspection #909 rewrites
rsconnect/subprocesses/inspect_environment.pywithpackaging-based rsconnect filtering, an editable check, and a pip ≥ 20.3 check. This work builds on that file, so start after Fix dependency filtering and require pip 20.3 for inspection #909 merges. - fix: support minor-only Python version overrides #911 is independent. It only touches
--override-python-versionhandling; expect at most a small merge conflict near the_get_python_env_info()call increate_python_environment().
Proposal
Keep the inspector running in the CLI's own environment, so it can keep using its dependencies (packaging, and toml on Python < 3.11). Most of what it does never reads the target interpreter: requirements files, pyproject.toml, uv export, rsconnect filtering, editable checks, and locale are all file or string work. Only query the project interpreter for the facts that come from it.
-
Find the project's interpreter.
which_python(python, directory)checks, in order:--python$VIRTUAL_ENV- a
.venvin the deploy directory or its parents, respectingUV_PROJECT_ENVIRONMENT $CONDA_PREFIXsys.executable
Log the interpreter that was picked.
-
Run the inspector with the CLI's interpreter and pass it the target. The parent runs
sys.executable -m rsconnect.subprocesses.inspect_environment --python <interp> --uv <uv path> .... Within the inspector, replace everysys.executablethat means "the project's Python" with the--pythonargument. -
Query the target interpreter for only these facts:
- Python version:
<interp> -I -c "import sys; print('%d.%d.%d' % sys.version_info[:3])". - pip version:
<interp> -m pip --version, now optional. uv-created venvs don't include pip. When pip is missing, omit the version instead of erroring;bundle.py:262already falls back when the package-manager version is absent. --force-generatefreeze:<interp> -m pip freezewhen pip ≥ 20.3 is present (keeping Fix dependency filtering and require pip 20.3 for inspection #909's version check and--excludeflags), otherwiseuv pip freeze --python <interp>. Both outputs go through Fix dependency filtering and require pip 20.3 for inspection #909's filter and editable check.
- Python version:
-
Use one uv binary. Resolve the bundled uv once in the parent process (the
uvdependency's binary, falling back toshutil.which("uv")), pass it to the inspector, and use it for bothuv exportanduv pip freezeinstead of bareuvfromPATH. -
Static notebooks run
<interp> -m nbconvertin the project's environment. When nbconvert is missing, raise a clearRSConnectExceptionnaming the interpreter and how to install nbconvert, instead of a rawCalledProcessError.
Decisions
- Behavior change: a globally installed CLI run inside an activated venv now inspects that venv. Call this out in the changelog.
--pythonbecomes a supported explicit override again; remove its deprecation warning.- The inspector is not run by file path inside the project's interpreter. That would require it to use only the standard library, and a stdlib replacement for
packagingwas tried and rejected.
Open questions
- With uv bundled, should
--force-generatealways useuv pip freeze --python <interp>? That's one code path, and it makes Fix dependency filtering and require pip 20.3 for inspection #909's pip ≥ 20.3 check irrelevant for generating requirements. The cost is that the manifest records pip as the package manager even though uv produced the freeze. - Does Connect accept a manifest with an empty
package_manager.versionwhen the project environment has no pip?
Tests
- Unit tests for the interpreter lookup order: env vars, a temporary
.venv, a.venvin a parent directory,UV_PROJECT_ENVIRONMENT,$CONDA_PREFIX, and thesys.executablefallback. - An integration-style test that creates a uv venv with neither pip nor rsconnect-python and installs one package into it.
--force-generateinspection from the dev environment should report that venv's Python version and package, and none of rsconnect's own dependencies. - Run the filtering and editable-check tests against
uv pip freezeoutput too. It formats editables as-e file:///...and has none of pip's# Editable install ...comments. deploy notebook --staticwith nbconvert missing from the project environment raises the clear error.
Once released and picked up by posit-cli, the Connect docs can keep recommending uv tool install posit-cli.
Activity
tdstein commentedon Nov 5, 2026
🤖 > This was generated by AI during triage.
Agent Brief
Category: bug
Summary: Inspect and render with the project's Python environment while keeping the environment inspector and its dependencies in the CLI environment.
Current behavior:
which_python()defaults to the CLI interpreter even withVIRTUAL_ENVset._inspect_environment()runs the inspector in the selected interpreter, requiring the project's environment to contain rsconnect and its dependencies. On current main after #909, a clean venv reproduced inspection failure on missingpackaging(the checkout was importable from the working directory). Interpreter selection withVIRTUAL_ENVset also reproduced selection of the CLI interpreter. Static notebook rendering already wraps subprocess failures inRSConnectException, but the message lacks interpreter-specific installation guidance.Desired behavior:
Select the project interpreter in this order: explicit
--python,VIRTUAL_ENV, a project environment in the deployment directory or its ancestors (respectingUV_PROJECT_ENVIRONMENT),CONDA_PREFIX, then the CLI interpreter. Log the selected interpreter and support platform-specific executable locations. Explicit invalid overrides must produce actionable errors.Run the inspector in the CLI environment and pass the selected project interpreter separately. Read requirements, project metadata, and locale in the inspector; query the target interpreter for its Python version and optional pip version. Resolve the bundled uv executable once in the parent, falling back to PATH, and use that executable for both export and freeze.
For generated requirements, use target-environment pip when pip >= 20.3 is present, preserving #909's exclusions. Otherwise use
uv pip freeze --python <target>. Apply #909's distribution filtering and editable validation to both outputs. Missing pip must not prevent inspection of a project environment. Preserve the pip requirements manifest semantics; verify how Connect handles the unavailable pip version before choosing the final serialized representation. Do not invent a pip version.Static notebooks must use the selected project interpreter. Missing nbconvert must raise an actionable
RSConnectExceptionnaming that interpreter and explaining how to install nbconvert.Key interfaces:
which_python(python, directory): interpreter resolution with deployment-directory context.Environment._get_python_env_info()andEnvironment._inspect_environment(): distinguish the CLI interpreter from the project interpreter and pass the resolved uv executable.detect_environment(),get_python_version(),get_version(),pip_freeze(), anduv_export(): obtain target facts without requiring inspector dependencies in the target environment.EnvironmentDataandManifest: represent unavailable pip metadata compatibly with Connect.make_notebook_html_bundle(): use the project interpreter and provide useful missing-nbconvert errors.Acceptance criteria:
UV_PROJECT_ENVIRONMENT, platform executable locations, explicit override validation, and CLI fallback.--pythondeprecation warning and document supported explicit overrides. The changelog calls out that a globally installed CLI now selects an activated project environment.Out of scope:
packagingwith a standard-library parser.Dependency: #909 merged on 2026-11-05; work can proceed. Connect acceptance verification is required before completion; if suitable server access is unavailable, report that specific blocker rather than claiming compatibility.