I have two functions, I have placed one of the functions into a seperate .py so I can import it, but I get an error when I try to run the script.
The function that I placed into the separate .py is:
def output_messaging(message):
global myEmailText
myLogFile.write(message)
myEmailText = myEmailText + message
print message
The script that I run has the following code:
def finish_process(errors):
global myLogFile
myLogFile.close()
if errors == 0:
myEmailHeader = "Subject: **"
elif errors == 1:
myEmailHeader = "Subject: **"
else:
myEmailDestination.append("**")
#myEmailHeader = "Subject: **"
server = smtplib.SMTP(myServer) #email data log to nominated individuals
server.sendmail(myEmailSender, myEmailDestination, myEmailHeader + "\n" + myEmailText)
server.quit()
When I run the script i get the following error.
NameError: global name 'myLogFile' is not defined
myLogFile is declared lower down in the code (which is the location of the log file), but I'm slightly confused.
Thanks
The error is clear. myLogFile is not defined anywhere in your output_messaging function. You need to define it in that function, or pass it in as a parameter.
You shouldn't be using globals anyway, they are almost always a bad idea. Pass parameters explicitly.
In output_messaging, you don't have global myLogFile to indicate that myLogFile is defined somewhere else in the file. When Python runs that function, it doesn't recognize the variable now.
Note that global variables are generally discouraged but that's a different discussion.
Related
So, I have this project of a form similar to this:
./
./__init__.py
./main.py
./errorHandle.py
./functions.py
Now, In my main.py I have this:
import errorHandling
from functions import *
And in errorHandle.py:
from functions import sendMessage
def exceptionHandle(ex,errorCode):
def exceptionHandle(ex,errorCode):
print(ex)
extra = ""
status = 1
if errorCode == constants.ErrorCodes.aws:
constants.awsWorking = 0
if checkConnection() == True:
extra = "A network connection was detected but no connection to AWS was possible. Possibilities include an issue of authentication, renamed/incorrectly named shadow, or a duplicate client name. "
constants.errorsListDelayed[int(time.time())] = [ex,errorCode,extra,constants.TargetConnection.aws]
else:
extra = "No internet connection detected/Google DNS down. "
constants.errorsListDelayed[int(time.time())] = [ex,errorCode,extra,constants.TargetConnection.awsAndMail]
return
elif errorCode == constants.ErrorCodes.loadConfig:
extra = checkIniExists()
elif errorCode == constants.ErrorCodes.camera:
status, extra = checkCameraInitial()
elif errorCode == constants.ErrorCodes.loadImages:
extra= "Couldn't load images. "
else:
extra= "Unknown Error location"
if status == 1:
cv2.destroyAllWindows()
sendErrorMessage(ex,errorCode,extra)
uploadError(ex,errorCode)
(indentation got a bit messy after copying)
And in my functions I have a number of functions, including the aforementioned sendMessage
Now, for some reason while I am able to import errorHandle, none of its functions, including the exceptionHandle function show, but it IS importing, as I can do something like this fine:
errorHandle.sendMessage(...)
And it would work without any real issues
I have also attempted different imports, with different errors that more or less resulted in the same idea. So I tried:
from errorHandle import exceptionHandle
But that didn't work either.
I have also tried
from errorHandle import *
which just loaded sendMessage only, and I tried to change the code in errorHandle to change the sendMessage to *, which loaded all the functions.py files, and I tried removing the whole import functions from errorHandle.py, which changed nothing.
Kind-of lost here, since it IS importing the module and recognizing it, just not the functions in the module.
EDIT:
ImportError: cannot import name 'exceptionHandle' from 'errorHandling'
I have ensured all the names are correct, also no functions exist with either of those names, I have also tried different names to make sure its not a weird bug due to a certain name.
Do you by any chance have a function named errorHandle inside your functions.py file?
Please see the code I have, and that it is running. Can you please provide a minimal reproducible example so the bug/problem can be replicated.
user#Inspiron:~/code/general/remthisdir$ cat errorHandle.py ;echo;cat functions.py ;echo ;cat main.py
from functions import sendMessage
def exceptionHandle():
print('Inside exceptionHandle')
def sendMessage():
print('Inside sendMessage')
import errorHandle
from functions import *
if __name__ == '__main__':
errorHandle.exceptionHandle()
sendMessage()
user#Inspiron:~/code/general/remthisdir$ python main.py
Inside exceptionHandle
Inside sendMessage
user#Inspiron:~/code/general/remthisdir$
Have this below function.But getting error ..any thoughts ?
def zabbix_discovery(pingdom_data):
discovery = []
for k,v in data["recipes"].items():
discovery.append(
{"{#NAME}": str(v['name'])}
)
cmd_args = [
'zabbix_sender',
'-z', config.get('ZABBIX', 'server'),
'-p', config.get('ZABBIX', 'port'),
'-s', config.get('ZABBIX', 'host'),
'-k', config.get('ZABBIX', 'key1'),
'-o', "'{ \"data\": " + discovery + " }'"
]
zabbix_trapper(cmd_args)
=====
Traceback (most recent call last):
File "txncheck_backup.py", line 52, in <module>
'-o', "'{ \"data\": " + discovery + " }'"
NameError: name 'discovery' is not defined
=====
You are using discovery before it is declared on the function call.
Also, as you declare it in the function, it will be destroyed at the end of it and wont be available in the main scope.
You are trying to access it before you call the function zabbix_discovery which assigns value to it. Even if you did correct this logical mistake, you still would not be able to access the discovery variable because it is a local variable. You can either add return discovery to the end of the function and then discovery = zabbix_discovery(pingdom_data), or make it a global variable. Former would look somewhat like this:
discovery = []
def zabbix_discovery(pingdom_data):
global discovery
do what you want to do with it
zabbix_discovery(args)
Also even when you fix these things your code will throw another error because you are trying to access dictionary data in your function, which has no value assigned too. If it is assigned somewhere outside the function, you can easily fix that by adding global data in the beginning of your function.
And why do you have pingdom_data as an argument in your function if you don't use it anywhere?
I have a server.py which contains a function and other files like requestor1.py requestor2.py .... requestorN.py
Server.py contains a function :
def callmeforhelp()
return "I am here to help you out!"
and requestor1.py file calls the function callmeforhelp() and it has the imports needed to call the function from server.py
Is there a way my server.py knows which file is calling it?
Something similar like below :
When requestor1.py calls the function, then :
def callmeforhelp()
print "Now I am being called by : "+caller // caller must contain the value as requestor1.py or even full path of requestor1.py
return "I am here to help you out!"
Try it in your server file:
import inspect
def callmeforhelp():
result = inspect.getouterframes(inspect.currentframe(), 2)
print("Caller is: " + str(result[1][1]))
Here is a way to get at the caller's local attributes:
import sys
def callmeforhelp():
print("Called from", sys._getframe(1).f_locals['__file__'])
This is a feature of CPython and is not guaranteed to be present in other language implementations.
So, I am passing a environment variable from bash to python;
#!/usr/bin/env python2
import os
#connect("weblogic", "weblogic", url=xxx.xxx.xxx.xxx:xxxx)
os.environ['bash_variable']
via wlst.sh I can print exported bash_variable, but how do I execute stored variable? Basically, I am trying to remove the original connect statement and pass a variable that has said information. Thanks
Question though, why wouldn't you called the script with the variable as an argument and use sys.argv[] ?
By example something like this.
import os
import sys
import traceback
from java.io import *
from java.lang import *
wlDomain = sys.argv[1]
wlDomPath = sys.argv[2]
wlNMHost = sys.argv[3]
wlNMPort = sys.argv[4]
wlDPath="%s/%s" %(wlDomPath,wlDomain)
wlNMprop="/apps/bea/wls/scripts/.shadow/NM.prop"
try:
print "Connection to Node Manager"
print ""
loadProperties(wlNMprop)
nmConnect(username=NMuser,password=NMpass,host=wlNMHost,port=wlNMPort,domainName=wlDomain,domainDir=wlDPath,mType='ssl',verbose='true')
except:
print "Fatal Error : No Connection to Node Manager"
exit()
print "Connected to Node Manager"
The NM.prop file is a 600 file with the username/password for the NM.
EDIT :
So from what I understand you want to do something like this :
URLS = ['t3s://Host1:Port1','t3s://Host2:Port2','t3s://Host3:Port3']
for urls in URLS:
connect('somebody','password',urls)
{bunch of commands}
disconnect()
And the values of the list URLS would be define by the environment.
The way I see it you have 3 choices :
Have 1 script per environment, more or less identical save for the URLS list
Have 1 script but with a conditionnal branching on sys.argv[1] (the environment as a parameter) and create the list there.
Have 1 script which use a parameter file for each environment according to the environment. Each parameter file containing the list in question.
Something like that :
propENV = sys.argv[1]
propPath = "/path1/path2"
propFile = "%s/%s" %(propPath,propENV)
loadProperties(propFile)
I would probably use the properties file option myself as it is more flexible from an operational standpoint...at least IMHO.
I've been looking around for an answer to my original issue.. how do i determine (programmatically) that my win32api.ShellExecute statement executed successfully, and if a successful execution occurs, execute an os.remove() statement.
Researching I found out that the ShellExecute() call returns the HINSTANCE. Further digging I found that ShellExecute() will return an HINSTANCE > 32 if it was successful. My problem/question now is, how do i use it to control the rest of my program's flow? I tried using an if HINSTANCE> 32: statement to control the next part, but I get a NameError: name 'hinstance' is not defined message. Normally this wouldn't confuse me because it means i need to define the variable 'hinstance' before referencing it; however, because i thought ShellExecute is supposed to return HINSTANCE, i thought that makes it available for use?
Here is my full code where i am trying to implement this. Note that in my print_file() def i am assigning hinstance to the full win32api.ShellExecute() command in attempt to capture the hinstance along with explicitly returning it at the end of the function.. this isn't working either.
import win32print
import win32api
from os.path import isfile, join
import glob
import os
import time
source_path = "c:\\temp\\source\\"
def main():
printer_name = win32print.GetDefaultPrinter()
while True:
file_queue = [f for f in glob.glob("%s\\*.txt" % source_path) if isfile(f)]
if len(file_queue) > 0:
for i in file_queue:
print_file(i, printer_name)
if hinstance > 32:
time.sleep(.25)
delete_file(i)
print "Filename: %r has printed" % i
print
time.sleep(.25)
print
else:
print "No files to print. Will retry in 15 seconds"
time.sleep(15)
def print_file(pfile, printer):
hinstance = win32api.ShellExecute(
0,
"print",
'%s' % pfile,
'/d:"%s"' % printer,
".",
0
)
return hinstance
def delete_file(f):
os.remove(f)
print f, "was deleted!"
def alert(email):
pass
main()
With ShellExecute, you will never know when the printing is complete, it depends on the size of the file and whether the printer driver buffers the contents (the printer might be waiting for you to fill the paper tray, for example).
According to this SO answer, it looks like subprocess.call() is a better solution, since it waits for the command to complete, only in this case you would need to read the registry to obtain the exe associated with the file.
ShellExecuteEx is available from pywin32, you can do something like:
import win32com.shell.shell as shell
param = '/d:"%s"' % printer
shell.ShellExecuteEx(fmask = win32com.shell.shellcon.SEE_MASK_NOASYNC, lpVerb='print', lpFile=pfile, lpParameters=param)
EDIT: code for waiting on the handle from ShellExecuteEx()
import win32com.shell.shell as shell
import win32event
#fMask = SEE_MASK_NOASYNC(0x00000100) = 256 + SEE_MASK_NOCLOSEPROCESS(0x00000040) = 64
dict = shell.ShellExecuteEx(fMask = 256 + 64, lpFile='Notepad.exe', lpParameters='Notes.txt')
hh = dict['hProcess']
print hh
ret = win32event.WaitForSingleObject(hh, -1)
print ret
The return value of ShellExecute is what you need to test. You return that from print_file, but you then ignore it. You need to capture it and check that.
hinstance = print_file(i, printer_name)
if hinstance > 32:
....
However, having your print_file function leak implementation detail like an HINSTANCE seems bad. I think you would be better to check the return value of ShellExecute directly at the point of use. So try to move the > 32 check inside print_file.
Note that ShellExecute has very weak error reporting. If you want proper error reporting then you should use ShellExecuteEx instead.
Your delete/sleep loop is very brittle indeed. I'm not quite sure I can recommend anything better since I'm not sure what you are trying to achieve. However, expect to run into trouble with that part of your program.