Skip to content

Conversation

@amol-
Copy link
Collaborator

@amol- amol- commented Dec 18, 2025

Intent

Allow user to specify uv.lock as the requirement file when deploying content to connect.

This intentionally avoids automatically detecting a uv.lock and preferring it as it would be an existing behavior change.
We can definitely implement such a behavior in the future as the implemented approach proves to be well received by users.

closes #749

Type of Change

  • Bug Fix
  • New Feature
  • Breaking Change

Approach

When --requirements-file receives uv.lock as its value,
we parse the uv lockfile and generate a requirements.txt.lock from it

Paired with our existing support for .python-version this allows users to deploy content to connect on an environment that mimics their local uv environment.

Automated Tests

A test that verifies inspect_environment correctly handles uv.lock has been added (test_uv_lock_export)

Directions for Reviewers

On an existing project having a requirements.txt (but not a uv.lock) you can do

uv init
uv add -r requirements.txt

That will generate a uv.lock file that is based on your requirements.txt,
now you can deploy using it

rsconnect deploy X . --requirements-file uv.lock

you should get the same exact environment you had with your previous requirements.txt

Checklist

  • I have updated CHANGELOG.md to cover notable changes.
  • I have updated all related GitHub issues to reflect their current state.
  • I have run the rsconnect-python-tests-at-night workflow in Connect against this feature branch.

@amol- amol- self-assigned this Dec 18, 2025
@github-actions
Copy link

github-actions bot commented Dec 18, 2025

PR Preview Action v1.6.3

🚀 View preview at
https://posit-dev.github.io/rsconnect-python/pr-preview/pr-750/

Built to branch gh-pages at 2025-12-19 15:55 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions
Copy link

github-actions bot commented Dec 18, 2025

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
5429 4154 77% 0% 🟢

New Files

No new covered files...

Modified Files

File Coverage Status
rsconnect/main.py 69% 🟢
rsconnect/subprocesses/inspect_environment.py 86% 🟢
TOTAL 78% 🟢

updated for commit: a2bbf09 by action🐍

@amol- amol- mentioned this pull request Dec 18, 2025
5 tasks
"Path to requirements file to record in the manifest instead of detecting the environment. "
"Must be inside the notebook directory. Use 'none' to capture via pip freeze."
),
help=("Path to requirements file listing the project dependencies. " "Must be inside the notebook directory."),
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Those help message changes are unrelated to this PR, but I have been trying to improve them based on #748 comments

Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we add details something like: "this might be a file like the standard requirements.txt, but any file that lists dependencies is accepted. For example a requirements.txt.lock file could also be used which will recreate the environment with exactly the versions listed in that lock file."

My concern on #748 is that we call this requirements-file and I believe most of our users will interpret this to mean that only a requirements.txt can be submitted. And they will never think that they could also submit a lock file to this. I understand that in the Python world these files are effectively in a subset/superset relationship and that both are "requirements file"s in our / Python parlance. But I don't think that is true of our data scientist users, and want to make sure we make it clear to them that the requirements-file option can indeed accept a lock file.

Copy link
Collaborator Author

@amol- amol- Dec 19, 2025

Choose a reason for hiding this comment

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

Oh I see what you mean.
This is confusing because the glossary is a bit fuzzy in this context.
For example if you use pip-tools the requirements.txt is the lockfile and the requirements.in is the dependencies file.

requirements.txt.lock isn't a convention in the python ecosystem, it's specific to Connect as the requirements.txt was already used with a different meaning.

Would it make sense to phrase it as

Path to requirements file listing the project dependencies.
Any file compatible with requirements.txt format or uv.lock is accepted, 
a requirements.txt.lock retrieved with "rsconnect content get-lockfile" is also supported. 
Must be inside the project directory.

?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, perfect

@amol- amol- marked this pull request as ready for review December 18, 2025 18:07
@amol- amol- requested a review from toph-allen December 18, 2025 18:07
@nealrichardson
Copy link
Contributor

Wouldn't the same approach work (more or less) for pyproject.toml? pylock.toml? I love that we're doing uv.lock, but seems reasonable to follow with the others, right? (See also #327.)

@amol-
Copy link
Collaborator Author

amol- commented Dec 19, 2025

Wouldn't the same approach work (more or less) for pyproject.toml? pylock.toml? I love that we're doing uv.lock, but seems reasonable to follow with the others, right? (See also #327.)

Yes, I wanted to try this approach specifically because it's flexible.
Deploy process can support the various formats as they become widespread without requiring major changes to connect server or even upgrading the server at all (users can use uv.lock independently from the connect version installed by their admins)

But before jumping on the bandwagon and saying that it can work for everything I wanted to put out one format (supported only when explicitly requested by the user and not automatically) to check what limitations users are going to face out in the wild.

If this approach proves as viable as I expect, with only a minority of corner cases not supported, I think we can expand it to any other format.

Comment on lines +1098 to +1101
"Path to requirements file listing the project dependencies. "
"Any file compatible with requirements.txt format or uv.lock is accepted, "
"a requirements.txt.lock retrieved with 'rsconnect content get-lockfile' is also supported. "
"Must be inside the project directory."
Copy link
Contributor

Choose a reason for hiding this comment

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

so just to be clear this accepts any of these:

  • uv.lock
  • requirements.txt
  • requirements.txt.lock

Can we state this more simply? Does it matter where the requirements.txt.lock came from?

Copy link
Collaborator Author

@amol- amol- Dec 19, 2025

Choose a reason for hiding this comment

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

requirements.txt.lock isn't really a thing, it can only come from connect itself when downloaded with get-lockfile .
From python point of view is just a perfectly normal requirements.txt with a different name, but the concerns voiced here #750 (comment) seemed to be that some users might now immediately understand they can send back a connect requirements.txt.lock unless explicitly documented


requirements = filter_pip_freeze_output(exported)
requirements = (
"# requirements.txt.lock generated from uv.lock by rsconnect-python on "
Copy link
Contributor

@mconflitti-pbc mconflitti-pbc Dec 19, 2025

Choose a reason for hiding this comment

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

I am providing a uv.lock file and this message is not what I am seeing. Instead I see from requirements.txt.lock

Copy link
Collaborator Author

@amol- amol- Dec 19, 2025

Choose a reason for hiding this comment

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

Uhm, Can you elaborate?

This is a comment that is prefixed to the requirements file uploaded to connect so that when the bundle is accessed for debugging purposes there is a hint that the requirements were not written by a user but were generated from a uv.lock

Copy link
Contributor

Choose a reason for hiding this comment

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

My bad, actually referring to this in the logs when deploying with uv.lock attached:

2025/12/19 18:30:53.191895006 Generating lockfile python/requirements.txt.lock from requirements.txt.lock

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.

basic support for uv.lock

5 participants