Skip to content

Commit a3e21a6

Browse files
committed
Adds 'flask' command
1 parent 5735415 commit a3e21a6

File tree

3 files changed

+42
-29
lines changed

3 files changed

+42
-29
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
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
@@ -20,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2021
and `*_app.py` are now considered. However, if the directory contains more than
2122
one file matching these new patterns, you must provide rsconnect-python with an
2223
explicit `--entrypoint` argument.
24+
- Added the `deploy flask` command.
25+
- Added the `write-manifest flask` command.
2326

2427
## [1.20.0] - 2023-09-11
2528

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ you will need to include the `--cacert` option that points to your certificate
117117
authority (CA) trusted certificates file. Both of these options can be saved along
118118
with the URL and API Key for a server.
119119

120-
> **Note**
120+
> **Note**
121121
> When certificate information is saved for the server, the specified file
122122
> is read and its _contents_ are saved under the server's nickname. If the CA file's
123123
> contents are ever changed, you will need to add the server information again.
@@ -135,7 +135,7 @@ rsconnect add \
135135
--name myserver
136136
```
137137

138-
> **Note**
138+
> **Note**
139139
> The `rsconnect` CLI will verify that the serve URL and API key
140140
> are valid. If either is found not to be, no information will be saved.
141141
@@ -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., `gunicorn`, `werkzeug`, `uwsgi`, `pyramid`, and `bottle`)
274+
* `flask`: Flask APIs
275+
* `fastapi`: ASGI-compliant APIs (e.g, `fastapi`, `quart`, `sanic`, and `falcon`)
275276
* `dash`: Python Dash apps
276277
* `streamlit`: Streamlit apps
277278
* `bokeh`: Bokeh server apps
@@ -430,7 +431,7 @@ filename referenced in the manifest.
430431

431432
### Environment variables
432433
You can set environment variables during deployment. Their names and values will be
433-
passed to Posit Connect during deployment so you can use them in your code. Note that
434+
passed to Posit Connect during deployment so you can use them in your code. Note that
434435
if you are using `rsconnect` to deploy to shinyapps.io, environment variable management
435436
is not supported on that platform.
436437

@@ -985,9 +986,9 @@ xargs printf -- '-g %s\n' < guids.txt | xargs rsconnect content build add
985986
```
986987
## Programmatic Provisioning
987988
988-
Posit Connect supports the programmatic bootstrapping of an administrator API key
989+
Posit Connect supports the programmatic bootstrapping of an administrator API key
989990
for scripted provisioning tasks. This process is supported by the `rsconnect bootstrap` command,
990-
which uses a JSON Web Token to request an initial API key from a fresh Connect instance.
991+
which uses a JSON Web Token to request an initial API key from a fresh Connect instance.
991992
992993
> **Warning**
993994
> This feature **requires Python version 3.6 or higher**.
@@ -998,7 +999,7 @@ rsconnect bootstrap \
998999
--jwt-keypath /path/to/secret.key
9991000
```
10001001
1001-
A full description on how to use `rsconnect bootstrap` in a provisioning workflow is provided in the Connect administrator guide's
1002+
A full description on how to use `rsconnect bootstrap` in a provisioning workflow is provided in the Connect administrator guide's
10021003
[programmatic provisioning](https://docs.posit.co/connect/admin/programmatic-provisioning) documentation.
10031004
10041005
## Server Administration Tasks

rsconnect/main.py

Lines changed: 30 additions & 21 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,
@@ -1281,18 +1283,22 @@ def deploy_html(
12811283
)
12821284

12831285

1284-
def generate_deploy_python(app_mode, alias, min_version):
1286+
def generate_deploy_python(app_mode: AppMode, alias: str, min_version: str, desc: Optional[str] = None):
1287+
1288+
if desc is None:
1289+
desc = app_mode.desc()
1290+
12851291
# noinspection SpellCheckingInspection
12861292
@deploy.command(
12871293
name=alias,
12881294
short_help="Deploy a {desc} to Posit Connect [v{version}+], Posit Cloud, or shinyapps.io.".format(
1289-
desc=app_mode.desc(),
1295+
desc=desc,
12901296
version=min_version,
12911297
),
12921298
help=(
12931299
"Deploy a {desc} module to Posit Connect, Posit Cloud, or shinyapps.io (if supported by the platform). "
12941300
'The "directory" argument must refer to an existing directory that contains the application code.'
1295-
).format(desc=app_mode.desc()),
1301+
).format(desc=desc),
12961302
no_args_is_help=True,
12971303
)
12981304
@server_args
@@ -1407,14 +1413,13 @@ def deploy_app(
14071413
return deploy_app
14081414

14091415

1410-
deploy_api = generate_deploy_python(app_mode=AppModes.PYTHON_API, alias="api", min_version="1.8.2")
1411-
# TODO: set fastapi min_version correctly
1412-
# deploy_fastapi = generate_deploy_python(app_mode=AppModes.PYTHON_FASTAPI, alias="fastapi", min_version="2021.08.0")
1413-
deploy_fastapi = generate_deploy_python(app_mode=AppModes.PYTHON_FASTAPI, alias="fastapi", min_version="2021.08.0")
1414-
deploy_dash_app = generate_deploy_python(app_mode=AppModes.DASH_APP, alias="dash", min_version="1.8.2")
1415-
deploy_streamlit_app = generate_deploy_python(app_mode=AppModes.STREAMLIT_APP, alias="streamlit", min_version="1.8.4")
1416-
deploy_bokeh_app = generate_deploy_python(app_mode=AppModes.BOKEH_APP, alias="bokeh", min_version="1.8.4")
1417-
deploy_shiny = generate_deploy_python(app_mode=AppModes.PYTHON_SHINY, alias="shiny", min_version="2022.07.0")
1416+
generate_deploy_python(app_mode=AppModes.PYTHON_API, alias="api", min_version="1.8.2")
1417+
generate_deploy_python(app_mode=AppModes.PYTHON_API, alias="flask", min_version="1.8.2", desc="Flask API")
1418+
generate_deploy_python(app_mode=AppModes.PYTHON_FASTAPI, alias="fastapi", min_version="2021.08.0")
1419+
generate_deploy_python(app_mode=AppModes.DASH_APP, alias="dash", min_version="1.8.2")
1420+
generate_deploy_python(app_mode=AppModes.STREAMLIT_APP, alias="streamlit", min_version="1.8.4")
1421+
generate_deploy_python(app_mode=AppModes.BOKEH_APP, alias="bokeh", min_version="1.8.4")
1422+
generate_deploy_python(app_mode=AppModes.PYTHON_SHINY, alias="shiny", min_version="2022.07.0")
14181423

14191424

14201425
@deploy.command(
@@ -1759,24 +1764,27 @@ def write_manifest_quarto(
17591764
)
17601765

17611766

1762-
def generate_write_manifest_python(app_mode, alias):
1767+
def generate_write_manifest_python(app_mode, alias, desc: Optional[str] = None):
1768+
if desc is None:
1769+
desc = app_mode.desc()
1770+
17631771
# noinspection SpellCheckingInspection
17641772
@write_manifest.command(
17651773
name=alias,
1766-
short_help="Create a manifest.json file for a {desc}.".format(desc=app_mode.desc()),
1774+
short_help="Create a manifest.json file for a {desc}.".format(desc=desc),
17671775
help=(
17681776
"Create a manifest.json file for a {desc} for later deployment. This will create an "
17691777
'environment file ("requirements.txt") if one does not exist. All files '
17701778
"are created in the same directory as the API code."
1771-
).format(desc=app_mode.desc()),
1779+
).format(desc=desc),
17721780
)
17731781
@click.option("--overwrite", "-o", is_flag=True, help="Overwrite manifest.json, if it exists.")
17741782
@click.option(
17751783
"--entrypoint",
17761784
"-e",
17771785
help=(
17781786
"The module and executable object which serves as the entry point for the {desc} (defaults to app)"
1779-
).format(desc=app_mode.desc()),
1787+
).format(desc=desc),
17801788
)
17811789
@click.option(
17821790
"--exclude",
@@ -1850,12 +1858,13 @@ def manifest_writer(
18501858
return manifest_writer
18511859

18521860

1853-
write_manifest_api = generate_write_manifest_python(AppModes.PYTHON_API, alias="api")
1854-
write_manifest_fastapi = generate_write_manifest_python(AppModes.PYTHON_FASTAPI, alias="fastapi")
1855-
write_manifest_dash = generate_write_manifest_python(AppModes.DASH_APP, alias="dash")
1856-
write_manifest_streamlit = generate_write_manifest_python(AppModes.STREAMLIT_APP, alias="streamlit")
1857-
write_manifest_bokeh = generate_write_manifest_python(AppModes.BOKEH_APP, alias="bokeh")
1858-
write_manifest_shiny = generate_write_manifest_python(AppModes.PYTHON_SHINY, alias="shiny")
1861+
generate_write_manifest_python(AppModes.BOKEH_APP, alias="bokeh")
1862+
generate_write_manifest_python(AppModes.DASH_APP, alias="dash")
1863+
generate_write_manifest_python(AppModes.PYTHON_API, alias="api")
1864+
generate_write_manifest_python(AppModes.PYTHON_API, alias="flask", desc="Flask API")
1865+
generate_write_manifest_python(AppModes.PYTHON_FASTAPI, alias="fastapi")
1866+
generate_write_manifest_python(AppModes.PYTHON_SHINY, alias="shiny")
1867+
generate_write_manifest_python(AppModes.STREAMLIT_APP, alias="streamlit")
18591868

18601869

18611870
# noinspection SpellCheckingInspection

0 commit comments

Comments
 (0)