Importing Python files in Start Up

Anonymous

Importing Python files in Start Up

Anonymous
Not applicable
pathOfFiles = "S:/My/Custom/Folder/"
ignoreList = ["sharedUserSetup.py", "__init__.py", "importPython.py"]
files = cmds.getFileList( folder=pathOfFiles, filespec='*.py' )
def importPy(): if len(files) == 0:       cmds.warning("No files found") else:       for f in files:           if f in ignoreList:                 continue           module = (os.path.splitext(f)[0])           exec( 'import ' + module)

I'm trying to "source" my python scripts when I first start a Maya session.

In this code I'm scanning my custom folder path and bringing out all of the python files and then attempting to import them. This code works perfectly fine if I execute it through Maya's command line window, however when I try and access this function through a UserSetup.py in a maya.utils.executeDeferred function it only works for that one instance. If I then try and run one of my scripts, for example, myScript.makeObject() through the command line I will get the error:

# Error: NameError: file <maya console> line 1: name 'myScript' is not defined # 

However if I do:

 

import importPython
myScript.makeObject()

 

I will be able to continuously call myScript.makeObject() and the script will execute as expected.

 

Could somebody explain why the python script isn't able to be called continuously using this start up method? I imagine what I'm doing is I'm importing the functions of the folder scripts in to the importPy() function rather than my Maya session? So how do I stop doing that?

 

Likewise if there is a better way to deal with this I'd love to hear it. 

 

Thanks! 

0 Likes
Reply
Accepted solutions (1)
4,903 Views
13 Replies
Replies (13)

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

I think you want to import modules in userSetup.py and use them directly without importing them again, right? I am confused with your description, when you exec import in a function scope, it shouldn't be allowed to used outside the function. Executing following script with Maya 2019 script editor with PyQt5 will give following result. PyQt5 is not shipped with Maya and compiled separately, it should be similar to your modules.

def importPy():
    exec("import PyQt5.QtWidgets as pyQtWidgets")
    
importPy()
print pyQtWidgets

Result

# Error: NameError: file <maya console> line 5: name 'pyQtWidgets' is not defined # 

But you could make it work in global scope by adding globals() as an argument of the exec like below

def importPy():
exec("import PyQt5.QtWidgets as pyQtWidgets", globals()) importPy() print pyQtWidgets

Result

<module 'PyQt5.QtWidgets' from 'C:\Program Files\Autodesk\Maya2019\Python\lib\site-packages\PyQt5\QtWidgets.pyd'>

So I tested with following userSetup and it seems working fine

def importPy():
    exec("import PyQt5.QtWidgets as pyQtWidgets", globals())

def tryImport():
	from maya.utils import executeDeferred
	executeDeferred("importPy()")

tryImport()

After Maya started, I execute print pyQtWidgets and it seems working.

file -f -new;
// untitled // 
commandPort -securityWarning -name commandportDefault;
onSetCurrentLayout "Maya Classic";
// Warning: file: ...
...
// AbcImport v1.0 using Alembic 1.7.5 (built Feb  6 2018 18:28:08) // 
updateRendererUI;
updateRendererUI;
print pyQtWidgets
<module 'PyQt5.QtWidgets' from 'C:\Program Files\Autodesk\Maya2019\Python\lib\site-packages\PyQt5\QtWidgets.pyd'>

Hope it helps.

 

Yours,

Li

 

0 Likes

Anonymous
Not applicable

Hi Li,

 

Thank you for your help.

 

This does indeed work and I can get the same output as yourself. However, if I then try and call the script from the python command line it doesn't work, do you know why this would be?

PythonCMD.PNG

 

 

Many thanks,

Kieren

0 Likes

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

I tried with my test and it is working with Python command line(e.g. pyQtWidgets.QCheckBox())
. I don't have any ideas based on your description now. Do you have a sample for us to look at?

 

Yours,

Li

0 Likes

Anonymous
Not applicable

This is the user setup I'm using: 

