Last active
March 21, 2025 01:55
-
-
Save lwcorp/7d54223bacc4dfc272762686c0159c80 to your computer and use it in GitHub Desktop.
Run Python code via cPanel without restarting or timing out, and also use Flask
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import json | |
import html | |
import signal | |
from datetime import datetime | |
from flask import Flask, render_template, request, jsonify | |
# Check if `signal.alarm` is supported | |
signal_supported = hasattr(signal, 'SIGALRM') | |
if signal_supported: | |
class TimeoutException(Exception): | |
pass | |
def timeout_handler(signum, frame): | |
raise TimeoutException("Request took too long!") | |
# Register the timeout signal handler | |
signal.signal(signal.SIGALRM, timeout_handler) | |
# Edit this part - start | |
template_folder = 'public_html/example' | |
template_file = 'index.html' | |
# Edit this part - end | |
app = Flask(__name__, | |
template_folder=template_folder, | |
static_folder=template_folder + '/static') | |
@app.route('/', methods=['GET', 'POST']) | |
def flaskFormProccessing(): | |
if __name__ == '__main__' and request.method == 'GET': | |
try: | |
return render_template(template_file) | |
except Exception as e: | |
print(str(e)) | |
# Edit this part - start | |
# Process the form nomally with Flask, for example firstName = request.form.get('first-name') and return jsonify({'key1': value2, 'key2': value2}) | |
pass | |
# Edit this part - end | |
# This is the only function that gets loaded initially so everything goes through here first | |
def application(environ, start_response): | |
# Before anything else, get the app restarted automatically to support any code changes | |
restart_file = os.path.join(os.path.dirname(__file__), 'tmp/restart.txt') | |
if os.path.exists(restart_file): | |
current_time = datetime.now().timestamp() | |
os.utime(restart_file, (current_time, current_time)) | |
# Set a realistic timeout instead of relying on the server's timeout | |
if signal_supported: | |
signal.alarm(30) | |
try: | |
# Avoid waiting indefinitely (or until a timeout) if a form was submitted without fields | |
content_length = int(environ.get('CONTENT_LENGTH', 0)) | |
if content_length == 0: | |
# Just an example, as it depends on what your form expects - the example assumes the form uses Fetch API or Ajax | |
start_response('200 OK', [('Content-Type', 'application/json')]) | |
return [json.dumps({'output': 'No form values passed', 'success': False}).encode()] | |
# Instead of checking form fields with manual methods, just send to Flask | |
with app.test_request_context(base_url=environ.get('wsgi.url_scheme', 'http') + '://' + environ.get('HTTP_HOST', ''), environ_overrides=environ): | |
# Let Flask handle the request | |
response = app.full_dispatch_request() | |
# Convert Flask's response to WSGI response | |
start_response( | |
response.status, | |
[(k, v) for k, v in response.headers] | |
) | |
return [response.get_data()] | |
except TimeoutException: | |
# Just an example, as it depends on what your form expects - the example assumes the form uses Fetch API or Ajax | |
start_response('504 Gateway Timeout', [('Content-Type', 'application/json')]) | |
return [json.dumps({'output': 'Request timed out', 'success': False}).encode()] | |
except Exception as e: | |
# Just an example, as it depends on what your form expects - the example assumes the form uses Fetch API or Ajax | |
start_response('500 Internal Server Error', [('Content-Type', 'application/json')]) | |
return [json.dumps({'output': str(e), 'success': False}).encode()] | |
finally: | |
# The timer finished serving its purpose | |
if signal_supported: | |
signal.alarm(0) # Disable the alarm | |
if __name__ == '__main__': | |
# Only use debug mode when running locally | |
is_production = os.environ.get('PRODUCTION', 'false').lower() == 'true' | |
if is_production: | |
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8080))) | |
else: | |
app.run(debug=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment