Skip to content

Commit b6cbcbc

Browse files
authored
Merge pull request #499 from rstudio/tdstein/491
Adds 'flask' sub-command
2 parents 175a4c3 + 0d163a3 commit b6cbcbc

File tree

3 files changed

+38
-25
lines changed

3 files changed

+38
-25
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
33

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).
6+
67
## Unreleased
78

89
### Fixed
@@ -26,10 +27,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2627
recognized filename patterns, the file patterns `app-*.py`, `app_*.py`, `*-app.py`,
2728
and `*_app.py` are now considered. However, if the directory contains more than
2829
one file matching these new patterns, you must provide rsconnect-python with an
29-
explicit `--entrypoint` argument.
30+
explicit `--entrypoint` argument.\
3031
- Added a new verbose logging level. Specifying `-v` on the command line uses this
3132
new level. Currently this will cause filenames to be logged as they are added to
3233
a bundle. To enable maximum verbosity (debug level), use `-vv`.
34+
- Added the `deploy flask` command.
35+
- Added the `write-manifest flask` command.
3336

3437
### Changed
3538
- Removing experimental support for Conda. Connect does not support restoring Conda environments.

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,9 @@ rsconnect write-manifest notebook my-notebook.ipynb
270270
You can deploy a variety of APIs and applications using sub-commands of the
271271
`rsconnect deploy` command.
272272

273-
* `api`: WSGI-compliant APIs such as Flask and packages based on Flask
274-
* `fastapi`: ASGI-compliant APIs (FastAPI, Quart, Sanic, and Falcon)
273+
* `api`: WSGI-compliant APIs (e.g., `bottle`, `falcon`, `flask`, `flask-restx`, `flasgger`, `pycnic`).
274+
* `flask`: Flask APIs (_Note: `flask` is an alias of `api`._).
275+
* `fastapi`: ASGI-compliant APIs (e.g, `fastapi`, `quart`, `sanic`, `starlette`)
275276
* `dash`: Python Dash apps
276277
* `streamlit`: Streamlit apps
277278
* `bokeh`: Bokeh server apps

rsconnect/main.py

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import click
99
from os.path import abspath, dirname, exists, isdir, join
1010
from functools import wraps
11+
from typing import Optional
1112

1213
from rsconnect.certificates import read_certificate_file
1314