"""sharedUserSetup.py acts like userSetup.py in that Maya executes any commands
in the file during startup.

The below text is copied from Maya's documentation:

Maya runs any Python commands in the sharedUserSetup.py file whenever it starts
up. You can use this file to set up your working environment or execute commonly
used Python commands such as importing the maya.cmds module.

The sharedUserSetup.py script is executed during the initialization and setup
phase of Maya; therefore, only commands which set up your working environment
and have no dependencies on Maya functionality can be successfully run in this
script.

Note: You can use maya.utils.executeDeferred() to delay code execution until
after the Maya scene is initialized. For more information, see maya.utils.
"""
################################################################################
# IMPORT BLOCK
import maya.cmds as cmds
import maya.mel as mel
import maya.utils
import sys, os

pth = 'S:/Departments/Art/TechArt_Testing/'
if not pth in sys.path:
    sys.path.append(pth) #Append our system path with our custom location 

# Instantiate logger class
import logging
L = logging.getLogger( __name__ )
L.setLevel(logging.INFO)
if not L.handlers:
	ch = logging.StreamHandler()
	ch.setFormatter( logging.Formatter("%(name)s : %(levelname)s : %(message)s") )
	L.addHandler(ch)
# HOW TO USE THE LOGGER:
# Instead of "print" use the following code snippets:
# L.debug("Debug message")
# L.info("Info)
# L.warn("A warning, but nothing we can't handle...")
# L.error("An error has occured, time to take drastic measures")
# L.fatal("A problem so huge we can't do anything but fail the entire program!")
#
# By changing the level of the logger you can decide how much information to
# print out. E.g.:
# L.setLevel(logging.DEBUG) - Logging messages above the setLevel threshhold
# is printed, in this case all messages would be printed.

################################################################################
# FUNCTIONS BLOCK

def executedDeferred():
	"""These commands are run after Maya is done initializing, so here we do
	have full access to Maya functionality"""
	sourceScripts()
	setEnv()
	importPython()
	print importPy

def importPython():
	exec("import importPython as importPy", globals())
	importPy.importPy()
	
def reportLoaded():
	print("\n")
	L.info( "Loaded" )
	print("\n")

def setEnv():
    L.info("Setting up the Maya environment")
    mel.eval('envSetup()')		

def sourceScripts():
	print("MAYA: \n")
	pathOfFiles = "S:/Departments/Art/TechArt_Testing/"
	files = cmds.getFileList( folder=pathOfFiles, filespec='*.mel' )
	if len(files) == 0:
		cmds.warning("No files found")
	else:
		for f in files:
			script = (f)
			command = ("source " +'"' + pathOfFiles + script + '"')
			mel.eval(command)
			L.info("Loaded " + script)
	print("\n")

################################################################################
# COMMANDS BLOCK

maya.utils.executeDeferred( executedDeferred )

My import python:

import maya.cmds as cmds
import sys, os

def importPy():

	print("We're now importing from Python")
	pathOfFiles = "S:/Departments/Art/TechArt_Testing/" #Set this to the path of the sharedUserSetup
	ignoreList = ["sharedUserSetup.py", "__init__.py", "importPython.py", 'sharedUserSetup - Copy.py', 'shelfBase.py'] #Used to ignore files from being imported
	files = cmds.getFileList( folder=pathOfFiles, filespec='*.py' ) #Scan the folder for python files

	if len(files) == 0: #If there are no files throw a warning
		cmds.warning("No files found")
	else:
		for ignoreFile in ignoreList: 
			files = [f.replace(ignoreFile, '') for f in files] #If there are files matching the ignore list array replace their value with a blank space so they don't import

	print(files)

	for f in files:
		module = (os.path.splitext(f)[0])
		if f == "": #If the file is a blank space ignore it and continue
			continue

		exec("import " + module, globals() ) #Import the script
		print ("Loaded " + module)

		
	print("Finished Pythoning")		

The python script I'm trying to load:

import maya.cmds as cmds

def makeObject():
    cmds.polyCube()
    print("Made a cube!")

makeObject()

I can provide this as a .zip with the folder structure setup if it makes things easier for you?

0 Likes

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

I have looked at your loading script again. I don't think loading with path work that way. 

e.g. import filepath

I think it should be imp.load_source.

 

My updated userSetup.py

from imp import load_source

def importPy():
    exec("import PyQt5.QtWidgets as pyQtWidgets", globals())    
    exec("hello = load_source('pythonScripts.hello', 'f:/case/pythonScripts/hello.py')", globals())

