Move cli interface code in package

This commit is contained in:
Patrick Jentsch 2023-05-11 16:33:21 +02:00
parent 8c935820e8
commit 336bbc39e4
11 changed files with 121 additions and 83 deletions

View File

@ -60,6 +60,9 @@ def create_app(config: Config = Config) -> Flask:
from .errors import init_app as init_error_handlers from .errors import init_app as init_error_handlers
init_error_handlers(app) init_error_handlers(app)
from .cli import init_app as init_cli
init_cli(app)
from .admin import bp as admin_blueprint from .admin import bp as admin_blueprint
default_breadcrumb_root(admin_blueprint, '.admin') default_breadcrumb_root(admin_blueprint, '.admin')
app.register_blueprint(admin_blueprint, url_prefix='/admin') app.register_blueprint(admin_blueprint, url_prefix='/admin')
@ -69,7 +72,7 @@ def create_app(config: Config = Config) -> Flask:
from .auth import bp as auth_blueprint from .auth import bp as auth_blueprint
default_breadcrumb_root(auth_blueprint, '.') default_breadcrumb_root(auth_blueprint, '.')
app.register_blueprint(auth_blueprint, url_prefix='/') app.register_blueprint(auth_blueprint)
from .contributions import bp as contributions_blueprint from .contributions import bp as contributions_blueprint
default_breadcrumb_root(contributions_blueprint, '.contributions') default_breadcrumb_root(contributions_blueprint, '.contributions')
@ -85,7 +88,7 @@ def create_app(config: Config = Config) -> Flask:
from .main import bp as main_blueprint from .main import bp as main_blueprint
default_breadcrumb_root(main_blueprint, '.') default_breadcrumb_root(main_blueprint, '.')
app.register_blueprint(main_blueprint, url_prefix='/') app.register_blueprint(main_blueprint)
from .services import bp as services_blueprint from .services import bp as services_blueprint
default_breadcrumb_root(services_blueprint, '.services') default_breadcrumb_root(services_blueprint, '.services')

View File

@ -1,77 +0,0 @@
from flask import current_app
from flask_migrate import upgrade
import click
import os
from app.models import (
CorpusFollowerRole,
Role,
SpaCyNLPPipelineModel,
TesseractOCRPipelineModel,
User
)
def _make_default_dirs():
base_dir = current_app.config['NOPAQUE_DATA_DIR']
default_directories = [
os.path.join(base_dir, 'tmp'),
os.path.join(base_dir, 'users')
]
for directory in default_directories:
if os.path.exists(directory):
if not os.path.isdir(directory):
raise NotADirectoryError(f'{directory} is not a directory')
else:
os.mkdir(directory)
def register(app):
@app.cli.command()
def deploy():
''' Run deployment tasks. '''
# Make default directories
print('Make default directories')
_make_default_dirs()
# migrate database to latest revision
print('Migrate database to latest revision')
upgrade()
# Insert/Update default database values
print('Insert/Update default Roles')
Role.insert_defaults()
print('Insert/Update default Users')
User.insert_defaults()
print('Insert/Update default CorpusFollowerRoles')
CorpusFollowerRole.insert_defaults()
print('Insert/Update default SpaCyNLPPipelineModels')
SpaCyNLPPipelineModel.insert_defaults()
print('Insert/Update default TesseractOCRPipelineModels')
TesseractOCRPipelineModel.insert_defaults()
@app.cli.group()
def converter():
''' Converter commands. '''
pass
@converter.command()
@click.argument('json_db')
@click.argument('data_dir')
def sandpaper(json_db, data_dir):
''' Sandpaper converter '''
from app.converters.sandpaper import convert
convert(json_db, data_dir)
@app.cli.group()
def test():
''' Test commands. '''
pass
@test.command('run')
def run_test():
''' Run unit tests. '''
from unittest import TestLoader, TextTestRunner
from unittest.suite import TestSuite
tests: TestSuite = TestLoader().discover('tests')
TextTestRunner(verbosity=2).run(tests)

10
app/cli/__init__.py Normal file
View File

@ -0,0 +1,10 @@
from .converter import init_app as converter_init_app
from .corpus import init_app as corpus_init_app
from .main import init_app as main_init_app
def init_app(app):
converter_init_app(app)
corpus_init_app(app)
main_init_app(app)

21
app/cli/converter.py Normal file
View File

