Skip to content

Conversation

wch
Copy link
Collaborator

@wch wch commented Jun 14, 2024

This PR makes it possible to do relative imports in a Shiny Express app, such as:

from . import utils

This is useful in the case of running Shiny Express apps in Shinylive on a web page where there are multiple Shiny apps running concurrently. This is important for the case where a page has multiple versions of an app, and each imports from a file with the same name, like utils.py -- without relative imports, only one copy of utils.py will be imported, and it will be shared across all of the concurrent apps.

In this sheet, this change has the effect of making all of the Error cells in the bottom row (in red) into OK cells (which would be green). https://docs.google.com/spreadsheets/d/1jIVoEDr234uo_ALOPiilSIoU-bj18L-R6YP_39ORXwM/edit#gid=0

image

I'm not sure yet, but it might be possible to make relative imports also work for Shiny Core apps.

@wch
Copy link
Collaborator Author

wch commented Jun 14, 2024

Regarding getting relative imports to work with Shiny Core, it looks like it is possible but it's a little odd: we would need to use the app's parent directory as the app_dir (this is equivalent to adding the parent directory to PYTHONPATH environment variable). This is a restriction that comes from the way uvicorn works.

Because the parent dir is on the Python search path, that means that if the directory containing app.py also contains utils.py, the relative import would work:

from . import utils  # OK

But the non-relative import would not:

import utils  # Error

This would be a surprising change of behavior.

One way around this would be to also add the application directory to the PYTHONPATH. However, the parent dir would still be on the search path, so there could be a conflict if the parent dir contains a utils.py or a utils/ subdir with __init__.py in it.

IMO, it is generally preferable to use relative imports to avoid naming conflicts. For example, a file named os.py would have a name conflict with the built-in os package, so what does import os do in that case?

References about relative imports with uvicorn:

@wch wch marked this pull request as ready for review June 14, 2024 17:18
@wch wch enabled auto-merge June 14, 2024 21:55
@wch wch added this pull request to the merge queue Jun 14, 2024
Merged via the queue into main with commit 0370662 Jun 14, 2024
@wch wch deleted the express-module-import branch June 14, 2024 22:12
@wch
Copy link
Collaborator Author

wch commented Jun 15, 2024

After merging, this is the updated spreadsheet. (Also note that I changed the colors to be more colorblind-friendly)
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant