Modifying launch of API to use 'sanic' executable. This was done because startup is much faster.

This commit is contained in:
Roland 2024-05-01 18:42:15 -06:00
parent 9ee73af61d
commit 41f3969330
No known key found for this signature in database
GPG key ID: 9D6DBD3ACF11AB93
4 changed files with 16 additions and 63 deletions

View file

@ -17,5 +17,4 @@ COPY main.py /opt/wrolpi/
COPY wrolpi /opt/wrolpi/wrolpi
COPY modules /opt/wrolpi/modules
ENTRYPOINT [ "python3", "-OO", "/opt/wrolpi/main.py"]
CMD ["-vv", "api", "--host", "0.0.0.0"]
CMD ["sanic", "main:api_app", "--host", "0.0.0.0", "--port", "8081"]

View file

@ -5,7 +5,7 @@ PartOf=wrolpi.target
[Service]
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/wrolpi/venv/bin/python3 -OO /opt/wrolpi/main.py -v api
ExecStart=/opt/wrolpi/venv/bin/sanic main:api_app --host 0.0.0.0 --port 8081
Group=wrolpi
User=wrolpi
WorkingDirectory=/opt/wrolpi/

25
main.py
View file

@ -8,7 +8,6 @@ from sanic import Sanic
from sanic.signals import Event
from wrolpi import flags, BEFORE_STARTUP_FUNCTIONS, admin
from wrolpi import root_api
from wrolpi import tags
from wrolpi.api_utils import api_app
from wrolpi.common import logger, check_media_directory, set_log_level, limit_concurrent, \
@ -52,12 +51,13 @@ INTERACTIVE_BANNER = '''
This is the interactive WROLPi shell. Use this to interact with the WROLPi API library.
Example (get the duration of every video file):
from modules.videos.models import Video
from modules.videos.common import get_video_duration
videos = session.query(Video).filter(Video.video_path != None).all()
videos = list(videos)
for video in videos:
get_video_duration(video.video_path.path)
from modules.videos.models import Video
from modules.videos.common import get_video_duration
videos = session.query(Video).all()
videos = list(videos)
for video in videos:
get_video_duration(video.file_group.primary_path)
Check local variables:
locals().keys()
@ -86,10 +86,6 @@ def main():
sub_commands = parser.add_subparsers(title='sub-commands', dest='sub_commands')
# Add the API parser, this will allow the user to specify host/port etc.
api_parser = sub_commands.add_parser('api')
root_api.init_parser(api_parser)
# DB Parser for running Alembic migrations
db_parser = sub_commands.add_parser('db')
db_parser.add_argument('command', help='Supported commands: upgrade, downgrade')
@ -136,9 +132,7 @@ def main():
if args.sub_commands == 'db':
return db_main(args)
# Run the API.
if args.sub_commands == 'api':
return root_api.main(args)
return 1
@api_app.main_process_start
@ -151,6 +145,9 @@ async def startup(app: Sanic):
@warning: This is NOT run after auto-reload! You must stop and start Sanic.
"""
logger.debug('startup')
check_media_directory()
# Initialize multiprocessing shared contexts before forking Sanic processes.
attach_shared_contexts(app)
logger.debug('startup done')

View file

@ -4,7 +4,7 @@ import re
from http import HTTPStatus
import vininfo.exceptions
from sanic import response, Blueprint, __version__ as sanic_version
from sanic import response, Blueprint
from sanic.request import Request
from sanic_ext import validate
from sanic_ext.extensions.openapi import openapi
@ -26,13 +26,12 @@ from wrolpi.common import logger, get_wrolpi_config, wrol_mode_enabled, get_medi
set_global_log_level, get_relative_to_media_directory
from wrolpi.dates import now
from wrolpi.downloader import download_manager
from wrolpi.errors import WROLModeEnabled, APIError, HotspotError, InvalidDownload, \
from wrolpi.errors import WROLModeEnabled, HotspotError, InvalidDownload, \
HotspotPasswordTooShort, NativeOnly, InvalidConfig
from wrolpi.events import get_events, Events
from wrolpi.files import files_bp
from wrolpi.files.lib import get_file_statistics, search_file_suggestion_count
from wrolpi.vars import API_HOST, API_PORT, DOCKERIZED, API_DEBUG, API_ACCESS_LOG, API_WORKERS, API_AUTO_RELOAD, \
truthy_arg, IS_RPI, IS_RPI4, IS_RPI5
from wrolpi.vars import DOCKERIZED, IS_RPI, IS_RPI4, IS_RPI5
from wrolpi.version import __version__
logger = logger.getChild(__name__)
@ -51,48 +50,6 @@ api_app.blueprint(otp_bp)
api_app.blueprint(videos_bp)
api_app.blueprint(zim_bp)
def run_webserver(
host: str = API_HOST,
port: int = API_PORT,
workers: int = API_WORKERS,
api_debug: bool = API_DEBUG,
access_log: bool = API_ACCESS_LOG,
):
# Attach all blueprints after they have been defined.
kwargs = dict(
host=host,
port=port,
workers=workers,
debug=api_debug,
access_log=access_log,
auto_reload=DOCKERIZED,
)
logger.warning(f'Running Sanic {sanic_version} with kwargs {kwargs}')
return api_app.run(**kwargs)
def init_parser(parser):
# Called by WROLPI's main() function
parser.add_argument('-H', '--host', default=API_HOST, help='What network interface to connect webserver')
parser.add_argument('-p', '--port', default=API_PORT, type=int, help='What port to connect webserver')
parser.add_argument('-w', '--workers', default=API_WORKERS, type=int, help='How many web workers to run')
parser.add_argument('--access-log', default=API_ACCESS_LOG, type=truthy_arg, help='Enable Sanic access log')
parser.add_argument('--api-debug', default=API_DEBUG, type=truthy_arg, help='Enable Sanic debug log')
parser.add_argument('--api-auto-reload', default=API_AUTO_RELOAD, type=truthy_arg, help='Enable Sanic auto reload')
def main(args):
return run_webserver(
host=args.host,
port=args.port,
workers=args.workers,
api_debug=args.api_debug,
access_log=args.access_log,
)
index_html = '''
<html>
<body>