From 336bbc39e43d787686a5e114d2cb75e5a7b1efd5 Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Thu, 11 May 2023 16:33:21 +0200
Subject: [PATCH] Move cli interface code in package
---
app/__init__.py | 7 ++--
app/cli.py | 77 -------------------------------------------
app/cli/__init__.py | 10 ++++++
app/cli/converter.py | 21 ++++++++++++
app/cli/corpus.py | 23 +++++++++++++
app/cli/main.py | 45 +++++++++++++++++++++++++
app/main/__init__.py | 2 +-
app/main/routes.py | 2 +-
app/tests/__init__.py | 5 +++
app/tests/cli.py | 9 +++++
nopaque.py | 3 +-
11 files changed, 121 insertions(+), 83 deletions(-)
delete mode 100644 app/cli.py
create mode 100644 app/cli/__init__.py
create mode 100644 app/cli/converter.py
create mode 100644 app/cli/corpus.py
create mode 100644 app/cli/main.py
create mode 100644 app/tests/__init__.py
create mode 100644 app/tests/cli.py
diff --git a/app/__init__.py b/app/__init__.py
index de8afb15..3afa99af 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -60,6 +60,9 @@ def create_app(config: Config = Config) -> Flask:
from .errors import init_app as init_error_handlers
init_error_handlers(app)
+ from .cli import init_app as init_cli
+ init_cli(app)
+
from .admin import bp as admin_blueprint
default_breadcrumb_root(admin_blueprint, '.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
default_breadcrumb_root(auth_blueprint, '.')
- app.register_blueprint(auth_blueprint, url_prefix='/')
+ app.register_blueprint(auth_blueprint)
from .contributions import bp as contributions_blueprint
default_breadcrumb_root(contributions_blueprint, '.contributions')
@@ -85,7 +88,7 @@ def create_app(config: Config = Config) -> Flask:
from .main import bp as 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
default_breadcrumb_root(services_blueprint, '.services')
diff --git a/app/cli.py b/app/cli.py
deleted file mode 100644
index e59a080d..00000000
--- a/app/cli.py
+++ /dev/null
@@ -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)
diff --git a/app/cli/__init__.py b/app/cli/__init__.py
new file mode 100644
index 00000000..1803deea
--- /dev/null
+++ b/app/cli/__init__.py
@@ -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)
diff --git a/app/cli/converter.py b/app/cli/converter.py
new file mode 100644
index 00000000..4d07bc30
--- /dev/null
+++ b/app/cli/converter.py
@@ -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)
diff --git a/app/cli/corpus.py b/app/cli/corpus.py
new file mode 100644
index 00000000..e79269f0
--- /dev/null
+++ b/app/cli/corpus.py
@@ -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
diff --git a/app/cli/main.py b/app/cli/main.py
new file mode 100644
index 00000000..2022d609
--- /dev/null
+++ b/app/cli/main.py
@@ -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()
diff --git a/app/main/__init__.py b/app/main/__init__.py
index 65630224..f32fed5f 100644
--- a/app/main/__init__.py
+++ b/app/main/__init__.py
@@ -1,5 +1,5 @@
from flask import Blueprint
-bp = Blueprint('main', __name__)
+bp = Blueprint('main', __name__, cli_group=None)
from . import routes
diff --git a/app/main/routes.py b/app/main/routes.py
index 708262db..56c37116 100644
--- a/app/main/routes.py
+++ b/app/main/routes.py
@@ -7,7 +7,7 @@ from sqlalchemy import or_
from . import bp
-@bp.route('', methods=['GET', 'POST'])
+@bp.route('/', methods=['GET', 'POST'])
@register_breadcrumb(bp, '.', 'home')
def index():
form = LoginForm()
diff --git a/app/tests/__init__.py b/app/tests/__init__.py
new file mode 100644
index 00000000..4665c05d
--- /dev/null
+++ b/app/tests/__init__.py
@@ -0,0 +1,5 @@
+from flask import Blueprint
+
+
+bp = Blueprint('tests', __name__)
+from . import cli
diff --git a/app/tests/cli.py b/app/tests/cli.py
new file mode 100644
index 00000000..a620bf0b
--- /dev/null
+++ b/app/tests/cli.py
@@ -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)
diff --git a/nopaque.py b/nopaque.py
index b369556a..bd9a9165 100644
--- a/nopaque.py
+++ b/nopaque.py
@@ -3,7 +3,7 @@
import eventlet
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 (
Avatar,
Corpus,
@@ -23,7 +23,6 @@ from typing import Any, Dict # noqa
app: Flask = create_app()
-cli.register(app)
@app.shell_context_processor