Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
e6ee50f
add jupyter-voila to models
bcwu Aug 23, 2022
d5cab0c
wrtie-manifest for voila
bcwu Aug 23, 2022
ac20ec0
add deploy voila command
bcwu Aug 25, 2022
aa703f8
mimetype inference no longer requires set defaults
bcwu Aug 26, 2022
03d05bc
enable deploying voila by directory
bcwu Aug 26, 2022
0671dd0
update return type
bcwu Aug 26, 2022
f23dfe8
update voila directory deploy to use single code path
bcwu Aug 26, 2022
4914f82
delete unused code path
bcwu Aug 26, 2022
b58cb34
update imports
bcwu Aug 26, 2022
6fdc811
raise entrypoint inference error
bcwu Aug 29, 2022
b3aa3c3
rename pack_relevant_files to pack_extra_files
bcwu Aug 29, 2022
6ef8ae9
add --disable-pip-version-check to pip list
bcwu Aug 29, 2022
e50d94c
add defaults to write_voila_manifest_json
bcwu Aug 29, 2022
564e82a
generate voila requirements when none exists
bcwu Aug 29, 2022
360469c
reduce error massage length for E501
bcwu Aug 29, 2022
1477f9d
shorten error msg further
bcwu Aug 29, 2022
0eab04a
update AppMode description for JUPYTER_VOILA
bcwu Aug 29, 2022
6e4283b
simplify packing steps
bcwu Sep 1, 2022
26be70b
include voila.json automatically
bcwu Sep 1, 2022
8725e9f
correct description of deploy voila
bcwu Sep 9, 2022
0abfe75
remove infer_entrypoint error check
bcwu Sep 13, 2022
f0f5597
update write_voila_manifest_json to handle both file and directory
bcwu Sep 13, 2022
4aedbaf
rename pack_extra_files to create_file_list
bcwu Sep 13, 2022
c4f6887
update make_voila_bundle
bcwu Sep 13, 2022
e0cfe36
update write_manifest_voila
bcwu Sep 13, 2022
e46a6be
Merge branch 'master' into bcwu-voila
bcwu Jan 18, 2023
8f21973
delete old version of create_file_list
bcwu Jan 18, 2023
e5c20d2
specify ipynb mimetype by suffix
bcwu Jan 20, 2023
c18b65b
add Manifest as a class
bcwu Jan 20, 2023
a3f52e7
add Bundle as a class
bcwu Jan 20, 2023
76a3e61
create predecessor to write_voila_manifest_json
bcwu Jan 20, 2023
380f7be
refactor write_voila_manifest_json
bcwu Jan 20, 2023
8fa16a3
refactor make_voila_bundle
bcwu Jan 20, 2023
926a836
add type annotation
bcwu Jan 20, 2023
2a23e92
correct call to manifest.data
bcwu Jan 20, 2023
3e2cb44
entrypoint is in metadata
bcwu Jan 23, 2023
9c75701
make manifest.json a property
bcwu Jan 23, 2023
80eeb79
check metadata when checking entrypoint
bcwu Jan 23, 2023
cd1369f
add file according to relative dir
bcwu Jan 24, 2023
1b6a3a8
enable multi-notebook mode via empty string
bcwu Feb 6, 2023
db97ae4
Merge branch 'master' into bcwu-voila
bcwu Feb 6, 2023
2007e6d
unstage existing validate_extra_files
bcwu Feb 7, 2023
2220e98
refactor validate_extra_files
bcwu Feb 7, 2023
ebcac59
fix create_file_list not excluding when path is a file
bcwu Feb 7, 2023
6a64af0
check voila.json exists before including
bcwu Feb 7, 2023
a536e70
no longer auto prepend base_dir when adding files
bcwu Feb 7, 2023
3058472
Revert "fix create_file_list not excluding when path is a file"
bcwu Feb 7, 2023
39a8765
fix create_file_list not excluding when path is a file
bcwu Feb 7, 2023
d434416
update validate_extra_files to include none case
bcwu Feb 7, 2023
5ee2189
update test_validate_extra_files
bcwu Feb 7, 2023
d76382c
Revert 5ee2189 to 2007e6d
bcwu Feb 7, 2023
5220175
check voila.json exists before including
bcwu Feb 7, 2023
9c18efc
add manifest ability to change files relative to entrypoint
bcwu Feb 7, 2023
69115ae
add Bundle ability to flatten to deploy_dir
bcwu Feb 7, 2023
4cf306b
change if-expression to or
bcwu Feb 7, 2023
e7738e1
store absolute path
bcwu Feb 8, 2023
d0886e7
rename base_dir to deploy_dir in create_voila_manifest
bcwu Feb 8, 2023
b2bae6a
add buffer to Manifest
bcwu Feb 9, 2023
9d29e9e
rename base_dir to deploy_dir in make_voila_bundle
bcwu Feb 9, 2023
ffb730f
add rscException for no valid manifest files
bcwu Feb 9, 2023
fcfbdd0
add buffer to Bundle
bcwu Feb 9, 2023
5adda80
add annotation per mypy
bcwu Feb 9, 2023
d3ea774
use stage_to_deploy for write_voila_manifest_json
bcwu Feb 9, 2023
488a379
replace os.path.relpath wtih relpath
bcwu Feb 9, 2023
cad1ae6
prioritize user provided requirements.txt
bcwu Feb 9, 2023
20257a9
rename stage_to_deploy to flattened_copy
bcwu Feb 10, 2023
075b84a
use create_python_environment
bcwu Feb 10, 2023
dfc9121
return just the file name when path is a file
bcwu Feb 10, 2023
dba24ee
add_relative_path
bcwu Feb 10, 2023
cfb6678
exclude environment files, rely on Environment
bcwu Feb 10, 2023
0402f46
Merge branch 'master' into bcwu-voila
bcwu Feb 13, 2023
4f6d7ae
Merge branch 'master' into bcwu-voila
bcwu Feb 13, 2023
355b2c1
use directory for list_environment_dirs
bcwu Feb 14, 2023
b3bcef6
use abspath on entrypoint
bcwu Feb 14, 2023
ce06ff6
add exclude to deploy_voila
bcwu Feb 14, 2023
69cf3f0
check parent dir for exclude
bcwu Feb 14, 2023
8675207
split candidates from infer_entrypoint
bcwu Feb 15, 2023
968e535
fix lack of CLI entrypoint for deploy_voila
bcwu Feb 16, 2023
cdd27b1
manifest rewrite for multi-notebook mode
bcwu Feb 16, 2023
a20c89f
set json dumps indent
bcwu Feb 16, 2023
6ba4a38
do not write manifest.json when bundling
bcwu Feb 16, 2023
e507f10
validate_extra_files when directly writing manifest
bcwu Feb 16, 2023
0a3c5db
add guess_deploy_dir & abs_entrypoint
bcwu Feb 16, 2023
90ce286
add --multi-notebook flag
bcwu Feb 16, 2023
5d72f6f
Move validation to create_voila_manifest
bcwu Feb 16, 2023
5eccf33
relax entrypoint check for multi-notebook
bcwu Feb 17, 2023
8311a1e
no_args_is_help & update Connect version
bcwu Feb 17, 2023
0165f23
More deploy_dir checks
bcwu Feb 17, 2023
008bd2f
update guess_deploy_dir
bcwu Feb 17, 2023
9ca2011
add voila test files
bcwu Feb 20, 2023
23ec32d
remove exception in infer_entrypoint_candidates
bcwu Feb 20, 2023
e2a0476
add exception if Manifest cannot be flattened
bcwu Feb 20, 2023
96b61d7
check valid path in create_voila_manifest
bcwu Feb 20, 2023
d111e8e
update multi_notebook check
bcwu Feb 20, 2023
a092e58
add voila multi-notebook test files
bcwu Feb 20, 2023
a74cf5b
add voila unit tests
bcwu Feb 20, 2023
294991c
add more voila test folder
bcwu Feb 24, 2023
82315e5
fix entrypoint not made with abspath
bcwu Feb 24, 2023
5dddfcb
add more voila bundle test
bcwu Feb 24, 2023
6a2973a
add abs_entrypoint when entrypoint_candidates==0
bcwu Feb 24, 2023
60fe87f
Update Connect version required to v2023.03.0+
bcwu Mar 1, 2023
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
473 changes: 458 additions & 15 deletions rsconnect/bundle.py

