@@ -23,13 +23,55 @@ class FileContentJson(TypedDict):
2323 type : NotRequired [Literal ["text" , "binary" ]]
2424
2525
26- def encode_shinylive_url (
27- app : str | Path ,
28- files : Optional [str | Path | Sequence [str | Path ]] = None ,
26+ class AppBundle (TypedDict ):
27+ language : Literal ["py" , "r" ]
28+ files : list [FileContentJson ]
29+
30+
31+ def create_shinylive_url (
32+ bundle : AppBundle ,
2933 mode : Literal ["editor" , "app" ] = "editor" ,
30- language : Optional [Literal ["py" , "r" ]] = None ,
3134 header : bool = True ,
3235) -> str :
36+ """ """
37+
38+ file_lz = lzstring_file_bundle (bundle ["files" ])
39+
40+ base = "https://shinylive.io"
41+ h = "h=0&" if not header and mode == "app" else ""
42+
43+ return f"{ base } /{ bundle ['language' ]} /{ mode } /#{ h } code={ file_lz } "
44+
45+
46+ def create_shinylive_bundle_text (
47+ app : str ,
48+ files : Optional [str | Path | Sequence [str | Path ]] = None ,
49+ language : Optional [Literal ["py" , "r" ]] = None ,
50+ root_dir : str | Path = "." ,
51+ ) -> AppBundle :
52+ if language is None :
53+ language = detect_app_language (app )
54+ elif language not in ["py" , "r" ]:
55+ raise ValueError (
56+ f"Language '{ language } ' is not supported. Please specify one of 'py' or 'r'."
57+ )
58+
59+ app_fc : FileContentJson = {
60+ "name" : f"app.{ 'py' if language == 'py' else 'R' } " ,
61+ "content" : app ,
62+ }
63+
64+ return {
65+ "language" : language ,
66+ "files" : add_supporting_files_to_bundle (app_fc , files , root_dir ),
67+ }
68+
69+
70+ def create_shinylive_bundle_file (
71+ app : str | Path ,
72+ files : Optional [str | Path | Sequence [str | Path ]] = None ,
73+ language : Optional [Literal ["py" , "r" ]] = None ,
74+ ) -> AppBundle :
3375 """
3476 Generate a URL for a [ShinyLive application](https://shinylive.io).
3577
@@ -57,20 +99,34 @@ def encode_shinylive_url(
5799
58100 if language is None :
59101 language = detect_app_language (app )
102+ elif language not in ["py" , "r" ]:
103+ raise ValueError (
104+ f"Language '{ language } ' is not supported. Please specify one of 'py' or 'r'."
105+ )
60106
61- # if app has a newline, then it's app content, not a path
62- if isinstance (app , str ) and "\n " in app :
63- app_path = ""
64- root_dir = Path ("." )
65- app_fc : FileContentJson = {
66- "name" : f"app.{ 'py' if language == 'py' else 'R' } " ,
67- "content" : app ,
68- }
69- file_bundle = [app_fc ]
70- else :
71- app_path = Path (app )
72- root_dir = app_path .parent
73- file_bundle = [read_file (app , root_dir )]
107+ app_path = Path (app )
108+ root_dir = app_path .parent
109+ app_fc = read_file (app , root_dir )
110+
111+ # if the app is not named either `ui.R` or `server.R`, then make it app.py or app.R
112+ if app_fc ["name" ] not in ["ui.R" , "server.R" ]:
113+ app_fc ["name" ] = f"app.{ 'py' if language == 'py' else 'R' } "
114+
115+ return {
116+ "language" : language ,
117+ "files" : add_supporting_files_to_bundle (app_fc , files , root_dir , app_path ),
118+ }
119+
120+
121+ def add_supporting_files_to_bundle (
122+ app : FileContentJson ,
123+ files : Optional [str | Path | Sequence [str | Path ]] = None ,
124+ root_dir : str | Path = "." ,
125+ app_path : str | Path = "" ,
126+ ) -> list [FileContentJson ]:
127+ app_path = Path (app_path )
128+
129+ file_bundle = [app ]
74130
75131 if isinstance (files , (str , Path )):
76132 files = [files ]
@@ -88,21 +144,7 @@ def encode_shinylive_url(
88144 read_file (file , root_dir ) for file in file_list if Path (file ) != app_path
89145 ]
90146
91- if language not in ["py" , "r" ]:
92- raise ValueError (
93- f"Language '{ language } ' is not supported. Please specify one of 'py' or 'r'."
94- )
95-
96- # if first file is not named either `ui.R` or `server.R`, then make it app.{language}
97- if file_bundle [0 ]["name" ] not in ["ui.R" , "server.R" ]:
98- file_bundle [0 ]["name" ] = f"app.{ 'py' if language == 'py' else 'R' } "
99-
100- file_lz = lzstring_file_bundle (file_bundle )
101-
102- base = "https://shinylive.io"
103- h = "h=0&" if not header and mode == "app" else ""
104-
105- return f"{ base } /{ language } /{ mode } /#{ h } code={ file_lz } "
147+ return file_bundle
106148
107149
108150def detect_app_language (app : str | Path ) -> Literal ["py" , "r" ]:
0 commit comments