From e257e83f313a2976347b0a30f58e66b7bcbc1235 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 15 Apr 2019 14:43:57 +0200 Subject: run flask --- check/app/models/sql_factory.py | 15 ++++++++------ check/app/server/api.py | 8 ++++++-- check/app/server/create.py | 7 +++---- check/app/utils/click_utils.py | 43 +++++++++++++++++++++++++++++++++++++++++ check/cli_flask.py | 17 ++++++++++++++++ check/cli_imagehash.py | 34 ++++++++++++++++++++++++++++++++ check/commands/cli_flask.py | 17 ---------------- check/commands/cli_imagehash.py | 34 -------------------------------- 8 files changed, 112 insertions(+), 63 deletions(-) create mode 100644 check/app/utils/click_utils.py create mode 100644 check/cli_flask.py create mode 100644 check/cli_imagehash.py delete mode 100644 check/commands/cli_flask.py delete mode 100644 check/commands/cli_imagehash.py diff --git a/check/app/models/sql_factory.py b/check/app/models/sql_factory.py index 3ed3af0..d4a371e 100644 --- a/check/app/models/sql_factory.py +++ b/check/app/models/sql_factory.py @@ -3,7 +3,7 @@ import glob import time import pandas as pd -from sqlalchemy import create_engine, Table, Column, String, BigInteger +from sqlalchemy import create_engine, Table, Column, String, Integer, BigInteger from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base @@ -22,11 +22,12 @@ Session = sessionmaker(bind=engine) Base = declarative_base() -class PHashTable(Base): - __tablename__ = 'phashes' +class FileTable(Base): + """Table for storing various hashes of images""" + __tablename__ = 'files' id = Column(Integer, primary_key=True) sha256 = Column(String(36, convert_unicode=True), nullable=False) - phash = Column(BigInteger(blank=True), nullable=False) + phash = Column(BigInteger, nullable=False) ext = Column(String(3, convert_unicode=True), nullable=False) def toJSON(self): return { @@ -37,13 +38,15 @@ class PHashTable(Base): } def search_by_phash(phash, threshold=6): + """Search files for a particular phash""" connection = engine.connect() - cmd = 'SELECT phashes.*, BIT_COUNT(phash ^ :phash) as hamming_distance FROM images_image HAVING hamming_distance < :threshold ORDER BY hamming_distance ASC LIMIT 1' + cmd = 'SELECT files.*, BIT_COUNT(phash ^ :phash) as hamming_distance FROM images_image HAVING hamming_distance < :threshold ORDER BY hamming_distance ASC LIMIT 1' matches = connection.execute(text(cmd), phash=phash, threshold=threshold) return matches def add_phash(sha256, phash, ext): - rec = PHashTable( + """Add a file to the table""" + rec = FileTable( sha256=sha256, phash=phash, ext=ext, ) session = Session() diff --git a/check/app/server/api.py b/check/app/server/api.py index 6b97b59..1b17a1e 100644 --- a/check/app/server/api.py +++ b/check/app/server/api.py @@ -18,12 +18,16 @@ api = Blueprint('api', __name__) @api.route('/') def index(): - """API status noop""" + """ + API status test endpoint + """ return jsonify({ 'status': 'ok' }) @api.route('/v1/match/', methods=['POST']) def upload(): - """Search by image""" + """ + Search by uploading an image + """ start = time.time() file = request.files['query_img'] diff --git a/check/app/server/create.py b/check/app/server/create.py index 11174d2..788bfaa 100644 --- a/check/app/server/create.py +++ b/check/app/server/create.py @@ -16,10 +16,10 @@ logging.debug("starting app") from flask import Flask, Blueprint, jsonify, send_from_directory, request from flask_sqlalchemy import SQLAlchemy -from app.models.sql_factory import connection_url, load_sql_datasets +from app.models.sql_factory import connection_url from app.settings import app_cfg as cfg -# from app.server.api import api +from app.server.api import api db = SQLAlchemy() @@ -34,9 +34,8 @@ def create_app(script_info=None): app.config['CELERY_RESULT_BACKEND'] = cfg.CELERY_RESULT_BACKEND db.init_app(app) - datasets = load_sql_datasets(replace=False, base_model=db.Model) - # app.register_blueprint(api, url_prefix='/api') + app.register_blueprint(api, url_prefix='/api') @app.errorhandler(404) def page_not_found(e): diff --git a/check/app/utils/click_utils.py b/check/app/utils/click_utils.py new file mode 100644 index 0000000..fe69a6b --- /dev/null +++ b/check/app/utils/click_utils.py @@ -0,0 +1,43 @@ +""" +Custom Click parameter types +""" +import click + +from app.settings import app_cfg as cfg +from app.settings import types + + +# -------------------------------------------------------- +# Click command helpers +# -------------------------------------------------------- +def enum_to_names(enum_type): + return {x.name.lower(): x for x in enum_type} + +def show_help(enum_type): + names = enum_to_names(enum_type) + return 'Options: "{}"'.format(', '.join(list(names.keys()))) + +def get_default(opt): + return opt.name.lower() + + +# -------------------------------------------------------- +# Custom Click parameter class +# -------------------------------------------------------- + + +class ParamVar(click.ParamType): + + name = 'default_type' + + def __init__(self, param_type): + # self.name = '{}'.format(param_type.name.lower()) + # sealf. + self.ops = {x.name.lower(): x for x in param_type} + + def convert(self, value, param, ctx): + """converts (str) repr to Enum hash""" + try: + return self.ops[value.lower()] + except: + self.fail('{} is not a valid option'.format(value, param, ctx)) diff --git a/check/cli_flask.py b/check/cli_flask.py new file mode 100644 index 0000000..f2f4738 --- /dev/null +++ b/check/cli_flask.py @@ -0,0 +1,17 @@ +# -------------------------------------------------------- +# wrapper for flask CLI API +# NB: python cli_flask.py run +# -------------------------------------------------------- + +import click + +from flask.cli import FlaskGroup +from app.server.create import create_app + +cli = FlaskGroup(create_app=create_app) + +# -------------------------------------------------------- +# Entrypoint +# -------------------------------------------------------- +if __name__ == '__main__': + cli() diff --git a/check/cli_imagehash.py b/check/cli_imagehash.py new file mode 100644 index 0000000..32f8250 --- /dev/null +++ b/check/cli_imagehash.py @@ -0,0 +1,34 @@ +# -------------------------------------------------------- +# add/edit commands in commands/datasets directory +# -------------------------------------------------------- + +import click + +from app.settings import app_cfg as cfg +from app.utils import logger_utils +from app.models.click_factory import ClickSimple + +# click cli factory +cc = ClickSimple.create(cfg.DIR_COMMANDS_IMAGEHASH) + +# -------------------------------------------------------- +# CLI +# -------------------------------------------------------- +@click.group(cls=cc, chain=False) +@click.option('-v', '--verbose', 'verbosity', count=True, default=4, + show_default=True, + help='Verbosity: -v DEBUG, -vv INFO, -vvv WARN, -vvvv ERROR, -vvvvv CRITICAL') +@click.pass_context +def cli(ctx, **kwargs): + """\033[1m\033[94mMegaPixels: Dataset Image Scripts\033[0m + """ + ctx.opts = {} + # init logger + logger_utils.Logger.create(verbosity=kwargs['verbosity']) + + +# -------------------------------------------------------- +# Entrypoint +# -------------------------------------------------------- +if __name__ == '__main__': + cli() diff --git a/check/commands/cli_flask.py b/check/commands/cli_flask.py deleted file mode 100644 index f2f4738..0000000 --- a/check/commands/cli_flask.py +++ /dev/null @@ -1,17 +0,0 @@ -# -------------------------------------------------------- -# wrapper for flask CLI API -# NB: python cli_flask.py run -# -------------------------------------------------------- - -import click - -from flask.cli import FlaskGroup -from app.server.create import create_app - -cli = FlaskGroup(create_app=create_app) - -# -------------------------------------------------------- -# Entrypoint -# -------------------------------------------------------- -if __name__ == '__main__': - cli() diff --git a/check/commands/cli_imagehash.py b/check/commands/cli_imagehash.py deleted file mode 100644 index 32f8250..0000000 --- a/check/commands/cli_imagehash.py +++ /dev/null @@ -1,34 +0,0 @@ -# -------------------------------------------------------- -# add/edit commands in commands/datasets directory -# -------------------------------------------------------- - -import click - -from app.settings import app_cfg as cfg -from app.utils import logger_utils -from app.models.click_factory import ClickSimple - -# click cli factory -cc = ClickSimple.create(cfg.DIR_COMMANDS_IMAGEHASH) - -# -------------------------------------------------------- -# CLI -# -------------------------------------------------------- -@click.group(cls=cc, chain=False) -@click.option('-v', '--verbose', 'verbosity', count=True, default=4, - show_default=True, - help='Verbosity: -v DEBUG, -vv INFO, -vvv WARN, -vvvv ERROR, -vvvvv CRITICAL') -@click.pass_context -def cli(ctx, **kwargs): - """\033[1m\033[94mMegaPixels: Dataset Image Scripts\033[0m - """ - ctx.opts = {} - # init logger - logger_utils.Logger.create(verbosity=kwargs['verbosity']) - - -# -------------------------------------------------------- -# Entrypoint -# -------------------------------------------------------- -if __name__ == '__main__': - cli() -- cgit v1.2.3-70-g09d2