Python script and class in the same file - python

I have a Python class that supposes to perform some tasks in the background by submitting itself to a cluster environment. e.g.
class AwesomeTaskController(object):
def run(bunch_of_tasks):
for task in bunch_of_tasks:
cmd = "%s %s" % (os.path.abspath(__file__), build_cli_paramters(task))
# call the API to submit the cmd
if __name__ == "__main__":
#blah blah do stuff with given parameters
All is well for the first time that this class was run. When it was run the first time, a pyc file is created. This pyc file isn't executable (permission wise).
So the 2nd time I use this class, the command will use the pyc directly and complains that permission is denied. Perhaps I am approaching this from the wrong angle?

.pyc files aren't executable themselves; you always have to execute the .py file. The .pyc file is just a compiled version of the .py file that Python generates on the fly to save itself some time the next time you run the .py file.
In your case, all you should need to do is check to see if __file__ ends with ".pyc" and remove the trailing "c". You could do that by, say, replacing __file__ in your script with:
(__file__[:-1] if __file__.endswith(".pyc") else __file__)
and that should solve your problem.

Related

Linking multiple python scripts to run one after another

I have three python scripts. One gathers data from database(data_for_report.py), another generates report from that data and creaters .xlsx file(report_gen.py) and the last one modifies the style of that excel file(excel_style.py).
Now all three files are in the same directory and what I do now is simply execute scripts one after another in the interpreter to get the report. I want to make everything work with one click so people who need this report could do it themselves. I thought of creating an exe with pyinstaller, but I can not think of a way to link my scripts together so that when data_for_report.py ends its job report_gen.py is started and so on.
I tried to put
subprocess.call("report_gen.py", shell=True)
at the end of the first script, but nothing happens, I just get this:
Out[2]: 1
How could I do this?
Actually, This problem can be solved by using batch programming. Your python files will run in batches i.e. one file after the other. I am assuming your all three python files resides in folder ReportGenerator with Path as C:\ReportGenerator so adjust accordingly the PATH as of your system (Please care for \ and / in PATH of folder having the python files).
Your files are which need to be executed:
data_for_report.py
report_gen.py
excel_style.py
Now open a Notepad file and write the below lines.
cd C:/ReportGenerator
python data_for_report.py
python report_gen.py
python excel_style.py
PAUSE
Now save this file with file_Name.bat anywhere u want in system and remember it. After saving the batch file icon will form on saving.
Now Open window command prompt and just drag this batch file to window command prompt.
Why not encapsulate all the logic for each script in a function, make a new file which imports all the 3 functions, and then run that script.
So if the scripts are
data_for_report.py
def f1():
...
report_gen.py
def f2():
...
excel_style.py
def f3():
...
Then the final script which you will run is :
from data_for_report import f1
from report_gen import f2
from excel_style import f3
f1()
f2()
f3()

Python scripts single instance does not work

I am using this file from tendo to be able to create a single instance for a script. Using Python 2.7
In a main.py script I am add a code line like this:
sgl_ins = singleton.SingleInstance()
.. main.py logic code ...
It creates the .lock file but the thing is that it is throwing me an error when the app logic finishes, more precisely when it reaches this part in the singleton.py code
try:
if sys.platform == 'win32':
if hasattr(self, 'fd'):
os.close(self.fd)
os.unlink(self.lockfile)
in the console I get
[Error 32] The process cannot access the file because it is being used by another process: ...
So it is weird because it should close the file that had been locked but it looks like when it tries to close it can not do it.
There is no other app or script instance running at the same time. I am running it into a Windows env the user has all permissions granted.
Any suggestion or comment?

Python Kodi - Force Python handling .pyo like .py

