mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
--static option for datasette serve
You can now tell Datasette to serve static files from a specific location at a specific mountpoint. For example: datasette serve mydb.db --static extra-css:/tmp/static/css Now if you visit this URL: http://localhost:8001/extra-css/blah.css The following file will be served: /tmp/static/css/blah.css Refs #160
This commit is contained in:
parent
1ecac1a438
commit
e981ac7d4d
2 changed files with 21 additions and 2 deletions
|
|
@ -773,7 +773,8 @@ class Datasette:
|
||||||
def __init__(
|
def __init__(
|
||||||
self, files, num_threads=3, cache_headers=True, page_size=100,
|
self, files, num_threads=3, cache_headers=True, page_size=100,
|
||||||
max_returned_rows=1000, sql_time_limit_ms=1000, cors=False,
|
max_returned_rows=1000, sql_time_limit_ms=1000, cors=False,
|
||||||
inspect_data=None, metadata=None, sqlite_extensions=None, template_dir=None):
|
inspect_data=None, metadata=None, sqlite_extensions=None,
|
||||||
|
template_dir=None, static_mounts=None):
|
||||||
self.files = files
|
self.files = files
|
||||||
self.num_threads = num_threads
|
self.num_threads = num_threads
|
||||||
self.executor = futures.ThreadPoolExecutor(
|
self.executor = futures.ThreadPoolExecutor(
|
||||||
|
|
@ -789,6 +790,7 @@ class Datasette:
|
||||||
self.sqlite_functions = []
|
self.sqlite_functions = []
|
||||||
self.sqlite_extensions = sqlite_extensions or []
|
self.sqlite_extensions = sqlite_extensions or []
|
||||||
self.template_dir = template_dir
|
self.template_dir = template_dir
|
||||||
|
self.static_mounts = static_mounts or []
|
||||||
|
|
||||||
def asset_urls(self, key):
|
def asset_urls(self, key):
|
||||||
for url_or_dict in (self.metadata.get(key) or []):
|
for url_or_dict in (self.metadata.get(key) or []):
|
||||||
|
|
@ -918,6 +920,8 @@ class Datasette:
|
||||||
# TODO: /favicon.ico and /-/static/ deserve far-future cache expires
|
# TODO: /favicon.ico and /-/static/ deserve far-future cache expires
|
||||||
app.add_route(favicon, '/favicon.ico')
|
app.add_route(favicon, '/favicon.ico')
|
||||||
app.static('/-/static/', str(app_root / 'datasette' / 'static'))
|
app.static('/-/static/', str(app_root / 'datasette' / 'static'))
|
||||||
|
for path, dirname in self.static_mounts:
|
||||||
|
app.static(path, dirname)
|
||||||
app.add_route(
|
app.add_route(
|
||||||
DatabaseView.as_view(self),
|
DatabaseView.as_view(self),
|
||||||
'/<db_name:[^/\.]+?><as_json:(.jsono?)?$>'
|
'/<db_name:[^/\.]+?><as_json:(.jsono?)?$>'
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import click
|
import click
|
||||||
from click_default_group import DefaultGroup
|
from click_default_group import DefaultGroup
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from subprocess import call, check_output
|
from subprocess import call, check_output
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -140,6 +141,18 @@ def package(files, tag, metadata, extra_options, branch, **extra_metadata):
|
||||||
call(args)
|
call(args)
|
||||||
|
|
||||||
|
|
||||||
|
class StaticMount(click.ParamType):
|
||||||
|
name = 'static mount'
|
||||||
|
|
||||||
|
def convert(self, value, param, ctx):
|
||||||
|
if ':' not in value:
|
||||||
|
self.fail('"%s" should be of format mountpoint:directory' % value, param, ctx)
|
||||||
|
path, dirpath = value.split(':')
|
||||||
|
if not os.path.exists(dirpath) or not os.path.isdir(dirpath):
|
||||||
|
self.fail('%s is not a valid directory path' % value, param, ctx)
|
||||||
|
return path, dirpath
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@click.argument('files', type=click.Path(exists=True), nargs=-1)
|
@click.argument('files', type=click.Path(exists=True), nargs=-1)
|
||||||
@click.option('-h', '--host', default='127.0.0.1', help='host for server, defaults to 127.0.0.1')
|
@click.option('-h', '--host', default='127.0.0.1', help='host for server, defaults to 127.0.0.1')
|
||||||
|
|
@ -157,7 +170,8 @@ def package(files, tag, metadata, extra_options, branch, **extra_metadata):
|
||||||
@click.option('--inspect-file', help='Path to JSON file created using "datasette build"')
|
@click.option('--inspect-file', help='Path to JSON file created using "datasette build"')
|
||||||
@click.option('-m', '--metadata', type=click.File(mode='r'), help='Path to JSON file containing license/source metadata')
|
@click.option('-m', '--metadata', type=click.File(mode='r'), help='Path to JSON file containing license/source metadata')
|
||||||
@click.option('-t', '--template-dir', type=click.Path(exists=True, file_okay=False, dir_okay=True), help='Path to directory containing custom templates')
|
@click.option('-t', '--template-dir', type=click.Path(exists=True, file_okay=False, dir_okay=True), help='Path to directory containing custom templates')
|
||||||
def serve(files, host, port, debug, reload, cors, page_size, max_returned_rows, sql_time_limit_ms, sqlite_extensions, inspect_file, metadata, template_dir):
|
@click.option('-s', '--static', type=StaticMount(), help='mountpoint:path-to-directory for serving static files', multiple=True)
|
||||||
|
def serve(files, host, port, debug, reload, cors, page_size, max_returned_rows, sql_time_limit_ms, sqlite_extensions, inspect_file, metadata, template_dir, static):
|
||||||
"""Serve up specified SQLite database files with a web UI"""
|
"""Serve up specified SQLite database files with a web UI"""
|
||||||
if reload:
|
if reload:
|
||||||
import hupper
|
import hupper
|
||||||
|
|
@ -183,6 +197,7 @@ def serve(files, host, port, debug, reload, cors, page_size, max_returned_rows,
|
||||||
metadata=metadata_data,
|
metadata=metadata_data,
|
||||||
sqlite_extensions=sqlite_extensions,
|
sqlite_extensions=sqlite_extensions,
|
||||||
template_dir=template_dir,
|
template_dir=template_dir,
|
||||||
|
static_mounts=static,
|
||||||
)
|
)
|
||||||
# Force initial hashing/table counting
|
# Force initial hashing/table counting
|
||||||
ds.inspect()
|
ds.inspect()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue