upgrade to oas 3

This commit is contained in:
Jan Friedli 2020-07-14 15:28:08 +02:00
parent 42f9ede4bf
commit 5d1e6b3235
No known key found for this signature in database
GPG key ID: F945FA2FCA30549D
10 changed files with 178 additions and 134 deletions

View file

@ -38,7 +38,7 @@ tests:debian:
- apt-get -qqy update - apt-get -qqy update
- apt-get -qqy install --no-install-recommends mat2 python3-flask python3-coverage python3-pip python3-setuptools - apt-get -qqy install --no-install-recommends mat2 python3-flask python3-coverage python3-pip python3-setuptools
- pip3 install wheel - pip3 install wheel
- pip3 install -r requirements.txt - pip3 install -r requirements.txt -r requirements-test.txt
- python3-coverage run --branch --include main.py,matweb/*.py -m unittest discover -s test - python3-coverage run --branch --include main.py,matweb/*.py -m unittest discover -s test
- python3-coverage report -m - python3-coverage report -m

25
main.py
View file

@ -1,5 +1,6 @@
import os import os
import jinja2 import jinja2
import yaml
from matweb import utils, rest_api, frontend from matweb import utils, rest_api, frontend
from flask import Flask, request from flask import Flask, request
@ -30,17 +31,31 @@ def create_app(test_config=None):
app.register_blueprint(rest_api.api_bp) app.register_blueprint(rest_api.api_bp)
app.json_encoder = LazyJSONEncoder app.json_encoder = LazyJSONEncoder
dirname = os.path.dirname(__file__)
with open(os.path.join(dirname, 'matweb/oas/components.yml')) as file:
components = yaml.full_load(file)
template = dict( template = dict(
schemes=['https', 'http'], servers=[
host=LazyString(lambda: request.host), {
basePath='/', 'url': LazyString(lambda: request.host_url),
'description': 'References the current running server'
}
],
info={ info={
'title': 'Mat2 Web API', 'title': 'Mat2 Web API',
'version': '1', 'version': '1',
'description': 'Mat2 Web RESTful API documentation', 'description': 'Mat2 Web RESTful API documentation',
} },
components=components
) )
Swagger(app, template=template) swagger_config = Swagger.DEFAULT_CONFIG
swagger_config['swagger_ui_bundle_js'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js'
swagger_config['swagger_ui_standalone_preset_js'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui-standalone-preset.js'
swagger_config['swagger_ui_css'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui.css'
swagger_config['openapi'] = "3.0.3"
Swagger(app, template=template, config=swagger_config)
CORS(app, resources={r"/api/*": {"origins": utils.get_allow_origin_header_value()}}) CORS(app, resources={r"/api/*": {"origins": utils.get_allow_origin_header_value()}})
return app return app

View file

@ -6,47 +6,32 @@ description: "This endpoint allows you to bulk download several files
which you uploaded beforehand. Note that the `download_list` which you uploaded beforehand. Note that the `download_list`
MUST contain more than two files. The max length is configurable MUST contain more than two files. The max length is configurable
(default is 10)." (default is 10)."
consumes: requestBody:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "The files that will be combined for one single download" description: "The files that will be combined for one single download"
required: true required: true
schema: content:
$ref: '#/definitions/BulkBody' application/json:
schema:
$ref: '#/components/schemas/BulkBody'
responses: responses:
201: 201:
description: "A new resource to download all files as one archive" description: "A new resource to download all files as one archive"
schema: content:
$ref: '#/definitions/UploadResponse' application/json:
schema:
$ref: '#/components/schemas/UploadResponse'
400: 400:
description: "Invalid input" description: "Invalid input"
schema: content:
$ref: '#/definitions/ErrorResponse' application/json:
schema:
oneOf:
- $ref: '#/components/schemas/ErrorAtLeastTwoResponse'
- $ref: '#/components/schemas/ErrorResponse'
500: 500:
description: "Unable to clean the file" description: "Unable to clean the file"
schema: content:
$ref: '#/definitions/ErrorResponse' application/json:
schema:
definitions: $ref: '#/components/schemas/ErrorResponse'
BulkBody:
type: "object"
properties:
download_list:
type: "array"
description: "An object containing the files you want to create a bulk download for"
items:
$ref: '#/definitions/BulkFile'
BulkFile:
type: "object"
properties:
file_name:
type: "string"
key:
type: "string"
secret:
type: "string"

68
matweb/oas/components.yml Normal file
View file

@ -0,0 +1,68 @@
schemas:
BulkBody:
type: "object"
properties:
download_list:
type: "array"
description: "An object containing the files you want to create a bulk download for"
items:
$ref: '#/components/schemas/BulkFile'
BulkFile:
type: "object"
properties:
file_name:
type: "string"
key:
type: "string"
secret:
type: "string"
ErrorAtLeastTwoResponse:
type: "object"
properties:
message:
type: "object"
description: "A description of the error"
properties:
download_list:
type: "array"
items:
type: "string"
example: "Min length is 2"
UploadResponse:
type: "object"
properties:
inactive_after_sec:
type: "integer"
format: "int64"
description: "Defines after how many seconds the download wont be available"
output_filename:
type: "string"
description: "The resulting filename after metadata removal"
mime:
type: "string"
description: "The mime type of the cleaned file"
key:
type: "string"
description: "A key used to guarantee file integrity"
secret:
type: "string"
description: "A secret used to guarantee file integrity"
meta:
type: "object"
description: "An object of the removed metadata where key indicates the metadata type"
items:
type: "string"
meta_after:
type: "object"
description: "An object of the remaining metadata where key indicates the metadata type"
items:
type: "string"
download_link:
type: "string"
description: "The link to download the cleaned file"
ErrorResponse:
type: "object"
properties:
message:
type: "string"
description: "A description of the error"

View file

@ -2,30 +2,39 @@
tags: tags:
- "File Download" - "File Download"
summary: 'Download a single cleaned file or zip archive containing multiple files' summary: 'Download a single cleaned file or zip archive containing multiple files'
consumes:
- "application/json"
produces:
- "*/*"
parameters: parameters:
- name: "key" - name: "key"
in: "path" in: "path"
description: "A key generated for that resource" description: "A key generated for that resource"
required: true required: true
type: "string" schema:
- name: "secret" type: "string"
in: "path" - name: "secret"
description: "A secret generated for that resource" in: "path"
required: true description: "A secret generated for that resource"
type: "string" required: true
- name: "filename" schema:
in: "path" type: "string"
description: "the filename of the cleaned file" - name: "filename"
required: true in: "path"
type: "string" description: "the filename of the cleaned file"
required: true
schema:
type: "string"
responses: responses:
200: 200:
description: "" description: "The cleaned file as attachment so a browser downloads the file directly"
content:
"*/*":
schema:
format: binary
400:
description: "Invalid input"
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
404: 404:
description: "The filename, key or secret are wrong or the link is too old and the file has been deleted" description: "The filename, key or secret are wrong or the link is too old and the file has been deleted"

