How to call function from another python file

Hi all,

This is probably a dumb question. I’m making a test project through Script Editor in Rhino 8.
There are only 2 py files in the same folder.

#! python3
# m1.py
def main():
    print("Hello I'm m1")

main()
#! python3
# m2.py
import m1

def main():
    m1.main()

main()

What m2 does is call m1.main(), and it works well in Script Editor.
My plan is to make m2 a Rhino command and publish this to a .yak file.(see pic. below)

After installing this .yak file, I try to execute the command “m2” but I got the message that it can’t find the module m1.(see pic. below)

So in this situation, how can I set all the file relations to make this work?

The basic steps are to add the path of the dir the Python module or package to be imported is in, to sys.path if it’s not already in there. If the project will only be run on your machine, any path you like can be hard coded as a string literal. In the RhinoPython settings, the user can add a path to sys.path too, essentially acting like setting PYTHONPATH. That would then be part of your installation instructions.

But if the code’s shipped via Yak or food4Rhino, it’s necessary to ask Rhino or Grasshopper where are the folders, either of the plugin or the Grasshopper dirs, that the user must then install your plug-in into (whether they know that if using food4Rhino, or if Yak does it for them in which case the user doesn’t need to know where it is, in order for your plug-in to its own files. It can use Rhino’s help instead).

This was useful, but much more boilerplate was necessary too - a lot of extra stuff needs to go into your project dir to ship with yak - and then version bumping and all the uninstall and install steps are needed to test a release properly. It felt like I might as well write it in C# instead. Testing a dev version using a hard coded path to the repo is easier. E.g. if you first del sys.modules[your_module_or_package]and importlib.reload(your_module_or_package) restarting Rhino can be avoided. But this does not test the same import steps your users will have to do:

path = os.path.dirname(Rhino.PlugIns.PlugIn.PathFromName("YOUR_PLUGIN_NAME")) 



if path not in sys.path:
    sys.path.append(path)

import your_module_or_package

Rhino Script Compiler and building Python-based plugin on macOS? - #9 by stevebaer?

I recommend Grasshopper instead. It’s possible to write Python code using nearly all the modern tooling. If using CPython3 components, it’s also possible to ship via PyPi, and avoid Yak entirely.

Hi @James_Parrott ,
thx for your reply.

That is my workaround for now, but I hope to simplify the installation process of my plugin so that my users can easily install all the necessary files/modules through a .yak file, and have all the relative paths configured properly.

I believe the new script editor was born for this purpose. It seems to have these features as well, but I can’t find much related documentation.

I’ve tried, but I found that if a .yak file contains commands from .gh files, it will copy all my ghuser objects even if they are not used in the command.

I’ve never thought this before, but it seems like a good way :smile:

@eirannejad
Could you shed some light?