-
Notifications
You must be signed in to change notification settings - Fork 15
/
iiif_testserver.py
executable file
·136 lines (114 loc) · 5.3 KB
/
iiif_testserver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python
"""Crude webserver that services IIIF Image API requests.
Relies upon IIIFManipulator objects to do any manipulations
requested and is thus very slow. Supports a number of different
versions of the specification via different base URIs (prefixes).
Simeon Warner - 2014--2020
"""
from flask import Flask
import logging
import re
import configargparse
import os
import os.path
import sys
from iiif.flask_utils import Config, write_pid_file, add_handler, make_prefix, top_level_index_page, serve_static, ReverseProxied, setup_app, split_comma_argument, add_shared_configs
def get_config(base_dir=''):
"""Get config from defaults, config file and/or parse arguments.
Uses configargparse to allow argments to be set from a config file
or via command line arguments.
base_dir - set a specific base directory for file/path defaults.
"""
p = configargparse.ArgParser(description='IIIF Image Testserver',
default_config_files=[os.path.join(base_dir, 'iiif_testserver.cfg')],
formatter_class=configargparse.ArgumentDefaultsHelpFormatter)
add_shared_configs(p, base_dir)
p.add('--container-prefix', default='',
help="Container prefix seen by client to add to links generated")
p.add('--scale-factors', default='auto',
help="Set of tile scale factors or 'auto' to calculate for each image "
"such that there are tiles up to the full image")
p.add('--api-versions', default='1.0,1.1,2.0,2.1,3.0',
help="Set of API versions to support")
p.add('--manipulators', default='pil',
help="Set of manipuators to instantiate. May be dummy,netpbm,pil "
"or gen for generated image")
p.add('--auth-types', default='none',
help="Set of authentication types to support")
p.add('--pages-dir', default=os.path.join(base_dir, 'testpages'),
help="Test pages directory")
p.add('--auth', action='store_true',
help="Enable features implementing the IIIF Authentication specification")
args = p.parse_args()
if (args.debug):
args.verbose = True
elif (args.verbose):
args.quiet = False
# Split list arguments
args.scale_factors = split_comma_argument(args.scale_factors)
args.manipulators = split_comma_argument(args.manipulators)
args.api_versions = split_comma_argument(args.api_versions)
args.auth_types = split_comma_argument(args.auth_types)
# Authentication features...
if (args.auth and 'gauth' not in args.auth_types):
args.auth_types.append('gauth')
if (args.auth and 'basic' not in args.auth_types):
args.auth_types.append('basic')
if (args.auth and 'clickthrough' not in args.auth_types):
args.auth_types.append('clickthrough')
if (args.auth and 'kiosk' not in args.auth_types):
args.auth_types.append('kiosk')
if (args.auth and 'external' not in args.auth_types):
args.auth_types.append('external')
logging_level = logging.WARNING
if args.verbose:
logging_level = logging.INFO
elif args.quiet:
logging_level = logging.ERROR
logging.basicConfig(format='%(name)s: %(message)s', level=logging_level)
return(args)
def create_testserver_flask_app(cfg):
"""Create testserver Flask application with one or more IIIF handlers."""
# Create Flask app
app = Flask(__name__, static_url_path='/' + cfg.pages_dir)
Flask.secret_key = "SECRET_HERE"
app.debug = cfg.debug
# Create shared configuration dict based on options
config = Config(cfg)
config.homedir = os.path.dirname(os.path.realpath(__file__))
config.gauth_client_secret_file = os.path.join(
config.homedir, config.gauth_client_secret)
# Install request handlers
client_prefixes = dict()
for api_version in cfg.api_versions:
for klass_name in cfg.manipulators:
for auth_type in cfg.auth_types:
# auth only for >=2.1
if (auth_type != 'none' and float(api_version) < 2.1):
continue
handler_config = Config(config)
handler_config.api_version = api_version
handler_config.klass_name = klass_name
handler_config.auth_type = auth_type
prefix = make_prefix(api_version, klass_name, auth_type)
client_prefix = os.path.join(config.container_prefix, prefix)
logging.debug("prefix = %s, client_prefix = %s" % (prefix, client_prefix))
client_prefixes[client_prefix] = prefix
handler_config.prefix = prefix
handler_config.client_prefix = client_prefix
add_handler(app, handler_config)
# Index page
config.prefixes = client_prefixes
app.add_url_rule('/', 'top_level_index_page',
top_level_index_page, defaults={'config': config})
if cfg.include_osd:
# OpenSeadragon files
app.add_url_rule('/openseadragon200/<path:filename>', 'OSD pages', serve_static,
defaults={'prefix': 'openseadragon200'})
return(app)
if __name__ == '__main__':
# Command line, run server
write_pid_file()
cfg = get_config()
app = setup_app(create_testserver_flask_app(cfg), cfg)
app.run(host=cfg.app_host, port=cfg.app_port)