@ -0,0 +1,21 @@
import click
def init_app(app):
@app.cli.group('converter')
def converter():
''' Converter commands. '''
pass
@converter.group('sandpaper')
def sandpaper_converter():
''' Sandpaper converter commands. '''
pass
@sandpaper_converter.command('run')
@click.argument('json_db')
@click.argument('data_dir')
def run_sandpaper_converter(json_db, data_dir):
''' Run the sandpaper converter. '''
from app.converters.sandpaper import convert
convert(json_db, data_dir)

23
app/cli/corpus.py Normal file
View File

@ -0,0 +1,23 @@
from app.models import Corpus, CorpusStatus
def init_app(app):
@app.cli.group('corpus')
def corpus():
''' Corpus commands. '''
pass
@corpus.command('dismantle')
def dismantle():
''' Dismantle built corpora. '''
status = [
CorpusStatus.QUEUED,
CorpusStatus.BUILDING,
CorpusStatus.BUILT,
CorpusStatus.STARTING_ANALYSIS_SESSION,
CorpusStatus.RUNNING_ANALYSIS_SESSION,
CorpusStatus.CANCELING_ANALYSIS_SESSION
]
for corpus in [x for x in Corpus.query.all() if x.status in status]:
corpus.status = CorpusStatus.SUBMITTED
corpus.num_analysis_sessions = 0

45
app/cli/main.py Normal file
View File

@ -0,0 +1,45 @@
from flask import current_app
from flask_migrate import upgrade
import os
from app.models import (
CorpusFollowerRole,
Role,
SpaCyNLPPipelineModel,
TesseractOCRPipelineModel,
User
)
def init_app(app):
@app.cli.command('deploy')
def deploy():
''' Run deployment tasks. '''
# Make default directories
print('Make default directories')
base_dir = current_app.config['NOPAQUE_DATA_DIR']
default_dirs = [
os.path.join(base_dir, 'tmp'),
os.path.join(base_dir, 'users')
]
for dir in default_dirs:
if os.path.exists(dir):
if not os.path.isdir(dir):
raise NotADirectoryError(f'{dir} is not a directory')
else:
os.mkdir(dir)
# migrate database to latest revision
print('Migrate database to latest revision')
upgrade()
# Insert/Update default database values
print('Insert/Update default Roles')
Role.insert_defaults()
print('Insert/Update default Users')
User.insert_defaults()
print('Insert/Update default CorpusFollowerRoles')
CorpusFollowerRole.insert_defaults()
print('Insert/Update default SpaCyNLPPipelineModels')
SpaCyNLPPipelineModel.insert_defaults()
print('Insert/Update default TesseractOCRPipelineModels')
TesseractOCRPipelineModel.insert_defaults()

View File

@ -1,5 +1,5 @@
from flask import Blueprint from flask import Blueprint
bp = Blueprint('main', __name__) bp = Blueprint('main', __name__, cli_group=None)
from . import routes from . import routes

View File

@ -7,7 +7,7 @@ from sqlalchemy import or_
from . import bp from . import bp
@bp.route('', methods=['GET', 'POST']) @bp.route('/', methods=['GET', 'POST'])
@register_breadcrumb(bp, '.', '<i class="material-icons">home</i>') @register_breadcrumb(bp, '.', '<i class="material-icons">home</i>')
def index(): def index():
form = LoginForm() form = LoginForm()

5
app/tests/__init__.py Normal file
View File

@ -0,0 +1,5 @@
from flask import Blueprint
bp = Blueprint('tests', __name__)
from . import cli

9
app/tests/cli.py Normal file
View File

@ -0,0 +1,9 @@
from unittest import TestLoader, TextTestRunner
from unittest.suite import TestSuite
from . import bp
@bp.cli.command('run')
def run_test():
''' Run unit tests. '''
tests: TestSuite = TestLoader().discover('tests')
TextTestRunner(verbosity=2).run(tests)

View File

@ -3,7 +3,7 @@
import eventlet import eventlet
eventlet.monkey_patch() eventlet.monkey_patch()
from app import cli, create_app, db, scheduler, socketio # noqa from app import create_app, db, scheduler, socketio # noqa
from app.models import ( from app.models import (
Avatar, Avatar,
Corpus, Corpus,
@ -23,7 +23,6 @@ from typing import Any, Dict # noqa
app: Flask = create_app() app: Flask = create_app()
cli.register(app)
@app.shell_context_processor @app.shell_context_processor