Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shinylive Python Question: Importing from subfolders #162

Open
darrida opened this issue Jul 29, 2024 · 3 comments
Open

Shinylive Python Question: Importing from subfolders #162

darrida opened this issue Jul 29, 2024 · 3 comments

Comments

@darrida
Copy link

darrida commented Jul 29, 2024

Curious if it's possible to import modules from local directory-based packages or folders. I feel like I was able to do this a couple of versions back, but I'm unable to now (it's also possible I'm just incorrectly remembering using regular py-shiny as well.

With larger apps/utilities, folders really help for organizing code (i.e., right now I have a utility that contains 28 other module files in the same directory as app.py), but I'm unable to figure out how to successfully import them (I've tried absolute imports, relative imports, regular folders, package folders, etc).

Any direction is helpful. Thanks!

(btw - really enjoying Shinylive)

@wch
Copy link
Collaborator

wch commented Jul 29, 2024

Hi, can you provide a simple example app?

@darrida
Copy link
Author

darrida commented Jul 30, 2024

Sure thing. I will try to get something to you tomorrow.

@darrida
Copy link
Author

darrida commented Aug 3, 2024

My apologies for not providing an example app yet. I did discover the issue, and figured out why I felt like I "remembered" that it used to work.

On personal projects I use a MacBook, and importing from modules organized into folders works fine in Shinylive.

At work I use a Windows laptop, and that is where importing from folders runs into issues.

The crux of it is this:

  • On MacOS, since it's unix based, the path for the module in the shinylive app.js file is formatted with "/" between directory levels (i.e., module_dir/sub_dir/tool.py
  • On Windows, the path format in app.js is formatted with an escaped backslash (i.e., module_dir\\sub_dir\\tool.py)

When I change the "\\" to a "/" in app.js after exporting the app, importing from modules in folders works (where before the browser error message says the module doesn't exist).

I didn't dig into your repo to see if the path is being generated in Python or something else like Javascript, but it seems like it's the kind of behavior created by pathlib.Path when run on Windows and expecting unix formatted paths (i.e., We develop on Windows and run on Linux servers. In our internal tooling we sometimes have to use PurePosixPath on paths where the string is passed to the linux server after being formatted on our local Windows laptops).

The crude tool I hurriedly threw together today as a temporary workaround is just a script that finds those locations in app.js and "fixes" the path to be a unix format. When I export the shinylive app, then run this script, my app with lots of modules nested in subfolders works.

import re
from pathlib import Path

filepath = Path(__file__).resolve().parent / "staging" / "app-name" / "app.json"

with open(filepath) as f:
    text = f.read()

def fix_path_slashes(match_obj):
    return re.sub(r"\\\\", "/", match_obj.group(1))

matches = re.findall(r'("name": "\S*.py", "content":)', text)
matches = [x for x in matches if "\\" in x]
if matches:
    print("FIXING:")
    for m in matches:
        print(">", m.replace('"name": "', "").replace('", "content":', ""))
    text = re.sub(r'("name": "\S*.py", "content":)', fix_path_slashes, text)

    with open(filepath, "w") as f:
        f.write(text)

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

No branches or pull requests

2 participants