'Load and execute a full python script from a raw link?
I'm facing some problems trying to load a full python script from my pastebin/github pages.
I followed this link, trying to convert the raw into a temp file and use it like a module: How to load a python script from a raw link (such as Pastebin)?
And this is my test (Using a really simple python script as raw, my main program is not so simple unfortunately): https://trinket.io/python/0e95ba50c8
When I run the script (that now is creating a temp file in the current directory of the .py file) I get this error:
PermissionError: [Errno 13] Permission denied: 'C:\\Users\\BOT\\Images\\tempxm4xpwpz.py'
Otherwise I also treid the exec()
function... No better results unfortunately.
With this code:
import requests as rq
import urllib.request
def main():
code = "https://pastebin.com/raw/MJmYEKqh"
response = urllib.request.urlopen(code)
data = response.read()
exec(data)
I get this error:
File "<string>", line 10, in <module>
File "<string>", line 5, in hola
NameError: name 'printest' is not defined
Since my program is more complex compared to this simple test, I don't know how to proceed... Basically What I want to achieve is to write the full script of my program on GitHub and connect it to a .exe so if I upgrade the raw also my program is updated. Avoiding to generate and share (only with my friends) a new .exe everytime...
Do you think is possible? If so.. what am I doing wrong?
PS: I'm also open to other possibilities to let my friends update the program without downloading everytime the .exe, as soon as they don't have to install anything (that's why I'm using .exe).
Solution 1:[1]
Disclaimer: it is really not a good idea to run an unverified (let alone untrusted) code. That being said if you really want to do it...
Probably the easiest and "least-dirty" way would be to run whole new process. This can be done directly in python. Something like this should work (inspiration from the answer you linked in your question):
import urllib.request
import tempfile
import subprocess
code = "https://pastebin.com/raw/MJmYEKqh"
response = urllib.request.urlopen(code)
data = response.read()
with tempfile.NamedTemporaryFile(suffix='.py') as source_code_file:
source_code_file.write(data)
source_code_file.flush()
subprocess.run(['python3', source_code_file.name])
You can also make your code with exec
run correctly:
What may work:
exec(data, {})
-- All you need to do, is to supply{}
as second argument (that is useexec(data, {})
). Functionexec
may receive two additional optional arguments -- globals and locals. If you supply just one, it will use the same directory for locals. That is the code within theexec
would behave like sort-of "clean" environment, at the top-level. Which is something you aim for.exec(data, globals())
-- Second option is to supply the globals from your current scope. This will also work, though you probably has no need to give theexec
ucted code access to your globals, given that that code will set-up everything inside anyway
What does not work:
exec(data, {}, {})
-- In this case the executed code will have two different dictionaries (albeit both empty) for locals and globals. As such it will behavie "as-in" (I'm not really sure about this part, but as I tested it, it seams as such) the function. Meaning that it will add theprintest
andhola
functions to the local scope instead of global scope. Regardless, I expected it to work -- I expected it will just query theprintest
in thehola
function from the local scope instead of global. However, for some reason thehola
function in this case gets compiled in such a way it expectsprintest
to be in global scope and not local, which is not there. I really did not figured out why. So this will result in theNameError
exec(data, globals(), locals())
-- This will provide access to the state from the caller function. Nevertheless, it will crash for the very same reason as in the previous caseexec(data)
-- This is just a shorthand forexec(data, globals(), locals()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Drecker |