diff --git a/extensions/vscode/src/api/types/configurations.ts b/extensions/vscode/src/api/types/configurations.ts index 2e883f088..79c626655 100644 --- a/extensions/vscode/src/api/types/configurations.ts +++ b/extensions/vscode/src/api/types/configurations.ts @@ -53,6 +53,7 @@ export enum ContentType { PYTHON_FLASK = "python-flask", PYTHON_SHINY = "python-shiny", PYTHON_STREAMLIT = "python-streamlit", + PYTHON_GRADIO = "python-gradio", QUARTO_SHINY = "quarto-shiny", QUARTO = "quarto", R_PLUMBER = "r-plumber", @@ -72,6 +73,7 @@ export const allValidContentTypes: ContentType[] = [ ContentType.PYTHON_FLASK, ContentType.PYTHON_SHINY, ContentType.PYTHON_STREAMLIT, + ContentType.PYTHON_GRADIO, ContentType.QUARTO_SHINY, ContentType.QUARTO, ContentType.R_PLUMBER, @@ -90,6 +92,7 @@ export const contentTypeStrings = { [ContentType.PYTHON_FLASK]: "run with Flask", [ContentType.PYTHON_SHINY]: "run with Python Shiny", [ContentType.PYTHON_STREAMLIT]: "run with Streamlit", + [ContentType.PYTHON_GRADIO]: "run with Gradio", [ContentType.QUARTO_SHINY]: "render with Quarto and run embedded Shiny app", [ContentType.QUARTO]: "render with Quarto", [ContentType.R_PLUMBER]: "run with Plumber", diff --git a/internal/clients/connect/apptypes.go b/internal/clients/connect/apptypes.go index 7c3164eee..f7f1f3832 100644 --- a/internal/clients/connect/apptypes.go +++ b/internal/clients/connect/apptypes.go @@ -24,6 +24,7 @@ const ( PythonStreamlitMode AppMode = "python-streamlit" PythonBokehMode AppMode = "python-bokeh" PythonFastAPIMode AppMode = "python-fastapi" + PythonGradioMode AppMode = "python-gradio" ShinyQuartoMode AppMode = "quarto-shiny" StaticQuartoMode AppMode = "quarto-static" PythonShinyMode AppMode = "python-shiny" @@ -61,6 +62,8 @@ func AppModeFromString(s string) (AppMode, error) { return PythonBokehMode, nil case "python-fastapi", "fastapi", "asgi": return PythonFastAPIMode, nil + case "python-gradio", "gradio": + return PythonGradioMode, nil case "python-shiny", "pyshiny": return PythonShinyMode, nil case "quarto-shiny": @@ -88,7 +91,7 @@ func (mode *AppMode) UnmarshalText(text []byte) error { // IsWorkerApp returns true for any content that is serviced by worker // processes. This includes Shiny applications, interactive R Markdown // documents, Plumber/Python (flask/fastapi) APIs, and Python apps -// (Dash, Streamlit, Bokeh, PyShiny, Voila). +// (Dash, Streamlit, Bokeh, PyShiny, Voila, Gradio). func (mode AppMode) IsWorkerApp() bool { return (mode.IsShinyApp() || mode.IsPythonApp() || @@ -113,7 +116,7 @@ func (mode AppMode) IsPythonAPI() bool { // IsPythonApp returns true for Python applications (Dash, Streamlit, Bokeh, Voila) func (mode AppMode) IsPythonApp() bool { switch mode { - case PythonDashMode, PythonStreamlitMode, PythonShinyMode, PythonBokehMode, JupyterVoilaMode: + case PythonDashMode, PythonStreamlitMode, PythonGradioMode, PythonShinyMode, PythonBokehMode, JupyterVoilaMode: return true } return false @@ -140,6 +143,11 @@ func (t AppMode) IsBokehApp() bool { return t == PythonBokehMode } +// IsGradioApp returns true for Python Gradio applications +func (t AppMode) IsGradioApp() bool { + return t == PythonGradioMode +} + // IsFastAPIApp returns true for Python FastAPI applications func (t AppMode) IsFastAPIApp() bool { return t == PythonFastAPIMode @@ -190,7 +198,7 @@ func (t AppMode) IsRContent() bool { // content type. func (t AppMode) IsPythonContent() bool { switch t { - case StaticJupyterMode, PythonAPIMode, PythonDashMode, PythonStreamlitMode, PythonBokehMode, PythonFastAPIMode, PythonShinyMode, JupyterVoilaMode: + case StaticJupyterMode, PythonAPIMode, PythonDashMode, PythonStreamlitMode, PythonBokehMode, PythonFastAPIMode, PythonGradioMode, PythonShinyMode, JupyterVoilaMode: return true } return false @@ -232,6 +240,8 @@ func (t AppMode) Description() string { return "Bokeh application" case PythonFastAPIMode: return "FastAPI application" + case PythonGradioMode: + return "Gradio application" case PythonShinyMode: return "Python Shiny application" case ShinyQuartoMode: @@ -255,6 +265,7 @@ var connectContentTypeMap = map[config.ContentType]AppMode{ config.ContentTypePythonFlask: PythonAPIMode, config.ContentTypePythonShiny: PythonShinyMode, config.ContentTypePythonStreamlit: PythonStreamlitMode, + config.ContentTypePythonGradio: PythonGradioMode, config.ContentTypeQuartoShiny: ShinyQuartoMode, config.ContentTypeQuarto: StaticQuartoMode, config.ContentTypeRPlumber: PlumberAPIMode, @@ -279,6 +290,7 @@ var contentTypeConnectMap = map[AppMode]config.ContentType{ PythonDashMode: config.ContentTypePythonDash, PythonFastAPIMode: config.ContentTypePythonFastAPI, PythonAPIMode: config.ContentTypePythonFlask, + PythonGradioMode: config.ContentTypePythonGradio, PythonShinyMode: config.ContentTypePythonShiny, PythonStreamlitMode: config.ContentTypePythonStreamlit, ShinyQuartoMode: config.ContentTypeQuartoShiny, diff --git a/internal/clients/connect/apptypes_test.go b/internal/clients/connect/apptypes_test.go index 3a5c0296c..40c69ec1b 100644 --- a/internal/clients/connect/apptypes_test.go +++ b/internal/clients/connect/apptypes_test.go @@ -36,6 +36,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp bool BokehApp bool FastAPIApp bool + GradioApp bool PyShinyApp bool VoilaApp bool StaticRmd bool @@ -58,6 +59,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -79,6 +81,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -100,6 +103,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -121,6 +125,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: true, @@ -142,6 +147,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -163,6 +169,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -184,6 +191,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -205,6 +213,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -226,6 +235,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -247,6 +257,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: true, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -268,6 +279,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: true, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -289,6 +301,29 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: true, + GradioApp: false, + PyShinyApp: false, + VoilaApp: false, + StaticRmd: false, + StaticJupyter: false, + StaticReport: false, + StaticContent: false, + }, { + Mode: PythonGradioMode, + RContent: false, + PythonContent: true, + QuartoContent: false, + WorkerApp: true, + APIApp: false, + PlumberAPI: false, + PythonAPI: false, + PythonApp: true, + ShinyApp: false, + DashApp: false, + StreamlitApp: false, + BokehApp: false, + FastAPIApp: false, + GradioApp: true, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -310,6 +345,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -331,6 +367,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: false, StaticRmd: false, @@ -352,6 +389,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: true, VoilaApp: false, StaticRmd: false, @@ -373,6 +411,7 @@ func (s *AppTypesSuite) TestAppMode() { StreamlitApp: false, BokehApp: false, FastAPIApp: false, + GradioApp: false, PyShinyApp: false, VoilaApp: true, StaticRmd: false, @@ -396,6 +435,7 @@ func (s *AppTypesSuite) TestAppMode() { s.Equal(each.StreamlitApp, each.Mode.IsStreamlitApp(), comment) s.Equal(each.BokehApp, each.Mode.IsBokehApp(), comment) s.Equal(each.FastAPIApp, each.Mode.IsFastAPIApp(), comment) + s.Equal(each.GradioApp, each.Mode.IsGradioApp(), comment) s.Equal(each.PyShinyApp, each.Mode.IsPyShinyApp(), comment) s.Equal(each.VoilaApp, each.Mode.IsVoilaApp(), comment) s.Equal(each.StaticRmd, each.Mode.IsStaticRmd(), comment) @@ -422,6 +462,7 @@ func (s *AppTypesSuite) TestAppModeStrings() { {PythonStreamlitMode, "python-streamlit"}, {PythonBokehMode, "python-bokeh"}, {PythonFastAPIMode, "python-fastapi"}, + {PythonGradioMode, "python-gradio"}, {ShinyQuartoMode, "quarto-shiny"}, {StaticQuartoMode, "quarto-static"}, {PythonShinyMode, "python-shiny"}, @@ -476,6 +517,7 @@ func (s *AppTypesSuite) TestDescription() { {PythonStreamlitMode, "Streamlit application"}, {PythonBokehMode, "Bokeh application"}, {PythonFastAPIMode, "FastAPI application"}, + {PythonGradioMode, "Gradio application"}, {ShinyQuartoMode, "Shiny Quarto document"}, {StaticQuartoMode, "Quarto document"}, {PythonShinyMode, "Python Shiny application"}, diff --git a/internal/config/types.go b/internal/config/types.go index d54ecce27..a02b2ca42 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -14,6 +14,7 @@ const ( ContentTypePythonFlask ContentType = "python-flask" ContentTypePythonShiny ContentType = "python-shiny" ContentTypePythonStreamlit ContentType = "python-streamlit" + ContentTypePythonGradio ContentType = "python-gradio" ContentTypeQuartoShiny ContentType = "quarto-shiny" ContentTypeQuarto ContentType = "quarto" ContentTypeRPlumber ContentType = "r-plumber" @@ -32,6 +33,7 @@ func AllValidContentTypeNames() []string { string(ContentTypePythonDash), string(ContentTypePythonFastAPI), string(ContentTypePythonFlask), + string(ContentTypePythonGradio), string(ContentTypePythonShiny), string(ContentTypePythonStreamlit), string(ContentTypeQuartoShiny), @@ -53,6 +55,7 @@ func (t ContentType) IsPythonContent() bool { ContentTypePythonDash, ContentTypePythonFastAPI, ContentTypePythonFlask, + ContentTypePythonGradio, ContentTypePythonShiny, ContentTypePythonStreamlit: return true @@ -76,6 +79,7 @@ func (t ContentType) IsAppContent() bool { ContentTypeRShiny, ContentTypePythonBokeh, ContentTypePythonDash, + ContentTypePythonGradio, ContentTypePythonStreamlit: return true } diff --git a/internal/schema/schemas/posit-publishing-record-schema-v3.json b/internal/schema/schemas/posit-publishing-record-schema-v3.json index 06447f104..62b02bf24 100644 --- a/internal/schema/schemas/posit-publishing-record-schema-v3.json +++ b/internal/schema/schemas/posit-publishing-record-schema-v3.json @@ -40,7 +40,7 @@ }, "type": { "type": "string", - "description": "Indicates the type of content. Valid values are: html, jupyter-notebook, jupyter-voila, python-bokeh, python-dash, python-fastapi, python-flask, python-shiny, python-streamlit, quarto-shiny, quarto, r-plumber, r-shiny, rmd-shiny, rmd", + "description": "Indicates the type of content. Valid values are: html, jupyter-notebook, jupyter-voila, python-bokeh, python-dash, python-fastapi, python-flask, python-gradio, python-shiny, python-streamlit, quarto-shiny, quarto, r-plumber, r-shiny, rmd-shiny, rmd", "enum": [ "", "html", @@ -50,6 +50,7 @@ "python-dash", "python-fastapi", "python-flask", + "python-gradio", "python-shiny", "python-streamlit", "quarto-shiny", diff --git a/internal/schema/schemas/posit-publishing-schema-v3.json b/internal/schema/schemas/posit-publishing-schema-v3.json index c611823a5..a642307e2 100644 --- a/internal/schema/schemas/posit-publishing-schema-v3.json +++ b/internal/schema/schemas/posit-publishing-schema-v3.json @@ -26,7 +26,7 @@ }, "type": { "type": "string", - "description": "Indicates the type of content being deployed. Valid values are: html, jupyter-notebook, jupyter-voila, python-bokeh, python-dash, python-fastapi, python-flask, python-shiny, python-streamlit, quarto-shiny, quarto, r-plumber, r-shiny, rmd-shiny, rmd", + "description": "Indicates the type of content being deployed. Valid values are: html, jupyter-notebook, jupyter-voila, python-bokeh, python-dash, python-fastapi, python-flask, python-gradio, python-shiny, python-streamlit, quarto-shiny, quarto, r-plumber, r-shiny, rmd-shiny, rmd", "enum": [ "html", "jupyter-notebook", @@ -35,6 +35,7 @@ "python-dash", "python-fastapi", "python-flask", + "python-gradio", "python-shiny", "python-streamlit", "quarto-shiny",