Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# [rsconnect-python](https://docs.posit.co/rsconnect-python)

The [Posit Connect](https://docs.posit.co/connect/) command-line interface.
The command-line interface for [Posit Connect](https://docs.posit.co/connect/) and [Posit Connect Cloud](https://connect.posit.cloud).

## Installation

Expand All @@ -22,7 +22,7 @@ pipx install rsconnect-python
python -m pip install rsconnect-python
```

## Usage
## Usage with Posit Connect

[Get an API key from your Posit Connect server](https://docs.posit.co/connect/user/api-keys/) with at least publisher privileges:

Expand All @@ -40,6 +40,24 @@ rsconnect deploy shiny app.py --title "my shiny app"

[Read more about publisher and admin capabilities on the docs site.](https://docs.posit.co/rsconnect-python)

## Usage with Posit Connect Cloud

Store your credentials, logging in to [Posit Connect Cloud](https://connect.posit.cloud) through your browser:

```bash
rsconnect add --connect-cloud --account <YOUR-ACCOUNT-NAME> --name cloud
```

Deploy your application:

```bash
rsconnect deploy shiny app.py --name cloud --title "my shiny app"
```

For non-interactive use such as CI, pass a service account credential with
`--client-id` and `--client-secret`, or the `CONNECT_CLOUD_CLIENT_ID` and
`CONNECT_CLOUD_CLIENT_SECRET` environment variables.

## Contributing

[Contributing docs](./CONTRIBUTING.md)
37 changes: 37 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- Posit Connect Cloud is now a supported deployment target, alongside Posit
Connect and shinyapps.io, mirroring the R rsconnect package's support.
Register an account with `rsconnect add -n <nickname> --connect-cloud
-A <account>`, which verifies the account exists and that you can publish to
it. Authentication is an interactive browser login by default; for CI and
other non-interactive use, pass a service account credential with
`--client-id`/`--client-secret` (or the `CONNECT_CLOUD_CLIENT_ID` and
`CONNECT_CLOUD_CLIENT_SECRET` environment variables). Tokens are refreshed
automatically. Deploy with any `rsconnect deploy` subcommand by passing
`--connect-cloud` (or `-s connect.posit.cloud`) with `-A <account>` (or the
`CONNECT_CLOUD_ACCOUNT` environment variable; a `SHINYAPPS_ACCOUNT` variable
exported for shinyapps.io is ignored here), or `-n <nickname>` for a saved
account. Supported content types: Shiny (Python
and R), Streamlit, Dash, Bokeh, Jupyter notebooks, Quarto, R Markdown, and
static content.
- `rsconnect add` now reports invalid option combinations and unreadable
certificate files as plain error messages. Previously these surfaced as raw
Python tracebacks.
- Deploying with a nickname (`-n`) no longer fails when `SHINYAPPS_ACCOUNT`,
`SHINYAPPS_TOKEN`, or `SHINYAPPS_SECRET` happen to be set in the environment.
Those values are ignored for nickname deploys — the saved credential is what
the nickname means. Shinyapps options typed on the command line still
conflict with `-n`.
- Credentials are now redacted from verbose (`-v`) log output and from error
messages that quote a request URL. This covers authorization and signing
headers, OAuth tokens and client secrets in request and response bodies, the
query-string credentials of presigned bundle-upload URLs, and the values of
environment variables passed with `-E` (names are still logged).
- `rsconnect deploy manifest` and `rsconnect deploy bundle` no longer overwrite
the title of existing content when `-t/--title` is not given. Previously a
redeploy reset the server-side title to one derived from the manifest or
bundle; now, as with the other deploy commands, a redeploy without `-t`
leaves the existing title unchanged.
- `rsconnect deploy pyproject` no longer uses the server nickname (`-n`) as a
title override. The title now comes from `-t/--title` or the pyproject
metadata, so redeploying with a nickname no longer renames existing content
after the nickname.
- Added support for Python 3.14. The test suite now runs on Python 3.14 in CI.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

i put my changes in the some Unreleased block as these pre-existing unreleased lines. Not sure if these were actually still unreleased or not.

- `rsconnect deploy` subcommands now accept `--quiet`, which suppresses the
step-by-step progress lines and the streamed server build log, printing only
Expand Down
19 changes: 18 additions & 1 deletion rsconnect/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
import sys
import traceback
import typing
from os.path import basename, exists, join, relpath
from os.path import basename, exists, isdir, join, relpath
from pathlib import PurePath
from typing import Optional, Sequence, cast
from warnings import warn

Expand Down Expand Up @@ -263,10 +264,15 @@ class QuartoInspectResultConfig(TypedDict):
project: QuartoInspectResultConfigProject


class QuartoInspectResultFiles(TypedDict):
input: list[str]


class QuartoInspectResult(TypedDict):
quarto: QuartoInspectResultQuarto
engines: list[str]
config: NotRequired[QuartoInspectResultConfig]
files: NotRequired[QuartoInspectResultFiles]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

set in all quarto inspections, but only needed for the Connect Cloud path (to pick primary file)



def quarto_inspect(
Expand Down Expand Up @@ -302,6 +308,17 @@ def validate_quarto_engines(inspect: QuartoInspectResult):
return engines


def quarto_inputs_from_inspect(file_or_directory: str, inspect: QuartoInspectResult) -> list[str]:
"""The project's render inputs relative to its root, in Quarto's render order.

Empty for a standalone document; its inspect output has no files section.
"""
if not isdir(file_or_directory):
return []
inputs = inspect.get("files", {}).get("input", [])
return [PurePath(relpath(each, file_or_directory)).as_posix() for each in inputs]


# ===============================================================================
# START: Compatibility entry point used by the vetiver-python package.
# vetiver's `deploy_connect` calls `deploy_python_fastapi` (below), which routes
Expand Down
Loading
Loading