def tryImport():
	from maya.utils import executeDeferred
	executeDeferred("importPy()")

tryImport()

hello.py

def helloMethod():
	print "Hello"

Result

hello
# Result: <module 'pythonScripts.hello' from 'f:/case/pythonScripts/hello.py'> # 
hello.helloMethod()
Hello

If you would like to import with a normal import, please add your module into sys.path with sys.path.append.

 

Hope it helps.

 

Yours,

Li

 

0 Likes

Anonymous
Not applicable

My user setup:

"""sharedUserSetup.py acts like userSetup.py in that Maya executes any commands
in the file during startup.

The below text is copied from Maya's documentation:

Maya runs any Python commands in the sharedUserSetup.py file whenever it starts
up. You can use this file to set up your working environment or execute commonly
used Python commands such as importing the maya.cmds module.

The sharedUserSetup.py script is executed during the initialization and setup
phase of Maya; therefore, only commands which set up your working environment
and have no dependencies on Maya functionality can be successfully run in this
script.

Note: You can use maya.utils.executeDeferred() to delay code execution until
after the Maya scene is initialized. For more information, see maya.utils.
"""
################################################################################
# IMPORT BLOCK
import maya.cmds as cmds
import maya.mel as mel
import maya.utils
import sys, os

pth = 'S:/Departments/Art/TechArt_Testing/'
if not pth in sys.path:
    sys.path.append(pth) #Append our system path with our custom location 

# Instantiate logger class
import logging
L = logging.getLogger( __name__ )
L.setLevel(logging.INFO)
if not L.handlers:
	ch = logging.StreamHandler()
	ch.setFormatter( logging.Formatter("%(name)s : %(levelname)s : %(message)s") )
	L.addHandler(ch)
# HOW TO USE THE LOGGER:
# Instead of "print" use the following code snippets:
# L.debug("Debug message")
# L.info("Info)
# L.warn("A warning, but nothing we can't handle...")
# L.error("An error has occured, time to take drastic measures")
# L.fatal("A problem so huge we can't do anything but fail the entire program!")
#
# By changing the level of the logger you can decide how much information to
# print out. E.g.:
# L.setLevel(logging.DEBUG) - Logging messages above the setLevel threshhold
# is printed, in this case all messages would be printed.

################################################################################
# FUNCTIONS BLOCK

def executedDeferred():
	"""These commands are run after Maya is done initializing, so here we do
	have full access to Maya functionality"""
	sourceScripts()
	setEnv()
	importPython()
	print importPy

def importPython():
	exec("import importPython as importPy", globals())
	importPy.importPy()
	
def reportLoaded():
	print("\n")
	L.info( "Loaded" )
	print("\n")

def setEnv():
    L.info("Setting up the Maya environment")
    mel.eval('envSetup()')		

def sourceScripts():
	print("MAYA: \n")
	pathOfFiles = "S:/Departments/Art/TechArt_Testing/"
	files = cmds.getFileList( folder=pathOfFiles, filespec='*.mel' )
	if len(files) == 0:
		cmds.warning("No files found")
	else:
		for f in files:
			script = (f)
			command = ("source " +'"' + pathOfFiles + script + '"')
			mel.eval(command)
			L.info("Loaded " + script)
	print("\n")

################################################################################
# COMMANDS BLOCK

maya.utils.executeDeferred( executedDeferred )

Python import: 

import maya.cmds as cmds
import sys, os

def importPy():

	print("We're now importing from Python")
	pathOfFiles = "S:/Departments/Art/TechArt_Testing/" #Set this to the path of the sharedUserSetup
	ignoreList = ["sharedUserSetup.py", "__init__.py", "importPython.py", 'sharedUserSetup - Copy.py', 'shelfBase.py'] #Used to ignore files from being imported
	files = cmds.getFileList( folder=pathOfFiles, filespec='*.py' ) #Scan the folder for python files

	if len(files) == 0: #If there are no files throw a warning
		cmds.warning("No files found")
	else:
		for ignoreFile in ignoreList: 
			files = [f.replace(ignoreFile, '') for f in files] #If there are files matching the ignore list array replace their value with a blank space so they don't import

	print(files)

	for f in files:
		module = (os.path.splitext(f)[0])
		if f == "": #If the file is a blank space ignore it and continue
			continue

		exec("import " + module, globals() ) #Import the script
		print ("Loaded " + module)

		
	print("Finished Pythoning")		

