diff --git a/debian/control b/debian/control index 609565cd..ef095bb5 100644 --- a/debian/control +++ b/debian/control @@ -1,17 +1,20 @@ Source: swh-sword Maintainer: Software Heritage developers Section: python Priority: optional Build-Depends: debhelper (>= 9), dh-python, python3-all, python3-aiohttp, - python3-swh.core, + python3-swh.core (>= ~0.0.14), + python3-defusedxml, + python3-jinja2, + python3-click, python3-vcversioner Standards-Version: 3.9.6 Homepage: https://forge.softwareheritage.org/diffusion// Package: python3-swh.sword Architecture: all Depends: ${misc:Depends}, ${python3:Depends} Description: Software Heritage SWORD Server diff --git a/requirements.txt b/requirements.txt index 2c0ea447..e87b8306 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,10 @@ # Add here external Python modules dependencies, one per line. Module names # should match https://pypi.python.org/pypi names. For the full spec or # dependency lines, see https://pip.readthedocs.org/en/1.1/requirements.html vcversioner aiohttp +defusedxml +jinja retrying click diff --git a/swh/sword/server.py b/swh/deposit/server.py similarity index 55% rename from swh/sword/server.py rename to swh/deposit/server.py index 6e22b5c5..4085554b 100644 --- a/swh/sword/server.py +++ b/swh/deposit/server.py @@ -1,96 +1,96 @@ # Copyright (C) 2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information import asyncio import aiohttp.web import click -import json -import multidict +import jinja2 from swh.core import config -from swh.core.api_async import (SWHRemoteAPI, decode_request) +from swh.core.api_async import SWHRemoteAPI DEFAULT_CONFIG = { 'host': ('str', '0.0.0.0'), 'port': ('int', 5012), + 'max_upload_size': ('int', 200 * 1024 * 1024) } -def encode_data(data, **kwargs): +template_loader = jinja2.FileSystemLoader( + searchpath=["swh/deposit/templates"]) +template_env = jinja2.Environment(loader=template_loader) + + +def encode_data(data, template_name=None, **kwargs): return aiohttp.web.Response( - body=json.dumps(data), - headers=multidict.MultiDict({'Content-Type': 'application/json'}), + body=data, + headers={'Content-Type': 'application/xml'}, **kwargs ) @asyncio.coroutine def index(request): - return aiohttp.web.Response(text='SWH SWORD Server') - - -@asyncio.coroutine -def hello(request): - name = request.match_info.get('name', "Anonymous") - text = "Hello, %s\n" % name - return aiohttp.web.Response(text=text) + return aiohttp.web.Response(text='SWH Deposit Server') @asyncio.coroutine -def service_document(): - pass +def service_document(request): + tpl = template_env.get_template('service_document.xml') + output = tpl.render( + noop=True, verbose=False, max_upload_size=200*1024*1024) + return encode_data(data=output) @asyncio.coroutine -def create_document(): +def create_document(request): pass @asyncio.coroutine -def update_document(): +def update_document(request): pass @asyncio.coroutine -def status_operation(): +def status_operation(request): pass @asyncio.coroutine -def delete_document(): +def delete_document(request): raise ValueError('Not implemented') def make_app(config, **kwargs): app = SWHRemoteAPI(**kwargs) - app.router.add_route('GET', '/', index) - app.router.add_route('GET', '/{name}', hello) - app.router.add_route('GET', '/v1/software/', service_document) - app.router.add_route('GET', '/v1/status/', status_operation) - app.router.add_route('POST', '/v1/software/', create_document) - app.router.add_route('PUT', '/v1/software/', update_document) - app.router.add_route('DELETE', '/v1/software/', delete_document) + app.router.add_route('GET', '/', index) + app.router.add_route('GET', '/api/1/deposit/', service_document) + app.router.add_route('GET', '/api/1/status/', status_operation) + app.router.add_route('POST', '/api/1/deposit/', create_document) + app.router.add_route('PUT', '/api/1/deposit/', update_document) + app.router.add_route('DELETE', '/api/1/deposit/', delete_document) app.update(config) return app @click.command() @click.argument('config-path', required=1) @click.option('--host', default='0.0.0.0', help="Host to run the server") @click.option('--port', default=5012, type=click.INT, help="Binding port of the server") @click.option('--debug/--nodebug', default=True, help="Indicates if the server should run in debug mode") def launch(config_path, host, port, debug): c = config.read(config_path, DEFAULT_CONFIG) port = port if port else c['port'] host = host if host else c['host'] app = make_app(c, debug=bool(debug)) aiohttp.web.run_app(app, host=host, port=port) if __name__ == '__main__': launch() diff --git a/swh/sword/templates/service_document.xml b/swh/deposit/templates/service_document.xml similarity index 58% rename from swh/sword/templates/service_document.xml rename to swh/deposit/templates/service_document.xml index 8ca983c2..80848d88 100644 --- a/swh/sword/templates/service_document.xml +++ b/swh/deposit/templates/service_document.xml @@ -1,29 +1,26 @@ 2.0 - ${max_upload_size} - - + {{ max_upload_size }} + {{ verbose }} + {{ noop }} The Software Heritage (SWH) archive - - SWH Software Collection - application/zip + + SWH Software Archive application/gzip - application/zip application/gzip Collection Policy - Software Heritage's software collection - true - Treatment description + Software Heritage Archive + false http://purl.org/net/sword/package/SimpleZip - https://sword.softwareheritage.org/v1/software/ + https://sword.softwareheritage.org/v1/deposit/