@@ -359,6 +359,32 @@ def run_app(
359359
360360 reload_args : ReloadArgs = {}
361361 if reload :
362+ if shiny_bookmarks_folder_name in reload_excludes :
363+ # Related: https://github.com/posit-dev/py-shiny/pull/1950
364+ #
365+ # Temp hack to work around uvicorn
366+ # https://github.com/encode/uvicorn/pull/2602 which will incorrectly reload
367+ # an app if any matching files in `RELOAD_INCLUDES_DEFAULT` (e.g. `*.png`)
368+ # are uploaded within `shiny_bookmarks` (an excluded relative directory).
369+ #
370+ # By extending `reload_excludes` to ignore everything under the bookmarks folder, we
371+ # can prevent the unexpected reload from happening for the root session. File
372+ # matches are performed via `pathlib.PurePath.match`, which is a right-match and
373+ # only supports `*` glob.
374+ #
375+ # Ignore up to five modules deep. This should cover most cases.
376+ #
377+ # Note: file uploads are always in the root session, so they are always
378+ # stored in the root bookmark dir of `shiny_bookmarks_folder_name / *`.
379+ reload_excludes = [
380+ * reload_excludes ,
381+ str (Path (shiny_bookmarks_folder_name ) / "*" ),
382+ str (Path (shiny_bookmarks_folder_name ) / "*" / "*" ),
383+ str (Path (shiny_bookmarks_folder_name ) / "*" / "*" / "*" ),
384+ str (Path (shiny_bookmarks_folder_name ) / "*" / "*" / "*" / "*" ),
385+ str (Path (shiny_bookmarks_folder_name ) / "*" / "*" / "*" / "*" / "*" ),
386+ ]
387+
362388 reload_args = {
363389 "reload" : reload ,
364390 # Adding `reload_includes` param while `reload=False` produces an warning
0 commit comments