This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
rsconnect-python is the Posit Connect command-line interface for deploying Python content (Shiny apps, Quarto documents, APIs, Jupyter notebooks, etc.) to Posit Connect servers. The tool handles bundling content, managing credentials, and orchestrating deployments.
# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install in editable mode with dev dependencies
pip install -e '.[test]'# Run tests with Python 3.8 (default)
make test
# Run tests with specific Python version
make test-3.12
# Run tests across all Python versions (3.8-3.12)
make all-tests
# Run single test file
pytest tests/test_bundle.py
# Run single test
pytest tests/test_bundle.py::test_function_name
# Run tests with verbose coverage
./scripts/runtests # Uses pytest with coverage# Format code with black
make fmt
# Run all linters (black, flake8, pyright)
make lint
# Run individual linters
black --check --diff rsconnect/
flake8 rsconnect/
pyright rsconnect/# Build documentation
make docs
# Serve documentation locally (with live reload)
make docs-serve# Build wheel distribution
make dist
# Install built package
make installmain.py - CLI entry point using Click framework. Defines all commands (deploy, add, list, etc.) and option parsing. Commands delegate to action functions.
api.py - HTTP client for Posit Connect API. Key classes:
RSConnectServer- represents a Connect server (URL, API key, certificates)RSConnectClient- low-level HTTP operationsRSConnectExecutor- high-level deployment operations (deploy_bundle, wait_for_task, etc.)SPCSConnectServer- specialized server for Snowflake deployments
actions.py & actions_content.py - High-level deployment orchestration:
actions.py- deployment workflows (test connections, create bundles, validate Quarto)actions_content.py- content management (list, search, build history, download bundles)
bundle.py - Content bundling and manifest generation. Creates tar.gz bundles containing:
- Application files
manifest.jsondescribing app mode, entry point, dependencies- Environment snapshot (requirements.txt or environment.yml)
Functions named make_*_bundle() for different content types (api, html, notebook, tensorflow, voila, quarto).
models.py - Data structures:
AppMode- represents content types (shiny, quarto-shiny, jupyter-static, python-api, etc.)AppModes- registry of all supported app modes with lookup functions- TypedDict models for API responses (ContentItemV1, TaskStatusV1, etc.)
metadata.py - Persistent storage of configuration:
ServerStore- saved server credentials (stored in~/.rsconnect-python/)AppStore- deployment history per directory (stored in localrsconnect-python/subdirs)
environment.py - Python dependency detection:
- Inspects virtual environments, conda environments, or current Python
- Generates requirements files for reproducible deployments
- Runs inspection in subprocess for isolation
- Validate - Check server connection, validate content files
- Bundle - Create manifest.json, snapshot dependencies, tar content files
- Upload - POST bundle to
/v1/contentor existing content GUID - Deploy - Server extracts bundle, starts deployment task
- Wait - Poll task status until COMPLETE or ERROR
- Store - Save deployment metadata to local AppStore
Different content types have different app modes (defined in models.py):
python-shiny- Shiny for Python appsquarto-shiny- Quarto documents with Shiny runtimejupyter-static- Rendered Jupyter notebookspython-api- FastAPI, Flask APIspython-dash- Plotly Dash appspython-streamlit- Streamlit appspython-holoviz-panel- HoloViz Panel apps- etc.
The app mode determines how Connect runs the content. Manifests must specify the correct mode.
- Unit tests in
tests/mirror module structure (test_bundle.py,test_api.py, etc.) - Uses
pytestwithhttprettyfor mocking HTTP requests conftest.pydefines shared fixtures
- Mock HTTP responses with
httprettydecorators - Use temporary directories for file operations
- Test fixtures in
tests/testdata/for sample content test_metadata.pyhas special flake8 exclusion for E501 (line length)
- GitHub Actions workflow in
.github/workflows/main.yml - Tests run on Python 3.8-3.12 across ubuntu/macos/windows
- Linting enforced on all PRs
- Coverage reported on Python 3.8 PRs
- Black formatting (120 char line length)
- Flake8 with specific ignores for Black compatibility (E203, E231, E302)
- Strict type checking with Pyright
- Python 3.8+ compatibility (use
typing_extensionsfor newer types)
- Strict type checking enabled (
typeCheckingMode = "strict") - Use
TypedDictfor structured dictionaries (API responses, manifest data) - Import from
typing_extensionsfor Python 3.8-3.10 compatibility py.typedmarker indicates typed package
- Raise
RSConnectExceptionfor operational errors (user-facing) - Include helpful error messages with context
- Use
cli_feedback()context manager for OK/ERROR output
- Logger in
log.pywith custom VERBOSE level between INFO and DEBUG - Use
logger.info()for user-visible progress - Use
logger.debug()for detailed diagnostics - Console output uses Click's
echo()andsecho()for colors
- Every deployment requires a
manifest.jsondescribing the content - Manifests include file checksums, app mode, entry point, dependencies
- Different manifest generators for different content types
- All API calls go through
RSConnectClientin api.py - Handle non-JSON responses and network errors gracefully
- Retry logic built into executor methods
- Support for certificate validation with custom CA bundles
- Version managed by
setuptools_scmbased on git tags - Update CHANGELOG.md before each release (even betas)
- Create annotated tag:
git tag -a 1.2.3 -m 'Release 1.2.3' - Push tag triggers GitHub Actions workflow for PyPI publishing
- Pre-releases must follow PEP 440 format
- Quarto support requires quarto CLI installed
actions.pyhasquarto_inspect()for introspecting projects- Special handling for Quarto projects with Shiny runtime
- Special deployment path for Snowflake Snowpark
SPCSConnectServerclass for Snowflake-specific authentication- JWT generation in
snowflake.py
- Optional MCP support for deploying MCP servers (Python 3.10+)
- Uses
fastmcplibrary when available - See
mcp_deploy_context.pyfor deployment context handling