Import a local module on <py-script> (Python for browsers)
Asked Answered
S

4

6

I found a very useful application, that works like html tags for Python applications. Supposedly I could use all the features of Python between tags within a Browserlike php, for example:

<py-script>
.......My program here....
</py-script>

Apparently the program works in a remote place, so when you use the libraries it uses the site libraries. But the libraries I need, (pyautocad) are locally in my computer, so when I try to load then the program searches in the site and fails. Below I add a snipett of the program

 <html>
  <head>
  <!-- <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />-->
    <!-- <script defer src="https://pyscript.net/alpha/pyscript.js"></script> -->
    
    <link rel="stylesheet" href="pyscript.css" />
    <script defer src="pyscript.js"></script>
    <py-env> 
        paths:
        api.py
    </py-env>
  </head>
  <body>
        <py-script>
import sys 
import os
from pyautocad import Autocad()
from api import *
#watchout()
        </py-script>
  </body>
</html>

I tried it via href, py-env and other methods with no luck. Does someone have any suggestions? Regards and thanks in advance.

Scatology answered 7/5, 2022 at 1:21 Comment(0)
S
1

When running Pyscript in the web browser loaded from a web server, your HTML/JavaScript/Python cannot specify local files. That is a security restriction enforced by the web browser. Accessing local files from a script is prohibited.

It is possible to create a form input element that the user can click to read a local file. Then you can instantiate an object that contains Python code and pass that object to Pyodide for execution. You can also store that object in the virtual file system (IDBFS - IndexDB) for loading from your script in the future without requiring the local file upload.

The simplest solution is to put the Python wheels on your web server. If that is not possible then you will need to write code that interfaces with Pyodide.

Note: you will need to verify that pyautocad is supported by Pyscript/Pyodide. That package probably contains C code which means that package must be ported to be supported by Pyodide.

Stroup answered 7/5, 2022 at 2:25 Comment(0)
B
1

similarly to what John says, it is not possible to directly import local modules, you need to server them to the client. to do so i create a specific view on the server that returns an http response with the file as content-disposition. I am then able to load the file in the py-env, and access it in the py-script

on your server views.py:

path = r'D:\path\to\\'

def dtsync(request,file:str):
    with open(path + file, 'rb') as f:
        response = HttpResponse(f.read(), content_type="application/liquid")
        response['Content-Disposition'] = 'inline; filename=' + os.path.basename(path + file)
        return response

your html:

<py-env>
    - pandas
    - paths:
            - /dtsync/dataframe.pkl
            - /dtsync/mymod.py
</py-env>
<py-script>
    import pandas as pd
    from mymod import myfunction

    df = pd.read_pickle('dataframe.pkl')
    print(df.head())
    
    myfunction(df)
</py-script>

the same will work to load databases or other filetype as you need. in this example i load a pandas dataframe and a module with a function to process it

Bela answered 16/6, 2022 at 2:24 Comment(0)
F
1

I'm afraid that pyautocad is not supported, but....

Locally speaking (there is already an answer for server side working) - There are some interesting things about pyscript and local modules. In subfolder modules there are two files: hello_module.py and byby_module.py.

hello_module.py is:

def hello():
    return '***** **** ** * Hello World * ** **** *****'

byby_module.py is:

def byby():
    return '***** **** ** * ByBy World * ** **** *****'

There is also the main.py in index folder calling functions from local subfolder modules.

main.py is:

pyscript.write("output", 'T E S T I N G', True)
pyscript.write("output", hello(), True)
pyscript.write("output", byby(), True)

index.html is:

<html>
    <head>
        <title>Test</title>
<!--        <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
        <script defer src="https://pyscript.net/alpha/pyscript.js" onerror=scriptLoadFailure('pyscr ipt.js')></script> -->
<link rel="stylesheet" href="pyscript.css" />
    <script defer src="pyscript.js"></script>
<py-env> 
paths
    ./modules/hello_module.py
    ./modules/byby_module.py
    ./main.py
</py-env>
    </head>
    <body>      

    <py-script src="./modules/hello_module.py"></py-script>
    <py-script src="./modules/byby_module.py"></py-script>
    <py-script src="main.py"></py-script>

    <div id="output"></div>
    </body>
</html>

Above example code works(!)

enter image description here

and shows that we can use local modules. There are a lot of questions and considerations to take care of and a lot of "What Ifs" like what if we have the same function name in both modules etc, etc....

On the contrary if main.py is removed from py-env node and from src attribute moving all the very same commands from file into py-script node of html then it fails!?

py-env and py-script part of html that fails looks like this:

<py-env> 
paths
    ./modules/hello_module.py
    ./modules/byby_module.py
</py-env>

<py-script src="./modules/hello_module.py"></py-script>
<py-script src="./modules/byby_module.py"></py-script>
<py-script>
pyscript.write("output", 'T E S T I N G', True)
pyscript.write("output", hello(), True)
pyscript.write("output", byby(), True)
</py-script>

The error is:

File "", line 2, in NameError: name 'hello' is not defined

It means (does it?!) that we can call local functions from different local modules but not from within html pyscript code which (the second part) is just as it is expected to be. If the same code is within the local .py file and declared as src attribute in html then it works.

Furfuran answered 13/7, 2022 at 10:38 Comment(2)
@marc_s Thanks, again. I ow you a few... Fancy a beer?Furfuran
Does this still works with the current version of PyScript?Bejewel
B
0

They have an error in the example code. The FETCH command dose not work. We must be using PATHS as shown in the below code. It perfectly works. Note we have quotes for packages(as "numpy") and no quotes for the paths (as hello.py, byby.py). We do not need to define main in py-config section. And we do not need to define hello.py and byby.py in the "<script src=... >" sections. We just need to define main.py. Main imports hello and byby.

<!DOCTYPE html>
<html lang="en">
<html>
    <head>
        <title>Test</title>
        <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
        <script defer src="https://pyscript.net/latest/pyscript.js"></script>
    </head>
<body>    
<py-config type="toml">
     packages = ["numpy"]

     paths = [hello.py,
              byby.py]
</py-config>

    <py-script src="main.py"></py-script>

    <div id="output"></div>
    </body>
</html>
Bolster answered 13/12, 2022 at 14:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.