@@ -65,6 +66,7 @@
6566
from .log import logger, LogOutputFormat
6667
from .metadata import ServerStore, AppStore
6768
from .models import (
69+
AppMode,
6870
AppModes,
6971
BuildStatus,
7072
ContentGuidWithBundleParamType,
@@ -1254,18 +1256,22 @@ def deploy_html(
12541256
)
12551257

12561258

1257-
def generate_deploy_python(app_mode, alias, min_version):
1259+
def generate_deploy_python(app_mode: AppMode, alias: str, min_version: str, desc: Optional[str] = None):
1260+
1261+
if desc is None:
1262+
desc = app_mode.desc()
1263+
12581264
# noinspection SpellCheckingInspection
12591265
@deploy.command(
12601266
name=alias,
12611267
short_help="Deploy a {desc} to Posit Connect [v{version}+], Posit Cloud, or shinyapps.io.".format(
1262-
desc=app_mode.desc(),
1268+
desc=desc,
12631269
version=min_version,
12641270
),
12651271
help=(
12661272
"Deploy a {desc} module to Posit Connect, Posit Cloud, or shinyapps.io (if supported by the platform). "
12671273
'The "directory" argument must refer to an existing directory that contains the application code.'
1268-
).format(desc=app_mode.desc()),
1274+
).format(desc=desc),
12691275
no_args_is_help=True,
12701276
)
12711277
@server_args
@@ -1277,7 +1283,7 @@ def generate_deploy_python(app_mode, alias, min_version):
12771283
"-e",
12781284
help=(
12791285
"The module and executable object which serves as the entry point for the {desc} (defaults to app)"
1280-
).format(desc=app_mode.desc()),
1286+
).format(desc=desc),
12811287
)
12821288
@click.option(
12831289
"--exclude",
@@ -1372,14 +1378,13 @@ def deploy_app(
13721378
return deploy_app
13731379

13741380

1375-
deploy_api = generate_deploy_python(app_mode=AppModes.PYTHON_API, alias="api", min_version="1.8.2")
1376-
# TODO: set fastapi min_version correctly
1377-
# deploy_fastapi = generate_deploy_python(app_mode=AppModes.PYTHON_FASTAPI, alias="fastapi", min_version="2021.08.0")
1378-
deploy_fastapi = generate_deploy_python(app_mode=AppModes.PYTHON_FASTAPI, alias="fastapi", min_version="2021.08.0")
1379-
deploy_dash_app = generate_deploy_python(app_mode=AppModes.DASH_APP, alias="dash", min_version="1.8.2")
1380-
deploy_streamlit_app = generate_deploy_python(app_mode=AppModes.STREAMLIT_APP, alias="streamlit", min_version="1.8.4")
1381-
deploy_bokeh_app = generate_deploy_python(app_mode=AppModes.BOKEH_APP, alias="bokeh", min_version="1.8.4")
1382-
deploy_shiny = generate_deploy_python(app_mode=AppModes.PYTHON_SHINY, alias="shiny", min_version="2022.07.0")
1381+
generate_deploy_python(app_mode=AppModes.PYTHON_API, alias="api", min_version="1.8.2")
1382+
generate_deploy_python(app_mode=AppModes.PYTHON_API, alias="flask", min_version="1.8.2", desc="Flask API")
1383+
generate_deploy_python(app_mode=AppModes.PYTHON_FASTAPI, alias="fastapi", min_version="2021.08.0")
1384+
generate_deploy_python(app_mode=AppModes.DASH_APP, alias="dash", min_version="1.8.2")
1385+
generate_deploy_python(app_mode=AppModes.STREAMLIT_APP, alias="streamlit", min_version="1.8.4")
1386+
generate_deploy_python(app_mode=AppModes.BOKEH_APP, alias="bokeh", min_version="1.8.4")
1387+
generate_deploy_python(app_mode=AppModes.PYTHON_SHINY, alias="shiny", min_version="2022.07.0")
13831388

13841389

13851390
@deploy.command(
@@ -1711,24 +1716,27 @@ def write_manifest_quarto(
17111716
)
17121717

17131718

1714-
def generate_write_manifest_python(app_mode, alias):
1719+
def generate_write_manifest_python(app_mode, alias, desc: Optional[str] = None):
1720+
if desc is None:
1721+
desc = app_mode.desc()
1722+
17151723
# noinspection SpellCheckingInspection
17161724
@write_manifest.command(
17171725
name=alias,
1718-
short_help="Create a manifest.json file for a {desc}.".format(desc=app_mode.desc()),
1726+
short_help="Create a manifest.json file for a {desc}.".format(desc=desc),
17191727
help=(
17201728
"Create a manifest.json file for a {desc} for later deployment. This will create an "
17211729
'environment file ("requirements.txt") if one does not exist. All files '
17221730
"are created in the same directory as the API code."
1723-
).format(desc=app_mode.desc()),
1731+
).format(desc=desc),
17241732
)
17251733
@click.option("--overwrite", "-o", is_flag=True, help="Overwrite manifest.json, if it exists.")
17261734
@click.option(
17271735
"--entrypoint",
17281736
"-e",
17291737
help=(
17301738
"The module and executable object which serves as the entry point for the {desc} (defaults to app)"
1731-
).format(desc=app_mode.desc()),
1739+
).format(desc=desc),
17321740
)
17331741
@click.option(
17341742
"--exclude",
@@ -1793,12 +1801,13 @@ def manifest_writer(
17931801
return manifest_writer
17941802

17951803

1796-
write_manifest_api = generate_write_manifest_python(AppModes.PYTHON_API, alias="api")
1797-
write_manifest_fastapi = generate_write_manifest_python(AppModes.PYTHON_FASTAPI, alias="fastapi")
1798-
write_manifest_dash = generate_write_manifest_python(AppModes.DASH_APP, alias="dash")
1799-
write_manifest_streamlit = generate_write_manifest_python(AppModes.STREAMLIT_APP, alias="streamlit")
1800-
write_manifest_bokeh = generate_write_manifest_python(AppModes.BOKEH_APP, alias="bokeh")
1801-
write_manifest_shiny = generate_write_manifest_python(AppModes.PYTHON_SHINY, alias="shiny")
1804+
generate_write_manifest_python(AppModes.BOKEH_APP, alias="bokeh")
1805+
generate_write_manifest_python(AppModes.DASH_APP, alias="dash")
1806+
generate_write_manifest_python(AppModes.PYTHON_API, alias="api")
1807+
generate_write_manifest_python(AppModes.PYTHON_API, alias="flask", desc="Flask API")
1808+
generate_write_manifest_python(AppModes.PYTHON_FASTAPI, alias="fastapi")
1809+
generate_write_manifest_python(AppModes.PYTHON_SHINY, alias="shiny")
1810+
generate_write_manifest_python(AppModes.STREAMLIT_APP, alias="streamlit")
18021811

18031812

18041813
# noinspection SpellCheckingInspection

0 commit comments

Comments
 (0)