Execute a script without a console window without using pythonw.exe - python

I have a python script that uses the http.server module that I would like to run without a terminal window being shown. Unfortunately, due to how I'm doing this, running the script in pythonw.exe does not work.
Here is the script:
import os
from http.server import CGIHTTPRequestHandler, HTTPServer
handler = CGIHTTPRequestHandler
handler.cgi_directories = ['/scripts']
server = HTTPServer(('localhost', 1271), handler)
server.serve_forever()
Unfortunately, I don't know any way get any error logs because, y'know, pythonw doesn't show the console. If anyone can tell me how to get the error logs, I'll be happy to add them to the bottom of this post.
I'm running 64-bit Windows 10 and python 3.6.6, if that makes a difference.
I'm sorry if this is a stupid question, but I—for the life of me—cannot find a solution anywhere.

You can just store output to a text file like this:
from http.server import CGIHTTPRequestHandler, HTTPServer
import sys
handler = CGIHTTPRequestHandler
handler.cgi_directories = ['/scripts']
server = HTTPServer(('localhost', 1271), handler)
sys.stderr = open('log.txt', 'w', 1)
server.serve_forever()

Related

Run Python HTTPServer in Background windows 10 Powershell

I have tested several proposal from anwers from other post but I can't get my server con run on the background from powershell using >pythonw server.py as I do with my other scrips.
my code is:
#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import socketserver
from urllib.parse import urlparse
from urllib.parse import parse_qs
import requests
import asyncio
import sys, os, signal, threading
class MyHttpRequestHandler(SimpleHTTPRequestHandler):
def end_headers (self):
self.send_header('Access-Control-Allow-Origin', '*')
SimpleHTTPRequestHandler.end_headers(self)
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
html = f"31"
self.wfile.write(bytes(html, "utf8"))
def create_server():
port = 8000
handler_object = MyHttpRequestHandler
my_server = socketserver.TCPServer(("", port), handler_object)
print("serving at port:" + str(port))
my_server.serve_forever()
threading.Thread(target=create_server).start()
the server runs just ok on foreground (calling it from PW >python server.py) but in background it does not reply.
I’m not sure it could easily be done using PowerShell as that is meant to be an interactive shell rather than a background system.
A couple of ideas. One is harder than the other.
Compile the python code into an EXE using something like PyInstaller and then run the EXE as a Windows Service (which is difficult to do at best)
Set up a scheduled task that runs the python script using pythonw when you log in to the system. This option would probably be the easier of the two and could be done through PowerShell using New-ScheduledTask
I suppose a third way would be through IIS but I’m not familiar with that unfortunately.
Edit: one other idea! Install Docker for Windows and run the server on a container rather than on your Windows host itself.

Python http.server CGI

Need to run python scrips with CGI options from a local python server
At the moment on my Apache I use CGI to get all the get and post requests anyone does to my python scripts to tell them to do things.
For example if I do a get request to 127.0.0.1:8080?filename=yomomma
My python script should print 'yomomma'
#!/usr/bin/python3
import cgi, os
form = cgi.FieldStorage()
fileitem = form['filename']
print(fileitem)
Heres the server im running in python (I have no idea what im doing apparently)
from http.server import *
from urllib import parse
import os
import cgi
class GetHandler(CGIHTTPRequestHandler):
def do_GET(self):
form = cgi.FieldStorage()
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.end_headers()
self.wfile.write('<meta http-equiv="refresh" content=1; URL=http://127.0.0.1:8080" /><pre>'.encode('utf-8'))
self.wfile.write(str(os.popen('python my_site.py').read()).encode('utf-8'))
if __name__ == '__main__':
from http.server import HTTPServer
server = HTTPServer(('localhost', 8080), GetHandler)
print('Starting server, use <Ctrl-C> to stop')
server.serve_forever()
Id like to be able to point this at any python file and get that python file to read the CGI parameters
It's unclear what you're asking to do here.
If you just want to run CGI scripts on HTTPServer, that's very simple. CGIHTTPRequestHandler is not meant to be subclassed, which is what you have done, and you don't need to rewrite the do_X functons. It simply returns the output of a CGI script like any other server, if it's under a cgi_directories folder. Read this.
So in the main function, you would have:
server = HTTPServer(('localhost', 8080), CGIHTTPRequestHandler)
Then just call a CGI script normally:
127.0.0.1:8080/cgi-bin/myscript.cgi?filename=yomomma
If you want to utilise http.server to handle requests, you need to use BaseHTTPRequestHandler, not CGIHTTPRequestHandler. Getting form data is then slightly different but easy. Read the section of this under "HTTP POST"

