Skip to content

Commit 98923cb

Browse files
authored
Support environment.python.requires option in manifest (#648)
1 parent 9f7c114 commit 98923cb

File tree

13 files changed

+1017
-813
lines changed

13 files changed

+1017
-813
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [??] - ??
8+
9+
### Added
10+
11+
- `rsconnect` now detects Python interpreter version requirements from
12+
`.python-version`, `pyproject.toml` and `setup.cfg`
13+
714
## [1.25.2] - 2025-02-26
815

916
### Fixed

README.md

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -219,24 +219,34 @@ ensuring that you use the same Python that you use to run your Jupyter Notebook:
219219
#### Python Version
220220

221221
When deploying Python content to Posit Connect,
222-
the server will require matching `<MAJOR.MINOR>` versions of Python. For example,
223-
a server with only Python 3.9 installed will fail to match content deployed with
224-
Python 3.8. Your administrator may also enable exact Python version matching which
225-
will be stricter and require matching major, minor, and patch versions. For more
226-
information see the [Posit Connect Admin Guide chapter titled Python Version
222+
the server will require a version of Python that matches the content
223+
requirements.
224+
225+
For example, a server with only Python 3.9 installed will fail to match content
226+
that requires Python 3.8.
227+
228+
`rsconnect` supports detecting Python version requirements in several ways:
229+
1. A `.python-version` file exists. In such case
230+
`rsconnect` will use its content to determine the python version requirement.
231+
2. A `pyproject.toml` with a `project.requires-python` field exists.
232+
In such case the requirement specified in the field will be used
233+
if no `.python-version` file exists.
234+
3. A `setup.cfg` with an `options.python_requires` field exists.
235+
In such case the requirement specified in the field will be used
236+
if **1** or **2** were not already satisfied.
237+
4. If no other source of version requirement was found, then
238+
the interpreter in use is considered the one required to run the content.
239+
240+
On Posit Connect `>=2025.03.0` the requirement detected by `rsconnect` is
241+
always respected. Older Connect versions will instead rely only on the
242+
python version used to deploy the content to determine the requirement.
243+
244+
For more information see the [Posit Connect Admin Guide chapter titled Python Version
227245
Matching](https://docs.posit.co/connect/admin/python/#python-version-matching).
228246

229-
We recommend installing a version of Python on your client that is also available
230-
in your Connect installation. If that's not possible, you can override
231-
rsconnect-python's detected Python version and request a version of Python
232-
that is installed in Connect, For example, this command:
233-
234-
```bash
235-
rsconnect deploy api --override-python-version 3.11.5 my-api/
236-
```
237-
238-
will deploy the content in `my-api` while requesting that Connect
239-
use Python version 3.11.5.
247+
We recommend providing a `pyproject.toml` with a `project.requires-python` field
248+
if the deployed content is an installable package and a `.python-version` file
249+
for plain directories.
240250

241251
> **Note**
242252
> The packages and package versions listed in `requirements.txt` must be

rsconnect/actions.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,12 @@
3131

3232
from . import api
3333
from .bundle import (
34-
create_python_environment,
3534
get_default_entrypoint,
3635
make_api_bundle,
3736
make_quarto_source_bundle,
3837
read_manifest_file,
3938
)
40-
from .environment import Environment, EnvironmentException
39+
from .environment import Environment
4140
from .exception import RSConnectException
4241
from .log import VERBOSE, logger
4342
from .models import AppMode, AppModes
@@ -78,8 +77,6 @@ def failed(err: str):
7877
passed()
7978
except RSConnectException as exc:
8079
failed("Error: " + exc.message)
81-
except EnvironmentException as exc:
82-
failed("Error: " + str(exc))
8380
except Exception as exc:
8481
traceback.print_exc()
8582
failed("Internal error: " + str(exc))
@@ -375,7 +372,7 @@ def deploy_app(
375372
)
376373
)
377374

378-
environment = create_python_environment(
375+
environment = Environment.create_python_environment(
379376
directory, # pyright: ignore
380377
force_generate,
381378
python,

rsconnect/api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@
5151
from typing_extensions import NotRequired, TypedDict
5252

5353
from . import validation
54-
from .bundle import _default_title, fake_module_file_from_directory
54+
from .bundle import _default_title
55+
from .environment import fake_module_file_from_directory
5556
from .certificates import read_certificate_file
5657
from .exception import DeploymentFailedException, RSConnectException
5758
from .http_support import CookieJar, HTTPResponse, HTTPServer, JsonData, append_to_path

0 commit comments

Comments
 (0)