View file

@ -2,16 +2,14 @@
tags: tags:
- "Supported Extensions" - "Supported Extensions"
summary: 'Returns a list of all supported file extensions' summary: 'Returns a list of all supported file extensions'
consumes:
- "application/json"
produces:
- "application/json"
responses: responses:
200: 200:
description: "A list of all supported file extensions" description: "A list of all supported file extensions"
schema: content:
type: "array" application/json:
items: schema:
type: "string" type: "array"
example: ".jpeg" items:
type: "string"
example: ".jpeg"

View file

@ -2,79 +2,43 @@
tags: tags:
- "File Upload (Metadata removal)" - "File Upload (Metadata removal)"
summary: 'Upload a single file which will be cleaned from metadata' summary: 'Upload a single file which will be cleaned from metadata'
consumes: requestBody:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "The file that will be cleaned from metadata. Note that the file must be base64 encoded" description: "The file that will be cleaned from metadata. Note that the file must be base64 encoded"
required: true required: true
schema: content:
type: "object" application/json:
properties: schema:
file_name: type: "object"
type: "string" properties:
example: 'my_example.jpg' file_name:
file: type: "string"
type: "string" example: 'my_example.jpg'
example: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==' file:
type: "string"
example: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='
responses: responses:
201: 201:
description: "An object containing all info about the cleaned file" description: "An object containing all info about the cleaned file"
schema: content:
$ref: '#/definitions/UploadResponse' application/json:
schema:
$ref: '#/components/schemas/UploadResponse'
400: 400:
description: "Invalid input" description: "Invalid input"
schema: content:
$ref: '#/definitions/ErrorResponse' application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
415: 415:
description: "Unsupported file type" description: "Unsupported file type"
schema: content:
$ref: '#/definitions/ErrorResponse' application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
500: 500:
description: "Unable to clean the file" description: "Unable to clean the file"
schema: content:
$ref: '#/definitions/ErrorResponse' application/json:
schema:
definitions: $ref: '#/components/schemas/ErrorResponse'
UploadResponse:
type: "object"
properties:
inactive_after_sec:
type: "integer"
format: "int64"
description: "Defines after how many seconds the download wont be available"
output_filename:
type: "string"
description: "The resulting filename after metadata removal"
mime:
type: "string"
description: "The mime type of the cleaned file"
key:
type: "string"
description: "A key used to guarantee file integrity"
secret:
type: "string"
description: "A secret used to guarantee file integrity"
meta:
type: "object"
description: "An object of the removed metadata where key indicates the metadata type"
items:
type: "string"
meta_after:
type: "object"
description: "An object of the remaining metadata where key indicates the metadata type"
items:
type: "string"
download_link:
type: "string"
description: "The link to download the cleaned file"
ErrorResponse:
type: "object"
properties:
message:
type: "string"
description: "A description of the error"

1
requirements-test.txt Normal file
View file

@ -0,0 +1 @@
openapi-spec-validator==0.2.8

View file

@ -8,4 +8,4 @@ Flask-Cors==3.0.8
Cerberus==1.3.2 Cerberus==1.3.2
Flask-Testing==0.8.0 Flask-Testing==0.8.0
blinker==1.4 blinker==1.4
flasgger==0.9.4 iknl-flasgger==0.9.2.post1

View file

@ -7,6 +7,7 @@ import zipfile
from six import BytesIO from six import BytesIO
from unittest.mock import patch from unittest.mock import patch
from openapi_spec_validator import validate_spec
import main import main
@ -420,6 +421,9 @@ class Mat2APITestCase(unittest.TestCase):
self.assertEqual(400, request.status_code) self.assertEqual(400, request.status_code)
self.assertEqual("Failed decoding file", error_message) self.assertEqual("Failed decoding file", error_message)
def test_valid_opena_api_spec(self):
spec = self.app.get('apispec_1.json').get_json()
validate_spec(spec)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()