Python CGIHTTPServer Default Directories

I've got the following minimal code for a CGI-handling HTTP server, derived from several examples on the inner-tubes:
#!/usr/bin/env python
import BaseHTTPServer
import CGIHTTPServer
import cgitb;
cgitb.enable() # Error reporting
server = BaseHTTPServer.HTTPServer
handler = CGIHTTPServer.CGIHTTPRequestHandler
server_address = ("", 8000)
handler.cgi_directories = [""]
httpd = server(server_address, handler)
httpd.serve_forever()
Yet, when I execute the script and try to run a test script in the same directory via CGI using http://localhost:8000/test.py, I see the text of the script rather than the results of the execution.
Permissions are all set correctly, and the test script itself is not the problem (as I can run it fine using python -m CGIHTTPServer, when the script resides in cgi-bin). I suspect the problem has something to do with the default CGI directories.
How can I get the script to execute?
My suspicions were correct. The examples from which this code is derived showed the wrong way to set the default directory to be the same directory in which the server script resides. To set the default directory in this way, use:
handler.cgi_directories = ["/"]
Caution: This opens up potentially huge security holes if you're not behind any kind of a firewall. This is only an instructive example. Use only with extreme care.
The solution doesn't seem to work (at least for me) if the .cgi_directories requires multiple layers of subdirectories ( ['/db/cgi-bin'] for instance). Subclassing the server and changing the is_cgi def seemed to work. Here's what I added/substituted in your script:
from CGIHTTPServer import _url_collapse_path
class MyCGIHTTPServer(CGIHTTPServer.CGIHTTPRequestHandler):
def is_cgi(self):
collapsed_path = _url_collapse_path(self.path)
for path in self.cgi_directories:
if path in collapsed_path:
dir_sep_index = collapsed_path.rfind(path) + len(path)
head, tail = collapsed_path[:dir_sep_index], collapsed_path[dir_sep_index + 1:]
self.cgi_info = head, tail
return True
return False
server = BaseHTTPServer.HTTPServer
handler = MyCGIHTTPServer
Here is how you would make every .py file on the server a cgi file (you probably don't want that for production/a public server ;):
import BaseHTTPServer
import CGIHTTPServer
import cgitb; cgitb.enable()
server = BaseHTTPServer.HTTPServer
# Treat everything as a cgi file, i.e.
# `handler.cgi_directories = ["*"]` but that is not defined, so we need
class Handler(CGIHTTPServer.CGIHTTPRequestHandler):
def is_cgi(self):
self.cgi_info = '', self.path[1:]
return True
httpd = server(("", 9006), Handler)
httpd.serve_forever()

can not restart squid with cronjob using python

I have written a simple python script to check if squid works normally
/scripts/proxychecker
#!/usr/bin/python
import urllib2
import sys, os, time
import socket
socket.setdefaulttimeout(5)
proxy_support = urllib2.ProxyHandler({'http': 'http://127.0.0.1:3128/'})
opener = urllib2.build_opener(proxy_support)
urllib2.install_opener(opener)
try:
response = urllib2.urlopen('http://python.org/')
html = response.read()
except:
#os.system("/etc/init.d/squid3 stop");
#os.system("/etc/init.d/squid3 start");
os.system("/etc/init.d/squid3 restart");
#os.system("service squid3 restart");
I shutdown squid, and manually executed this script "/scripts/proxychecker ",
it did bring up squid
but if I add this script to cron job:
*/1 * * * * /scripts/proxychecker >/root/debug.txt
it did not work
and from /root/debug.txt
it said
"Since the script you are attempting to invoke has been converted to an
Upstart job, you may also use the start(8) utility, e.g. start squid3"
I do not think this is the reason why squid not be brought up
because I have changed command as bellows , and still did not work
#os.system("/etc/init.d/squid3 stop");
#os.system("/etc/init.d/squid3 start");
os.system("/etc/init.d/squid3 restart");
#os.system("service squid3 restart");
it is a strange problem
also
cron is created by root
and this script also executed by root, permission should not be the reason
Use restart squid instead of service squid restart.

Why do I get a 500 error when running a CGI from `public_html`, when it works with a python CGI server?

Summary: Python cgi script runs as expected when called from a simple python debug server, but fails with 500 Premature end of script headers error when run from ~/public_html/cgi-bin/
Problems
My CGI script works fine when run through a simple python webserver, and I see the right output when navigating to nameofmyhost.com:8080/...
However, when running the same script from my public_html/cgi-bin directory it gives me a 500 premature end of script headers error. What can I do to fix this?
The permissions on the file seem ok:
drwxrwxrwx cgi-bin
-rwxr-xr-x cgi-bin/generate_list.py
This is simple_httpd.py, the simple python webserver
from http.server import HTTPServer, CGIHTTPRequestHandler
port = 8080
httpd = HTTPServer(('', port), CGIHTTPRequestHandler)
print("Starting simple_httpd on port: " + str(httpd.server_port))
httpd.serve_forever()
CGI script generate_list.py:
#! /usr/local/bin/python3
import athletemodel
import yate
import glob
data_files = glob.glob("data/*.txt")
athletes = athletemodel.put_to_store(data_files)
print(yate.start_response())
print(yate.include_header("Coach Kelly's List of Athletes"))
print(yate.start_form("generate_timing_data.py"))
print(yate.para("Select an athlete from the list to work with:"))
for each_athlete in athletes:
print(yate.radio_button("which_athlete", athletes[each_athlete].name))
print (yate.end_form("Select"))
print(yate.include_footer({"Home": "/index.html"}))
I'm guessing I need to maybe explicitly state my directory somewhere, maybe?
PS: I am going through the Head First Python book by Oreilly
Debugging steps
Check that the server can locate my files
Server finds simple html file in public_home [OK]
Check that the CGI script can execute without error.
Content-type: text/html
<html>
<head>
<title>Coach Kelly's List of Athletes</title>
[...]
CGI script ran from command line - outputs as expected [OK]
Check that the server can execute a simple CGI script in the same location
Try a simple CGI script to see if the server is able to execute any CGI scripts at all:
#!/usr/local/bin/python3
print("Content-Type; text/html")
print("")
print("<html><body><h1>hello</h1></body></html>")
Server fails to execute simple CGI script, giving the same error [FAIL]
Fixes
Fix 1: Change the data path to be absolute instead of relative:
- data_files = glob.glob("data/*.txt")
+ data_files = glob.glob("/home/delliott/public_html/webapp/data/*.txt")
The problem is that the base of your school webserver is not the same as the base of the simple_httpd.py server. This means that you will have to provide absolute paths to your data directory instead of relative paths.
Change the following lines:
- data_files = glob.glob("data/*.txt")
+ data_files = glob.glob("/home/<username>/public_html/data/*.txt")
This should now behave as expected (if I understand your problem correctly.)
[Edit]: A quick way to check if your cgi-bin scripts work is to run them from the command line. Log into your school server and try the cgi script ion its own:
$ cd /home/<username>/public_html/
$ python3 my_cgi_script.py
This should print out the html that you expect, or a stack trace.

Categories

Resources