Refactoring, adding db context manager

This commit is contained in:
evilchili 2022-11-20 09:28:00 -08:00
parent 3359fe1b1a
commit a34fcc648b
6 changed files with 70 additions and 39 deletions

View File

@ -3,26 +3,19 @@ import os
import typer import typer
from dotenv import load_dotenv from dotenv import load_dotenv
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from groove import ondemand from groove import webserver
from groove.db import metadata from groove.db.manager import database_manager
app = typer.Typer() app = typer.Typer()
@app.command()
def initialize(): def initialize():
load_dotenv() load_dotenv()
debug = os.getenv('DEBUG', None)
# todo: abstract this and replace in_memory_db fixture logging.basicConfig(format='%(asctime)s - %(message)s',
engine = create_engine(f"sqlite:///{os.environ.get('DATABASE_PATH')}", future=True) level=logging.DEBUG if debug else logging.INFO)
Session = sessionmaker(bind=engine, future=True)
session = Session()
metadata.create_all(bind=engine)
session.close()
@app.command() @app.command()
@ -43,21 +36,11 @@ def server(
""" """
Start the Groove on Demand playlsit server. Start the Groove on Demand playlsit server.
""" """
load_dotenv()
ondemand.initialize()
print("Starting Groove On Demand...") print("Starting Groove On Demand...")
initialize()
debug = os.getenv('DEBUG', None) with database_manager as manager:
logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.DEBUG if debug else logging.INFO) manager.import_from_filesystem()
ondemand.server.run( webserver.start(host=host, port=port, debug=debug)
host=os.getenv('HOST', host),
port=os.getenv('PORT', port),
debug=debug,
server='paste',
quiet=True
)
if __name__ == '__main__': if __name__ == '__main__':

1
groove/db/__init__.py Normal file
View File

@ -0,0 +1 @@
from groove.db.schema import metadata, track, playlist, entry

43
groove/db/manager.py Normal file
View File

@ -0,0 +1,43 @@
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from . import metadata
class DatabaseManager:
"""
A context manager for working with sqllite database.
"""
def __init__(self):
self._engine = None
self._session = None
@property
def engine(self):
if not self._engine:
self._engine = create_engine(f"sqlite:///{os.environ.get('DATABASE_PATH')}", future=True)
return self._engine
@property
def session(self):
if not self._session:
Session = sessionmaker(bind=self.engine, future=True)
self._session = Session()
return self._session
def import_from_filesystem(self):
pass
def __enter__(self):
metadata.create_all(bind=self.engine)
return self
def __exit__(self, exc_type, exc_value, traceback):
if self.session:
self.session.close()
database_manager = DatabaseManager()

View File

@ -11,11 +11,20 @@ from groove.helper import PlaylistDatabaseHelper
server = bottle.Bottle() server = bottle.Bottle()
def initialize(): def start(host: str, port: int, debug: bool) -> None:
""" """
Configure the sqlite database. Start the Bottle app.
""" """
logging.debug(f"Configuring sqllite using {os.environ.get('DATABASE_PATH')}")
server.install(sqlite.Plugin(dbfile=os.environ.get('DATABASE_PATH'))) server.install(sqlite.Plugin(dbfile=os.environ.get('DATABASE_PATH')))
logging.debug(f"Configuring webserver with host={host}, port={port}, debug={debug}")
server.run(
host=os.getenv('HOST', host),
port=os.getenv('PORT', port),
debug=debug,
server='paste',
quiet=True
)
@server.route('/') @server.route('/')

View File

@ -7,23 +7,18 @@ import atheris
import bottle import bottle
from boddle import boddle from boddle import boddle
from groove import ondemand from groove import webserver
@pytest.fixture(autouse=True, scope='session')
def init_db():
ondemand.initialize()
def test_server(): def test_server():
with boddle(): with boddle():
ondemand.index() webserver.index()
assert bottle.response.status_code == 200 assert bottle.response.status_code == 200
def test_auth_with_valid_credentials(): def test_auth_with_valid_credentials():
with boddle(auth=(os.environ.get('USERNAME'), os.environ.get('PASSWORD'))): with boddle(auth=(os.environ.get('USERNAME'), os.environ.get('PASSWORD'))):
ondemand.build() webserver.build()
assert bottle.response.status_code == 200 assert bottle.response.status_code == 200
@ -31,7 +26,7 @@ def test_auth_random_input():
def auth(fuzzed_input): def auth(fuzzed_input):
with boddle(auth=(fuzzed_input, fuzzed_input)): with boddle(auth=(fuzzed_input, fuzzed_input)):
response = ondemand.build() response = webserver.build()
assert response.status_code == 401 assert response.status_code == 401
atheris.Setup([sys.argv[0], "-atheris_runs=100000"], auth) atheris.Setup([sys.argv[0], "-atheris_runs=100000"], auth)
@ -49,11 +44,11 @@ def test_auth_random_input():
]) ])
def test_playlist(db, slug, expected): def test_playlist(db, slug, expected):
with boddle(): with boddle():
response = ondemand.get_playlist(slug, db) response = webserver.get_playlist(slug, db)
assert response.status_code == expected assert response.status_code == expected
def test_playlist_on_empty_db(in_memory_db): def test_playlist_on_empty_db(in_memory_db):
with boddle(): with boddle():
response = ondemand.get_playlist('some-slug', in_memory_db) response = webserver.get_playlist('some-slug', in_memory_db)
assert response.status_code == 404 assert response.status_code == 404