Is it possible to use executable files with Django. For instance I have a Django form that takes input a file. I want to pass the file as an argument to a script/executable/program and output the results back with django. What would be a good starting point for this idea? Thanks a lot
subprocess
The question you should you be asking is it possible in python. Essentially all you would need to do it take in the inputs, into a python script which you can call from your django view or what not. Once there run the execute subprocess command with your executable, and take in the results. :)
Goodluck.
do you want some things like this?
>>> import commands
>>> commands.getstatusoutput('pwd')
(0, '/home/efazati')
Yes, you can do this. There are a few different ways to do it in Python. If you want to read the output and use it then you probably want popen, found at http://docs.python.org/library/os.html#os.popen
Warning, this can be very dangerous. If the data added to the command line is malicious (even accidentally) then you could cause bad stuff to happen on the server. You're effectively giving people who submit forms the ability to run commands on the server with the same permissions the web server has.
import os
ls_fd = os.popen('ls -l /tmp')
output = ls_fd.read()
ls_fd.close()
Doing it this way your ls_fd is a file like object. you .read() it like a file. You can only do it once, then you're at the end of the file. Likewise, you should .close() it when you're done.
Strongly consider against adding user input to the command line. You can create a list of possible options and then give the user a choice which one they want. Then instead of taking the user's input and adding it to the end of the command line you can use one of your pre-configured command lines and execute that.
Related
I'm trying to restrict write and read access to a Python file. Suppose I have the following code:
with open('test.py', 'w+') as file:
file.write('''
open("document.txt", "w+").write("Hello, World!")
open("document.txt", "r+").read()
''')
By executing this code, a new file is created that in the new file there are two lines of code to write and read a another file.
I want the file created by executing this code (test.py) to hit PermissionError while running and not be able to create a new file or read it; Also, this file is only executable and normal commands work in it, but it can not access other files.
If I read you correctly, this is not a python problem, but an environment problem. I understand the question as something like 'how do I prevent python code from executing arbitrary reads or writes?'. There would be a trivial solution (modifying the generated test.py so it throws an error) but presumably that's not what you want.
The easiest way to make python hit a PermissionError... is to make sure it doesn't have permissions. So run your code as a user with extremely limited permissions---specifically no write permissions anywhere---or perhaps no default permissions at all, and use something like facls to grant permission to read specific files explicitly from a more priveleged sentinel process. (This assumes you are running Linux, but there are likely other ways to do this in different OSs).
Alternatively, look into various sandboxing techniques to give you a python interpreter with the relavent modules replaced with modules which throw errors, or an environment where outside modification is impossible.
It would help if you made it clearer why this is important, and why you are writing a python script with another python script (is this just an example of malicious action?).
You could technically change the permission of the file itself on the filesystem your trying to access.
Check the previous thread about changing permissions
os.chmod(path, <permission value>)
Where 000 is to disable anyone other than root to edit on linux.
I have a collection of expert advisor (EA) scripts written in the MQL5 programming language for the stock/forex trading platform, MetaTrader5. The extension of these files is mq5. I am looking for a way to programatically run these MQL5 files from my Python script on a regular basis. The EAs do some price transformations, eventually saving a set of csv files that will later be read by my Python script to apply Machine Learning models on them.
My first natural choice was the Python API for MetaTrader5. However, according to its documentation, it "is designed for convenient and fast obtaining of exchange data via interprocessor communication directly from the MetaTrader 5 terminal" and as such, it doesn't provide the functionality I need to be able to run MQL scripts using Python.
I have found some posts here on SO (such as #1, #2) about executing non-python files using Python but those posts seemed to always come with the precondition that they already had Python code written in them, only the extension differed - this is different from my goal.
I then came across Python's subprocess module and started experimenting with that.
print(os.path.isfile(os.path.join("path/to/dir","RSIcalc.mq5")))
with open(os.path.join("path/to/dir","RSIcalc.mq5")) as f:
subprocess.run([r"C:\Program Files\MetaTrader 5\terminal64.exe", f], capture_output=True)
The print statement returns True, so the mq5 file exists in the specified location. Then the code opens the MetaTrader5 terminal but nothing else happens, the EA doesn't get executed, process finishes immediately after that.
Am I even on the right track for what I'm trying to achieve here? If yes, what might be the solution for me to run these MQL5 scripts programatically from Python?
Edit:
I use Windows 10 64-bit.
subprocess is indeed the right module for what you want to achieve. But let's look at what you're doing here:
with open(os.path.join("path/to/dir","RSIcalc.mq5")) as f
You're creating a file descriptor handle called f, which is used to write or read contents from a file. If you do print(f) you'll see that it's a python object, that converted to string looks like <_io.TextIOWrapper name='RSIcalc.mq5' mode='r' encoding='UTF-8'>. It is extremely unlikely that such a string is what you want to pass as a command-line parameter to your terminal executable, which is what happens when you include it in your call to subprocess.run().
What you likely want to do is this:
full_path = os.path.abspath(os.path.join("path/to/dir","RSIcalc.mq5"))
result = subprocess.run([r"C:\Program Files\MetaTrader 5\terminal64.exe", full_path], capture_output=True)
Now, this assumes your terminal64 can execute arbitrary scripts passed as parameters. This may or may not be true - you might need extra parameters like "-f" before passing the file path, or you might have to feed script contents through the stdin pipe (unlikely, on Windows, but who knows). That's for you to figure out, but my code above should probably be your starting point.
I don’t think you need to be passing a file object to your sub process statement. In my experience. A program will run a file when the path to the file is provided as a command line argument. Try this:
subprocess.run([r"C:\\Program Files\\MetaTrader 5\\terminal64.exe", os.path.join(“path/to/dir”, “RSIcalc.mq5”], capture_output=True)
This is the same as typing C:\Program Files\MetaTrader 5\terminal64.exe path\to\dir\RSIcalc.mq5 in your terminal.
I want to create a SQL like language using Python. I want it to look like CMD but always open a proper dedicated tab instead of opening Command prompt to take in the commands. Any recommendations for modules that let you create a command line?
I could use Tkinter and take input from user and process it but I'm curious if there's a better way of doing this.
If I understood correctly, if you desire a "shell like" UI experience you can try
something more like a TUI (Text User Interface), I recommend :
prompt-toolkit: https://github.com/prompt-toolkit/python-prompt-toolkit
npyscreen: https://github.com/npcole/npyscreen
Also take a look at this answer: Input in a Python text-based GUI (TUI)
use start (your file's name) in window cmd when you have the directory contains your file set as directory, so the whole thing would be like:
cd C:/username/my folder/subfolder/folder containing your python file don't forget next line here, start filename.py
end result should be what you want. and you don't need a module, input() is going to cut it.
I need to use an old-fashioned DOS/Windows executable (the source is not available). It uses two input files and produces one output file.
I have to run this several thousands times, using different input files. I wrote a simple python script looping over input files to automate this.
The problem is that this exe finishes every single run with the immortal "press Enter".
I start the script, keep the key pressed, 'returns' accumulate in the bufor and the script runs for a while producing several outputs.
Is there any more elegant way to proceed (i.e. without using the finger and staring at the monitor)?
I have already tried some obvious solutions (e.g. os.system('return'), os.system('\n')) but they do not work.
Next day edit:
#Eric, many thanks for the code, it works. I also thank others who contribute, and sorry for slopply written question and unformatted code in the comment (it was 3.30 am :)
From the information in your comment, what I think you want is something like:
import subprocess
for i in range(1, 20001):
command = "wine executable.exe input{number}.txt > output{number}.txt".format(number=i)
p = subprocess.Popen(command, stdin=subprocess.PIPE, shell=True)
# send a newline
p.communicate(input="\n")
Use Python's subprocess module and run your executable with Popen.
Then you can send "enter" to the process with communicate.
Have you tried os.system(‘\r\n’)? I think that’s the newline character on windows.
Edit: Your answer also used a forward slash instead of a backslash--definitely try the other way too, unless that’s just a typo.
How can i change password of ubuntu root user by python script? Thanks.
There are two main ways to go about this -
One is calling the passwd command line tool from python (such as via stdlib's subprocess module). If your script isn't running as root, you'll need to wrap using the "su" or "sudo" commands in order to elevate to root privledge. Writing the expected data to stdin should be sufficient, but if you find you need to perform different actions based on exactly what the sudo/passwd prompts say, the pexpect module may be helpful.
The second is writing directly to the /etc/shadow file where the password hashes are stored. This will definitely require your script to run as root, in order to have read/write perms on /etc/shadow. Stdlib offers the spwd module for accessing /etc/shadow, but it's read-only, so you'll have to roll your own reader/writer... the csv module might be useful, /etc/shadow is close to being a csv file with a ":" separator, but with some minor differences.
If you choose the second route, you'll need to be able to generate new hashes of replacement password, and insert them into the shadow file. The fastest way on linux is to use the stdlib crypt module, but you'll have to take care of salt generation, and setting the appropriate password hash prefix ("$5$", "$6$" etc). Alternately, the host_context object in the Passlib library can take care of most of that for you (disclaimer: I'm the author of that library).
In general, I'd recommend the first route if possible - modifying /etc/shadow directly is fraught with danger - if you mess up the /etc/shadow file, you won't be able to log in. If you go this route, back up the file a lot.
You can modify /etc/passwd (/etc/shadow) with Python script which will need root permissions sudo python modify.py /etc/passwd (where modify.py is your script that will change password)
You can use the commands module to pipe output to the terminal.
x = commands.getstatusoutput("passwd root")
However, you'll have to get creative trying to enter the values for "Old Password:" and "New Password:." The variable x wont be assigned until the command is finished, and the command won't finish until the old and new passwords are entered. If you just use the command module a second time, then it will simply spawn a new subprocess. So, like others have said, just write to /etc/shadow using the open function.