Large diffs are not rendered by default.

208 changes: 208 additions & 0 deletions rsconnect/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@
make_api_bundle,
make_notebook_html_bundle,
make_notebook_source_bundle,
make_voila_bundle,
read_manifest_app_mode,
write_notebook_manifest_json,
write_api_manifest_json,
write_environment_file,
write_quarto_manifest_json,
write_voila_manifest_json,
validate_entry_point,
validate_extra_files,
validate_file_is_notebook,
Expand Down Expand Up @@ -842,6 +844,108 @@ def deploy_notebook(
ce.deploy_bundle().save_deployed_info().emit_task_log()


# noinspection SpellCheckingInspection,DuplicatedCode
@deploy.command(
name="voila",
short_help="Deploy Jupyter notebook in Voila mode to RStudio Connect [v2023.03.0+].",
help=("Deploy a Jupyter notebook in Voila mode to RStudio Connect."),
no_args_is_help=True,
)
@server_args
@content_args
@click.option(
"--entrypoint",
"-e",
help=("The module and executable object which serves as the entry point."),
)
@click.option(
"--multi-notebook",
"-m",
is_flag=True,
help=("Deploy in multi-notebook mode."),
)
@click.option(
"--exclude",
"-x",
multiple=True,
help=(
"Specify a glob pattern for ignoring files when building the bundle. Note that your shell may try "
"to expand this which will not do what you expect. Generally, it's safest to quote the pattern. "
"This option may be repeated."
),
)
@click.option(
"--python",
"-p",
type=click.Path(exists=True),
help=(
"Path to Python interpreter whose environment should be used. "
"The Python environment must have the rsconnect package installed."
),
)
@click.option(
"--force-generate",
"-g",
is_flag=True,
help='Force generating "requirements.txt", even if it already exists.',
)
@click.option(
"--image",
"-I",
help="Target image to be used during content execution (only applicable if the RStudio Connect "
"server is configured to use off-host execution)",
)
@click.argument("path", type=click.Path(exists=True, dir_okay=True, file_okay=True))
@click.argument(
"extra_files",
nargs=-1,
type=click.Path(exists=True, dir_okay=False, file_okay=True),
)
@cli_exception_handler
def deploy_voila(
path: str = None,
entrypoint: str = None,
python=None,
force_generate=False,
extra_files=None,
exclude=None,
image: str = "",
title: str = None,
env_vars: typing.Dict[str, str] = None,
verbose: bool = False,
new: bool = False,
app_id: str = None,
name: str = None,
server: str = None,
api_key: str = None,
insecure: bool = False,
cacert: typing.IO = None,
connect_server: api.RSConnectServer = None,
multi_notebook: bool = False,
):
kwargs = locals()
set_verbosity(verbose)
app_mode = AppModes.JUPYTER_VOILA
kwargs["extra_files"] = extra_files = validate_extra_files(dirname(path), extra_files)
environment = create_python_environment(
path if isdir(path) else dirname(path),
force_generate,
python,
)
ce = RSConnectExecutor(**kwargs).validate_server().validate_app_mode(app_mode=app_mode)
ce.make_bundle(
make_voila_bundle,
path,
entrypoint,
extra_files,
exclude,
force_generate,
environment,
image=image,
multi_notebook=multi_notebook,
).deploy_bundle().save_deployed_info().emit_task_log()


# noinspection SpellCheckingInspection,DuplicatedCode
@deploy.command(
name="manifest",
Expand Down Expand Up @@ -1358,6 +1462,110 @@ def write_manifest_notebook(
write_environment_file(environment, base_dir)


@write_manifest.command(
name="voila",
short_help="Create a manifest.json file for a Voila notebook.",
help=(
"Create a manifest.json file for a Voila notebook for later deployment. "
'This will create an environment file ("requirements.txt") if one does '
"not exist. All files are created in the same directory as the notebook file."
),
)
@click.option("--overwrite", "-o", is_flag=True, help="Overwrite manifest.json, if it exists.")
@click.option(
"--python",
"-p",
type=click.Path(exists=True),
help="Path to Python interpreter whose environment should be used. "
+ "The Python environment must have the rsconnect package installed.",
)
@click.option(
"--force-generate",
"-g",
is_flag=True,
help='Force generating "requirements.txt", even if it already exists.',
)
@click.option("--verbose", "-v", "verbose", is_flag=True, help="Print detailed messages")
@click.option(
"--image",
"-I",
help="Target image to be used during content execution (only applicable if the RStudio Connect "
"server is configured to use off-host execution)",
)
@click.argument("path", type=click.Path(exists=True, dir_okay=True, file_okay=True))
@click.argument(
"extra_files",
nargs=-1,
type=click.Path(exists=True, dir_okay=False, file_okay=True),
)
@click.option("--entrypoint", "-e", help=("The module and executable object which serves as the entry point."))
@click.option(
"--exclude",
"-x",
multiple=True,
help=(
"Specify a glob pattern for ignoring files when building the bundle. Note that your shell may try "
"to expand this which will not do what you expect. Generally, it's safest to quote the pattern. "
"This option may be repeated."
),
)
@click.option(
"--multi-notebook",
"-m",
is_flag=True,
help=("Set the manifest for multi-notebook mode."),
)
def write_manifest_voila(
path: str,
entrypoint: str,
overwrite,
python,
force_generate,
verbose,
extra_files,
exclude,
image,
multi_notebook,
):
set_verbosity(verbose)
with cli_feedback("Checking arguments"):
base_dir = dirname(path)
extra_files = validate_extra_files(base_dir, extra_files)
manifest_path = join(base_dir, "manifest.json")

if exists(manifest_path) and not overwrite:
raise RSConnectException("manifest.json already exists. Use --overwrite to overwrite.")

with cli_feedback("Inspecting Python environment"):
python, environment = get_python_env_info(path, python, False, force_generate)

_warn_on_ignored_conda_env(environment)

environment_file_exists = exists(join(base_dir, environment.filename))

if environment_file_exists and not force_generate:
click.secho(
" Warning: %s already exists and will not be overwritten." % environment.filename,
fg="yellow",
)
else:
with cli_feedback("Creating %s" % environment.filename):
write_environment_file(environment, base_dir)

with cli_feedback("Creating manifest.json"):
write_voila_manifest_json(
path,
entrypoint,
environment,
AppModes.JUPYTER_VOILA,
extra_files,
exclude,
force_generate,
image,
multi_notebook,
)


@write_manifest.command(
name="quarto",
short_help="Create a manifest.json file for Quarto content.",
Expand Down
2 changes: 2 additions & 0 deletions rsconnect/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class AppModes(object):
SHINY_QUARTO = AppMode(13, "quarto-shiny", "Shiny Quarto Document")
STATIC_QUARTO = AppMode(14, "quarto-static", "Quarto Document", ".qmd")
PYTHON_SHINY = AppMode(15, "python-shiny", "Python Shiny Application")
JUPYTER_VOILA = AppMode(16, "jupyter-voila", "Jupyter Voila Application")

_modes = [
UNKNOWN,
Expand All @@ -96,6 +97,7 @@ class AppModes(object):
SHINY_QUARTO,
STATIC_QUARTO,
PYTHON_SHINY,
JUPYTER_VOILA,
]

_cloud_to_connect_modes = {
Expand Down
Loading