Started work on cli, which also meant adding setup.py

I'm using click, and click recommends using a setup.py - so I've added one of
those. I also refactored code into a new datasite package. It's not quite
deploying to now properly at the moment though - I seem to have messed up the
path handling a bit.

Also snuck in a new template for the "Row" view.

Refs #40
pull/81/head
Simon Willison 2017-10-27 00:08:24 -07:00
rodzic 2a9799bae6
commit 1592fd0419
10 zmienionych plików z 94 dodań i 15 usunięć

Wyświetl plik

@ -1,7 +1,7 @@
FROM python:3
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
RUN python app.py --build
RUN pip install .
RUN datasite build
EXPOSE 8006
CMD ["python", "app.py"]
CMD ["datasite", "serve", "--port", "8006"]

Wyświetl plik

Wyświetl plik

@ -3,6 +3,8 @@ from sanic import response
from sanic.exceptions import NotFound
from sanic.views import HTTPMethodView
from sanic_jinja2 import SanicJinja2
from jinja2 import FileSystemLoader
import click
import sqlite3
from contextlib import contextmanager
from pathlib import Path
@ -14,7 +16,7 @@ import hashlib
import sys
import time
app_root = Path(__file__).parent
app_root = Path(__file__).parent.parent
BUILD_METADATA = 'build-metadata.json'
DB_GLOBS = ('*.db', '*.sqlite', '*.sqlite3')
@ -25,7 +27,12 @@ conns = {}
app = Sanic(__name__)
jinja = SanicJinja2(app)
jinja = SanicJinja2(
app,
loader=FileSystemLoader([
str(app_root / 'datasite' / 'templates')
])
)
def get_conn(name):
@ -43,10 +50,12 @@ def get_conn(name):
def ensure_build_metadata(regenerate=False):
build_metadata = app_root / BUILD_METADATA
if build_metadata.exists() and not regenerate:
json.loads(build_metadata.read_text())
return json.loads(build_metadata.read_text())
print('Building metadata... path={}'.format(build_metadata))
metadata = {}
for glob in DB_GLOBS:
for path in app_root.glob(glob):
print(' globbing, path={}'.format(path))
name = path.stem
if name in metadata:
raise Exception('Multiple files with same stem %s' % name)
@ -154,7 +163,7 @@ class BaseView(HTTPMethodView):
@app.route('/')
async def index(request, sql=None):
databases = []
for key, info in ensure_build_metadata(True).items():
for key, info in ensure_build_metadata().items():
database = {
'name': key,
'hash': info['hash'],
@ -246,7 +255,7 @@ class TableView(BaseView):
class RowView(BaseView):
template = 'table.html'
template = 'row.html'
def data(self, request, name, hash, table, pk_path):
conn = get_conn(name)
@ -409,10 +418,3 @@ def sqlite_timelimit(conn, ms):
conn.set_progress_handler(handler, 10000)
yield
conn.set_progress_handler(None, 10000)
if __name__ == '__main__':
if '--build' in sys.argv:
ensure_build_metadata(True)
else:
app.run(host="0.0.0.0", port=8006)

24
datasite/cli.py 100644
Wyświetl plik

@ -0,0 +1,24 @@
import click
from .app import app, ensure_build_metadata
@click.group()
def cli():
"""
Datasite!
"""
@cli.command()
def build():
ensure_build_metadata(True)
@cli.command()
@click.argument('files', type=click.Path(exists=True), nargs=-1)
@click.option('-h', '--host', default='0.0.0.0')
@click.option('-p', '--port', default=8001)
@click.option('--debug', is_flag=True)
def serve(files, host, port, debug):
'''Serve up specified database files with a web UI'''
click.echo('Serve! files={} on port {}'.format(files, port))
app.run(host=host, port=port, debug=debug)

Wyświetl plik

@ -0,0 +1,35 @@
{% extends "base.html" %}
{% block title %}{{ database }}: {{ table }}{% endblock %}
{% block content %}
<h1><a href="/{{ database }}-{{ database_hash }}">{{ database }}</a></h1>
<h2><a href="/{{ database }}-{{ database_hash }}/{{ table }}">{{ table }}</a></h2>
<style>
td {
white-space: pre;
vertical-align: top;
border-top: 1px solid #666;
padding: 2px 4px;
}
</style>
<table>
<tr>
{% if primary_keys and row_link %}<th scope="col">Link</th>{% endif %}
{% for column in columns %}<th scope="col">{{ column }}</th>{% endfor %}
</tr>
{% for row in rows %}
<tr>
{% if primary_keys and row_link %}
<td><a href="/{{ database }}-{{ database_hash }}/{{ table }}/{{ row_link(row) }}">{{ row_link(row) }}</a></td>
{% endif %}
{% for td in row %}
<td>{{ td }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% if took_ms %}<small>Took {{ took_ms }}</small>{% endif %}
{% endblock %}

18
setup.py 100644
Wyświetl plik

@ -0,0 +1,18 @@
from setuptools import setup, find_packages
setup(
name='datasite',
version='0.1',
packages=find_packages(),
package_data={'datasite': ['templates/*.html']},
include_package_data=True,
install_requires=[
'click==6.7',
'sanic==0.6.0',
'sanic-jinja2==0.5.5',
],
entry_points='''
[console_scripts]
datasite=datasite.cli:cli
''',
)