Hey guys i definitely getting crazy
i want to force Python to handle a .pyo like a .py
i got kodi xbmc forked and getting crazy
i already tried out and changed multiple lines and nothing changed?
i linked them here:
const std::string ADDON_PYTHON_EXT = "*.py";
changed this line to *.pyo
return URIUtils::HasExtension(m_strPath, ".py"); changed this line to. .pyo
i thought that would be enough after compiling, still nothing happens when try to open a add-on
still python does not load .pyo files and does not handle them as .py
btw: i figured out deleting all .py files in the folder and just let the first loaded .py file there so 1 -> .py and the others are all .pyo the add-on works.
but when deleting this firstly loaded .py and using this as a .pyo
it fails.
So what do i have to change that it always use .pyo
First UPDATE:
i tried it out,
it does indeed work as a workaround
Created a dummy -> include.py
with just 1 line import service was enough.
But i want to fix this directly in kodi.
in documentions
"If there is a current pyc file, this is taken as the compiled version, so no compile step has to be taken before running the command. Otherwise the py file is read, the compiler has to compile it"
So easy said,
execute .py if not available check if .pyo
but i cannot find where to change / add this method
i cannot find even the method right for the execution
Second Update:
i added these lines in githublink to file
//pyoextension == script
std::string pyoextension = script;
//Check if the file does exist
if (!CFile::Exists(script, false))
{
//pyoextension append o to get -> .pyo
pyoextension = script + "o";
//Check if pyoextension exist -> .pyo
//if not nothing exist throw error
if (!CFile::Exists(pyoextension, false)){
CLog::Log(LOGERROR, "%s - Not executing non-existing script %s", __FUNCTION__, script.c_str());
return -1;
}
LanguageInvokerPtr invoker = GetLanguageInvoker(pyoextension);
return ExecuteAsync(pyoextension, invoker, addon, arguments);
}
LanguageInvokerPtr invoker = GetLanguageInvoker(script);
return ExecuteAsync(script, invoker, addon, arguments);
Checking if the the add-on does not exist as a .py file checking if the .pyo file is there, and execute that instead. But still the checking does work, but it still throws an error out that it cannot start the script
Changing such line (const std::string ADDON_PYTHON_EXT = "*.py"; changed this line to *.pyo) is not a good solution
Main reason is that the kodi is configured to use .py extension to be load from addon.xml file which tradition is followed by all the addon. Changing such headers file will only result to work addon only in your custom build kodi and you have to modify all other addon along with it.
The solution I prefer most is you should follow below steps:
Create a function in your python script (let's call it as function named service() which execute all the necessary code from your file named service.py)
Now create a python file (include.py) to include it in addon.xml containing code as below:
include.py
import service
service.service()
It might not even be worth it, Kodi is moving to python3 soon, and python3 dropped pyo files. It might use pyc then, but that's not sure right now.

Python line by line execution

I couldn't fine solution for this question using search option so my question is:
I have a script that does the job but only for one file. Just to explain what`s going on here:
import sys
sys.path.append('C:\Program Files\FME\fmeobjects\python27')
import fmeobjects
runner = fmeobjects.FMEWorkspaceRunner()
workspace = 'C:\FME\Project_1.fmw'
parameters = {}
parameters['SourceDataset_ACAD'] ='C:\AutoCAD\Project_1.dwg'
parameters['DestDataset_OGCKML'] ='C:\Maps_KMZ\Project_1.kmz'
runner.runWithParameters(workspace, parameters)
try:
# Run Workspace with parameters set in above directory
runner.runWithParameters(workspace, parameters)
# or use promptRun to prompt for published parameters
#runner.promptRun(workspace)
except fmeobjects.FMEException as ex:
# Print out FME Exception if workspace failed
print ex.message
else:
#Tell user the workspace ran
print('The Workspace is ran successfully'.format(workspace))
runner = None
This script executes FMW file that does conversion from AutoCAD DWG (C:\AutoCAD) to KMZ file and stores it in C:\Maps_KMZ folder. Now, I need to do the same thing for about 20-ish FME files that are in the same source folder.
Is it possible to execute each file at the time and add specific time frame between two executions let`s say 2 minute pause between them, because I can not run 2 or more conversions at the same time, it would crash Windows.
Thank you very much for your help!
I suggest that you modify your script to use command line arguments. You can either use sys.argv directly for a very simple interface or the parseargs module for more complex options.
You can write the interface to accept individual files names or directory names. To traverse the files of a directory, look at os.walk().

Trying to run a python script with crontab every hour, but one section of the python code does not execute

I wrote a script using python and selenium that tries to register for a class called puppy play. Crontab runs the script every hour and sends any output to a file called "cronpup.log". This section of code is in my python script and it just checks to see if the registration was successful or not then appends the results to the file "pup.log".
# Pup Logger
f = open("pup.log", "a+")
f.write(time.strftime("%Y-%m-%d %H:%M:%S "))
if pups == 1:
f.write("Pups!\n")
elif pups == 0:
f.write("No Pups\n")
else:
f.write("Ruh Roh, Something is wrong\n")
f.close()
This creates the "pup.log" file with entries like the following
$ pup.log
2014-10-17 17:49:18 No Pups
2014-10-17 19:37:28 No Pups
I can run the python script just fine from the terminal, but when crontab executes the script no new entries are made in "pup.log". I've checked the output from crontab and have found nothing. Here is crontab's output
$ cronpup.log
.
----------------------------------------------------------------------
Ran 1 test in 81.314s
OK
It seems like crontab is just ignoring that section of the code, but that seems pretty silly. Any ideas how to get this working?
The line
f = open("pup.log", "a+")
is your problem. Open is looking the the current working directory for pup.log, creating it if necessary, and appending to it. If you run from the terminal while in the same directory as the python script, that's where pup.log will appear. The cwd when running from cron is the home directory of the user the job is running as, so when run from cron it's dropping a pup.log file somewhere else on your system.
You can either hardcode a full path, or use
os.chdir(os.path.dirname(os.path.abspath(__file__)))
to set the current working directory to the directory the python file is in, or modify the above to put pup.log whereever you like.

Categories

Resources