flaresolverr / src /flaresolverr.py
sanjay7178's picture
chore: Update test requirements and package information
7387da9
raw
history blame
4.02 kB
import json
import logging
import os
import sys
import certifi
from bottle import run, response, Bottle, request, ServerAdapter
from bottle_plugins.error_plugin import error_plugin
from bottle_plugins.logger_plugin import logger_plugin
from bottle_plugins import prometheus_plugin
from dtos import V1RequestBase
import flaresolverr_service
import utils
class JSONErrorBottle(Bottle):
"""
Handle 404 errors
"""
def default_error_handler(self, res):
response.content_type = 'application/json'
return json.dumps(dict(error=res.body, status_code=res.status_code))
app = JSONErrorBottle()
@app.route('/')
def index():
"""
Show welcome message
"""
res = flaresolverr_service.index_endpoint()
return utils.object_to_dict(res)
@app.route('/health')
def health():
"""
Healthcheck endpoint.
This endpoint is special because it doesn't print traces
"""
res = flaresolverr_service.health_endpoint()
return utils.object_to_dict(res)
@app.post('/v1')
def controller_v1():
"""
Controller v1
"""
req = V1RequestBase(request.json)
res = flaresolverr_service.controller_v1_endpoint(req)
if res.__error_500__:
response.status = 500
return utils.object_to_dict(res)
if __name__ == "__main__":
# check python version
if sys.version_info < (3, 9):
raise Exception("The Python version is less than 3.9, a version equal to or higher is required.")
# fix for HEADLESS=false in Windows binary
# https://stackoverflow.com/a/27694505
if os.name == 'nt':
import multiprocessing
multiprocessing.freeze_support()
# fix ssl certificates for compiled binaries
# https://github.com/pyinstaller/pyinstaller/issues/7229
# https://stackoverflow.com/questions/55736855/how-to-change-the-cafile-argument-in-the-ssl-module-in-python3
os.environ["REQUESTS_CA_BUNDLE"] = certifi.where()
os.environ["SSL_CERT_FILE"] = certifi.where()
# validate configuration
log_level = os.environ.get('LOG_LEVEL', 'info').upper()
log_html = utils.get_config_log_html()
headless = utils.get_config_headless()
server_host = os.environ.get('HOST', '0.0.0.0')
server_port = int(os.environ.get('PORT', 8191))
# configure logger
logger_format = '%(asctime)s %(levelname)-8s %(message)s'
if log_level == 'DEBUG':
logger_format = '%(asctime)s %(levelname)-8s ReqId %(thread)s %(message)s'
logging.basicConfig(
format=logger_format,
level=log_level,
datefmt='%Y-%m-%d %H:%M:%S',
handlers=[
logging.StreamHandler(sys.stdout)
]
)
# disable warning traces from urllib3
logging.getLogger('urllib3').setLevel(logging.ERROR)
logging.getLogger('selenium.webdriver.remote.remote_connection').setLevel(logging.WARNING)
logging.getLogger('undetected_chromedriver').setLevel(logging.WARNING)
logging.info(f'FlareSolverr {utils.get_flaresolverr_version()}')
logging.debug('Debug log enabled')
# Get current OS for global variable
utils.get_current_platform()
# test browser installation
flaresolverr_service.test_browser_installation()
# start bootle plugins
# plugin order is important
app.install(logger_plugin)
app.install(error_plugin)
prometheus_plugin.setup()
app.install(prometheus_plugin.prometheus_plugin)
# start webserver
# default server 'wsgiref' does not support concurrent requests
# https://github.com/FlareSolverr/FlareSolverr/issues/680
# https://github.com/Pylons/waitress/issues/31
class WaitressServerPoll(ServerAdapter):
def run(self, handler):
from waitress import serve
serve(handler, host=self.host, port=self.port, asyncore_use_poll=True)
run(app, host=server_host, port=server_port, quiet=True, server=WaitressServerPoll)