B4J Question [pybridge] Using Multiple .py files

stevel05

Expert
Licensed User
Longtime User
I have been playing with pybridge and came up with a scenario that I wanted to import a variable from a second py file using an import. I presume for the usual reasons, File.DirAssets cannot be on the PythonPath and therefore can't import from there.

I thought I would create a directory in the Python directory of the Objects directory and add that to PythonPath. I chose the Python Directory as that gets copied verbatim by the Build Standalone Process.

I tried adding "PYTHONPATH" to the EnvironmentVars, but looking at the code for PyBridge, this gets over written.

You may already have a simpler solution, but if not, could I request amending the PyBridge.Start method to do something similar to this:
B4X:
Dim PythonPath As String = Options.EnvironmentVars.GetDefault("PYTHONPATH","")
If PythonPath <> "" Then
    Options.EnvironmentVars.Put("PYTHONPATH", Options.PyBridgePath & ";" & PythonPath)
Else
    Options.EnvironmentVars.Put("PYTHONPATH", Options.PyBridgePath)
End If

Which checks if the PythonPath env has been set and prepends the PyBridgePath.

I have tried this out and it seems to work as expected.
 

stevel05

Expert
Licensed User
Longtime User
I've just realized that this may cause issues when exporting or backing up the project so may not be the best solution.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
For completeness, I eventually decided to store the .py files in the Files folder and when run, copy them to their own folder in Dir.App and point the PYTHONPATH environment variable to that. This satisfies the need to be able to distribute the python files with the ide's export as zip, and works without change when building a standalone package.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I had a similar requirement (calling other script functions in DirAssets)

Probably not the best way, but it works without having to move the script files around.

B4J
B4X:
    Dim scripts As String = File.geturi(File.DirAssets,"__init__.py").Replace("file:/","").Replace("\","/").Replace("__init__.py","").Replace("%20"," ")
    opt.EnvironmentVars = CreateMap("script_dir" : scripts)

see post #7 for Python code to use with this

Justr make sure you have an __init__.py in the files folder
 
Last edited:
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
got it working with this python change
B4X:
import os, sys, zipfile, tempfile
script_dir = os.getenv("SCRIPT_DIR")
# Create a persistent temporary directory
temp_dir = tempfile.TemporaryDirectory()
extracted_scripts_path = None
if script_dir.startswith("jar:"):
    jar_path = script_dir[len("jar:"):]
    jar_path = jar_path[:jar_path.find("!")]
    with zipfile.ZipFile(jar_path, 'r') as jar_file:
        jar_file.extractall(temp_dir.name)
        extracted_scripts_path = os.path.join(temp_dir.name, "Files")
else:
    extracted_scripts_path = script_dir
sys.path.append(extracted_scripts_path)
# any imports from here to local scripts are valid
from First_Python import func1
print(func1(4, 7))

Edit: forgot this bit when finished
B4X:
temp_dir.cleanup()
 
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…