Script to import: 

import maya.cmds as cmds

def makeObject():
    cmds.polyCube()
    print("Made a cube!")

makeObject()
0 Likes

Anonymous
Not applicable
################################################################################
# IMPORT BLOCK
import maya.cmds as cmds
import maya.mel as mel
import maya.utils
import sys, os

pth = 'S:/Departments/Art/TechArt_Testing/'
if not pth in sys.path:
    sys.path.append(pth) #Append our system path with our custom location 
################################################################################ # FUNCTIONS BLOCK def executedDeferred(): """These commands are run after Maya is done initializing, so here we do have full access to Maya functionality""" sourceScripts() setEnv() importPython() print importPy def importPython(): exec("import importPython as importPy", globals()) importPy.importPy() def setEnv(): mel.eval('envSetup()') def sourceScripts(): print("MAYA: \n") pathOfFiles = "S:/Departments/Art/TechArt_Testing/" files = cmds.getFileList( folder=pathOfFiles, filespec='*.mel' ) if len(files) == 0: cmds.warning("No files found") else: for f in files: script = (f) command = ("source " +'"' + pathOfFiles + script + '"') mel.eval(command) print("\n") ################################################################################ # COMMANDS BLOCK maya.utils.executeDeferred( executedDeferred )

My shared user setup

0 Likes

Anonymous
Not applicable

The python import: 

import maya.cmds as cmds
import sys, os

def importPy():

	print("We're now importing from Python")
	pathOfFiles = "S:/Departments/Art/TechArt_Testing/" #Set this to the path of the sharedUserSetup
	ignoreList = ["sharedUserSetup.py", "__init__.py", "importPython.py", 'sharedUserSetup - Copy.py', 'shelfBase.py'] #Used to ignore files from being imported
	files = cmds.getFileList( folder=pathOfFiles, filespec='*.py' ) #Scan the folder for python files

	if len(files) == 0: #If there are no files throw a warning
		cmds.warning("No files found")
	else:
		for ignoreFile in ignoreList: 
			files = [f.replace(ignoreFile, '') for f in files] #If there are files matching the ignore list array replace their value with a blank space so they don't import

	print(files)

	for f in files:
		module = (os.path.splitext(f)[0])
		if f == "": #If the file is a blank space ignore it and continue
			continue

		exec("import " + module, globals() ) #Import the script
		print ("Loaded " + module)

		
	print("Finished Pythoning")		
0 Likes

Anonymous
Not applicable

If you would like to import with a normal import, please add your module into sys.path with sys.path.append.

If I'm correct in my thinking, I should be doing this in the above user setup script

0 Likes

cheng_xi_li
Autodesk Support
Autodesk Support
Accepted solution

Hi,

 

I think it is imported in the module namespace. You can make your module in the __main__ like below.

 

import runpy
.....

def importPython():
	exec("import importPython as importPy", globals())
	result = runpy._run_module_as_main("importPython")
	#it is now in the __main__ namespace now, so the module name is no longer available
	importPy()

Yours,

Li

0 Likes

Anonymous
Not applicable

Hi Li,

 

Thanks for that, that's certainly worked. My only problem now is to use: 

runpy._run_module_as_main("importPython")

but to replace "importPython" with a string variable.

This doesn't seem to work currently.

 

Thanks,

Kieren 

 

 


 

0 Likes

cheng_xi_li
Autodesk Support
Autodesk Support

Hi,

 

I tested replacing "importPython" with a string variable, it seems working fine.

 

def importPython():
	exec("import importPython as importPy", globals())
	moduleName = "importPython"
	result = runpy._run_module_as_main(moduleName)
	importPy()

Yours,

Li

0 Likes

Anonymous
Not applicable

Thank you for your help.

 

I'm still having issues getting this to work exactly how I want it to however, the initial question has been resolved so I'm marking this as solved

0 Likes