Trying to use system path for sikuli script and import it in other scripts.

Asked by Anshu

I have a sikuli script with some common functions and i am using , something like
myLib = "C:\test"
exec open(myLib+"\GenericFunctions.sikuli\GenericFunctions.py").read()
which works perfect when i use the functions inside.

Now i have to use the same scripts on mac - only difference being - the path to myLib.
So on windows side i tried to put this path "C:\test\GenericFunctions.sikuli" in the environment variable and intend to use
import GenericFunctions (so i don't need to specify any path)

But it fails with error that - there is no module called GenericFunctions.

In one of the previous posts,
https://answers.launchpad.net/sikuli/+question/110877
it was suggested :

You can even import other Sikuli scripts as python modules. Suppose you have /somedir/myutil.sikuli/myutil.py, then in your main Sikuli script do

import sys
sys.path.append('/somedir/myutil.sikuli')
import myutil

Note : i have no Images in the Generic functions script.

SO i just have to define this path so that i don't need to modify the scripts for mac.

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:
Revision history for this message
RaiMan (raimund-hocke) said :
#1

some comments (since I cannot see a question ;-)

--- "import sys" not needed, it is already done by the Sikuli initialization

--- sys.path.append()
since in the IDE, sys.path is not reset on rerun of a script, the path is appended again each time.
to avoid this:
if "some-path" not in sys.path: sys.path.append("some-path")

--- Sikuli X
in a few days, this will be a little bit easier with Sikuli X
--- you may import other .sikuli and only have to take care, that they can be found using sys.path
e.g. in your case:
if "/somedir" not in sys.path: sys.path.append("/somedir")
and "import myutil" will work
--- if the imported scripts contain images, they will be found automatically, since Sikuli X manages a new image path container internally additionally to the singular bundle path.

So using import is the future ;-)

Since I am using Mac / Windows and Sikuli IDE / Netbeans / Jython in parallel with the "same" scripts I have a basic.py located in
Mac: /Applications/Sikuli-IDE/contents/Java/Lib
Windows: c:\Program Files\Sikuli-IDE\Lib
and in appropriate places for NetBeans and Jython
since these are in the standard sys.path

This is a kind of bootstrap, where I evaluate the current environment, set some global variables and finally import my generics.py.

This will slightly change with Sikuli X, since the imported modules might be .sikuli's and images will be found automatically (no more need to use get/setBundlePath together with import)

Revision history for this message
Anshu (anshu-ca) said :
#2

Hi Raiman,
To solve my problem of running the same script on both MAC and Windows , using Sikuli X,
following code is awesome.This solved my one issue.

# works on all platforms
p = getBundlePath()
slash = "\\" if Env.getOS() == OS.WINDOWS else "/"
myPath = p.rpartition(slash)[0] # gets the directory containing your running .sikuli
if not myPath in sys.path: sys.path.append(myPath)
# now you can import every .sikuli in the same directory
import myLib

My question now is , that i have so many scripts (soon will be 50+) , and all of them use this myLib , for instance.
So how do i set this myPath in the systempath - globally.I do not want to put this code in each of the script, if there is a better way to do that.

Thanks
Anshu

Revision history for this message
Anshu (anshu-ca) said :
#3

I also tried to put my script (myLib.sikuli as well as myLib.py) in
 c:\Program Files\Sikuli-IDE\Lib and entered that path in environment variable "Path" manually .

But then import myLib fails in Sikuli , saying No module named myLib.

Revision history for this message
RaiMan (raimund-hocke) said :
#4

A recommended approach for Sikuli X, if you do not want to touch sys.path:

for all Sikuli versions, if you want to use import:
- myLib.sikuli must contain (recommended as first line) when using Sikuli features in myLib.sikuli:
from sikuli.Sikuli import *

with Sikuli X (recommended, when myLib contains images):
- put myLib.sikuli in c:\Program Files\Sikuli-IDE\Lib (is already in sys.path when running Sikuli)
- in your scripts, use:
from myLib import *
(so all names in myLib can be used without qualification (myLib.aFunction() is needed when using import myLib))
(all images in myLib will be found automatically)

Nothing else to do with Sikuli X - only "from myLib import * " in every script using variables, functions and/or images from myLib.sikuli.

Revision history for this message
Roberta Aparecida (comroberta) said :
#5

RainMan
I tried the approach to Sikuli X, not works, appear this message: ImportError: No module named myLib.
Shoul you help me?
Thanks
Roberta Comunale

Revision history for this message
RaiMan (raimund-hocke) said :
#6
Revision history for this message
Anshu (anshu-ca) said :
#7

Hi RaiMan,
I am also back with same problem :( and also noticed something.
Like i said before - importing of scripts is working fine for me , when i use the sample code
# works on all platforms
p = getBundlePath()
slash = "\\" if Env.getOS() == OS.WINDOWS else "/"
myPath = p.rpartition(slash)[0] # gets the directory containing your running .sikuli
if not myPath in sys.path: sys.path.append(myPath)
# now you can import every .sikuli in the same directory
import myLib

But i want to put my sikuli script in folder : C:\Program Files (x86)\Sikuli X\libs
so that I need to use single statement in my scripts : "from myLib import *
But using this approach - i get the error that module myLib is not defined
;
so for testing purpose, i gave a print statement - print sys.path and it prints following line

['C:\\Program Files (x86)\\Sikuli X\\sikuli-script.jar', 'C:\\Program Files (x86)\\Sikuli X\\Lib', 'C:\\Program Files (x86)\\Sikuli X\\sikuli-script.jar\\Lib', '__classpath__', '__pyclasspath__/', '.']

- What appears wrong is "C:\\Program Files (x86)\\Sikuli X\\Lib" folder.
Under Sikuli X - the actual folder name is libs and not Lib; my scripts is also put under libs and not Lib folder.

Is that the root cause of the problem ???(confusion between libs and Lib folder)

Thanks for being patient - to hear the same issue again.
Anshu

Revision history for this message
Best RaiMan (raimund-hocke) said :
#8

@Anshu
--- 1.
when an "import myLib" works, an "from myLib import *" always works too. the only difference is, that in the first case you have to qualify everything with myLib.someFunction(), whereas in the second case, this is not needed. Just use the plain names contained in myLib. In the second case you are responsible yourself, to avoid naming conflicts between main script and imported scripts.

--- 2. The libs folder contains the native libraries. It is not recommended to put anything else there.

--- 3. The folder Lib (it might not be there, just create it in this case) is already in sys.path (as you can see in the above listing). So if you use this folder to store your libraries, there would be no need to care about sys.path. Only import would be needed.

Revision history for this message
Anshu (anshu-ca) said :
#9

Thanks RaiMan,
I created the Lib folder under C:\\Program Files (x86)\\Sikuli X and placed myLib.sikuli in there.
Now i can import myLib in all my scripts - with just a single line : from myLib import *

Feeling Very Happy.
Anshu

Revision history for this message
Anshu (anshu-ca) said :
#10

Thanks RaiMan, that solved my question.