I am trying to write a program that handles HTTP requests and takes a screenshot of the links in the query parameters. I want to make it so that the browser stays open and requests create tabs in order to save RAM. The problem is that the first request is handled as it should be: the program returns a screenshot. But the second request fails. "RuntimeError: Event loop is closed".
#main.py
from flask import Flask, Response, request
from schedule_gen import capture_screenshot
app = Flask(__name__)
@app.route('/schedule', methods=['GET'])
async def schedule():
# Processing query parameters.
url = request.args.get('url')
can_cache = request.args.get('canCache', False)
if url is None:
return "No url"
screenshot = await capture_screenshot(url)
return Response(screenshot, mimetype='image/png')
if __name__ == '__main__':
app.run(debug=True, port=8800, host='0.0.0.0')
#schedule_gen
from pyppeteer import launch
browser = None
async def get_browser():
global browser
if browser is None:
browser = await launch(
options={'args': ['--no-sandbox']},
handleSIGINT=False,
handleSIGTERM=False,
handleSIGHUP=False
)
return browser
async def capture_screenshot(url):
b = await get_browser()
page = await b.newPage()
# Set the viewport height to match the entire page
await page.setViewport({'width': 1920, 'height': 0})
await page.goto(url)
screenshot = await page.screenshot({'fullPage': True})
await page.close()
return screenshot
I tried all sorts of options, but none of them worked.
You are mixing Flask
synchronous request handling with asynchronous functions but Flask
dont allow that, you can use Quart
to solve this. First install it pip install quart
then in main.py
modify it like this:
from quart import Quart, Response, request
from schedule_gen import capture_screenshot
app = Quart(__name__)
@app.route('/schedule', methods=['GET'])
async def schedule():
# Processing query parameters.
url = request.args.get('url')
can_cache = request.args.get('canCache', False)
if url is None:
return "No url"
screenshot = await capture_screenshot(url)
return Response(screenshot, mimetype='image/png')
if __name__ == '__main__':
app.run(debug=True, port=8800, host='0.0.0.0')