Skip to content

Instantly share code, notes, and snippets.

@LukeB42
Last active May 12, 2016 06:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LukeB42/42951473a220f7837bc51827208dffde to your computer and use it in GitHub Desktop.
Save LukeB42/42951473a220f7837bc51827208dffde to your computer and use it in GitHub Desktop.
A scaffold for rapidly developing a REST API.
#!/usr/bin/env python3
# Implements a scaffold for rapidly developing a REST API.
import os
import sys
import pwd
import time
import optparse
from gevent.wsgi import WSGIServer
from flask import Flask
from flask.ext import restful
prog = sys.argv[0].replace("./","").replace(".py", "")
app = Flask(prog)
api = restful.Api(app, prefix='/v1/')
app.version = "0.0.1"
# Business logic goes here.
# http://flask-restful.readthedocs.io/
class Service(restful.Resource):
def get(self):
return {}, 200
api.add_resource(Service, "index")
def Daemonise(pidfile):
try:
pid = os.fork()
if pid > 0:
sys.exit(0) # End parent
except OSError as e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (err.errno, err.strerror))
sys.exit(-2)
os.setsid()
os.umask(0)
try:
pid = os.fork()
if pid > 0:
try:
# TODO: Read the file first and determine if already running.
f = file(pidfile, 'w')
f.write(str(pid))
f.close()
except IOError as e:
logging.error(err)
sys.stderr.write(repr(err))
sys.exit(0) # End parent
except OSError as err:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (err.errno, err.strerror))
sys.exit(-2)
for fd in (0, 1, 2):
try:
os.close(fd)
except OSError:
pass
if __name__ == '__main__':
description = ""
epilog = "Psybernetics %s." % time.asctime().split()[-1]
parser = optparse.OptionParser(prog=prog,version=app.version,description=description,epilog=epilog)
parser.set_usage('./%s [options]' % prog)
#parser.add_option("--config", dest="config", action="store", default=None, help="(defaults to %s.config)" % prog)
parser.add_option("-a", "--address", dest="address", action="store", default='0.0.0.0', help="(defaults to 0.0.0.0)")
parser.add_option("-p", "--port", dest="port", action="store", default='5000', help="(defaults to 5000)")
parser.add_option("--key", dest="key", action="store", default=None, help="SSL key file")
parser.add_option("--cert", dest="cert", action="store", default=None, help="SSL certificate")
parser.add_option("--pidfile", dest="pidfile", action="store", default="%s.pid" % prog, help="(defaults to ./%s.pid)" % prog)
parser.add_option("--logfile", dest="logfile", action="store", default="%s.log" % prog, help="(defaults to ./%s.log)" % prog)
parser.add_option("--stop", dest="stop", action="store_true", default=False)
parser.add_option("--debug", dest="debug", action="store_true", default=False, help="Log to stdout")
parser.add_option("-d", dest="daemonise", action="store_true", default=False, help="Run in the background")
parser.add_option("--run-as", dest="run_as", action="store",default=None, help="(defaults to the invoking user)")
(options,args) = parser.parse_args()
log = print
if (pwd.getpwuid(os.getuid())[2] == 0) and not options.run_as:
print("Running as root is not permitted.\nExecute this as a different user.")
raise SystemExit
sock = (options.address, int(options.port))
if options.run_as:
sock = socket(family=_socket.AF_INET)
try:
sock.bind((options.address, int(options.port)))
except _socket.error:
ex = sys.exc_info()[1]
strerror = getattr(ex, 'strerror', None)
if strerror is not None:
ex.strerror = strerror + ': ' + repr(options.address+':'+options.port)
raise
sock.listen(50)
sock.setblocking(0)
uid = pwd.getpwnam(options.run_as)[2]
try:
os.setuid(uid)
log("Now running as %s." % options.run_as)
except Exception as e: raise
httpd = WSGIServer(sock, app, certfile=options.cert, keyfile=options.key)
log("Binding to %s:%s" % (options.address, options.port))
if options.daemonise:
f = file(options.pidfile, 'a')
f.write(' %i' % httpd_process.pid)
f.close()
try:
httpd.serve_forever()
except KeyboardInterrupt:
log("Stopping...")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment