From c8a125aa07f66168bee669158a5d5870feed3652 Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 18 Nov 2022 16:11:23 +0200 Subject: [PATCH 01/10] convert API spec from Swagger 2 to OpenAPI 3 using Swagger Editor (not working yet) --- annif/__init__.py | 2 +- annif/openapi/annif.yaml | 313 +++++++++++++++++++++++++++++++++++++++ annif/swagger/annif.yaml | 260 -------------------------------- 3 files changed, 314 insertions(+), 261 deletions(-) create mode 100644 annif/openapi/annif.yaml delete mode 100644 annif/swagger/annif.yaml diff --git a/annif/__init__.py b/annif/__init__.py index 6bf3bb745..320916742 100644 --- a/annif/__init__.py +++ b/annif/__init__.py @@ -16,7 +16,7 @@ def create_app(config_name=None): # 'cxapp' here is the Connexion application that has a normal Flask app # as a property (cxapp.app) - specdir = os.path.join(os.path.dirname(__file__), "swagger") + specdir = os.path.join(os.path.dirname(__file__), "openapi") cxapp = connexion.App(__name__, specification_dir=specdir) if config_name is None: config_name = os.environ.get("ANNIF_CONFIG") diff --git a/annif/openapi/annif.yaml b/annif/openapi/annif.yaml new file mode 100644 index 000000000..3917c3fbc --- /dev/null +++ b/annif/openapi/annif.yaml @@ -0,0 +1,313 @@ +openapi: 3.0.1 +info: + title: Annif REST API + version: v1 +servers: +- url: /v1 +paths: + /projects: + get: + tags: + - Project administration + summary: get a list of projects + operationId: annif.rest.list_projects + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ProjectList' + /projects/{project_id}: + get: + tags: + - Project administration + summary: show project information + operationId: annif.rest.show_project + parameters: + - name: project_id + in: path + description: project identifier + required: true + schema: + type: string + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Project' + application/problem+json: + schema: + $ref: '#/components/schemas/Project' + 404: + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Problem' + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + /projects/{project_id}/suggest: + post: + tags: + - Automatic subject indexing + summary: suggest subjects for a given text + operationId: annif.rest.suggest + parameters: + - name: project_id + in: path + description: project identifier + required: true + schema: + type: string + requestBody: + content: + application/x-www-form-urlencoded: + schema: + required: + - text + properties: + text: + type: string + description: input text + limit: + type: integer + description: maximum number of results to return + format: int32 + default: 10 + threshold: + type: number + description: minimum score threshold, below which results will not + be returned + default: 0.0 + language: + type: string + description: language of subject labels + required: true + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/SuggestionResultList' + application/problem+json: + schema: + $ref: '#/components/schemas/SuggestionResultList' + 400: + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Problem' + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + 404: + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Problem' + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + 503: + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/components/schemas/Problem' + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + /projects/{project_id}/learn: + post: + tags: + - Learning from feedback + summary: learn from manually indexed documents + operationId: annif.rest.learn + parameters: + - name: project_id + in: path + description: project identifier + required: true + schema: + type: string + requestBody: + description: documents to learn from + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/IndexedDocument' + required: true + responses: + 204: + description: successful operation + content: {} + 404: + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Problem' + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + 503: + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/components/schemas/Problem' + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + x-codegen-request-body-name: documents +components: + schemas: + ProjectBackend: + required: + - backend_id + type: object + properties: + backend_id: + type: string + example: my-backend + description: A backend of a project + Project: + required: + - backend + - language + - name + - project_id + type: object + properties: + project_id: + type: string + example: my-project + name: + type: string + example: My Project + language: + type: string + example: en + backend: + $ref: '#/components/schemas/ProjectBackend' + is_trained: + type: boolean + example: true + modification_time: + type: string + format: date-time + example: 2020-05-19T16:42:42Z + description: A project definition + ProjectList: + type: object + properties: + projects: + type: array + items: + $ref: '#/components/schemas/Project' + description: A list of projects + SuggestionResult: + required: + - label + - score + - uri + type: object + properties: + uri: + type: string + example: http://example.org/subject1 + label: + type: string + example: Archaeology + notation: + type: string + example: "42.42" + score: + type: number + example: 0.85 + description: A single candidate subject for a document + SuggestionResultList: + type: object + properties: + results: + type: array + items: + $ref: '#/components/schemas/SuggestionResult' + description: A list of analysis results + IndexedDocument: + type: object + properties: + text: + type: string + example: A quick brown fox jumped over the lazy dog. + subjects: + type: array + items: + type: object + properties: + uri: + type: string + example: http://example.org/subject1 + label: + type: string + example: Vulpes vulpes + description: A document with attached, known good subjects + Problem: + type: object + properties: + type: + type: string + description: | + An absolute URI that identifies the problem type. When dereferenced, + it SHOULD provide human-readable documentation for the problem type + (e.g., using HTML). + format: uri + example: https://zalando.github.io/problem/constraint-violation + default: about:blank + title: + type: string + description: | + A short, summary of the problem type. Written in english and readable + for engineers (usually not suited for non technical stakeholders and + not localized); example: Service Unavailable + status: + maximum: 6E+2 + exclusiveMaximum: true + minimum: 1E+2 + type: integer + description: | + The HTTP status code generated by the origin server for this occurrence + of the problem. + format: int32 + example: 503 + detail: + type: string + description: | + A human readable explanation specific to this occurrence of the + problem. + example: Connection to database timed out + instance: + type: string + description: | + An absolute URI that identifies the specific occurrence of the problem. + It may or may not yield further information if dereferenced. + format: uri + parameters: + project_id: + name: project_id + in: path + description: project identifier + required: true + schema: + type: string + example: dummy-fi + diff --git a/annif/swagger/annif.yaml b/annif/swagger/annif.yaml deleted file mode 100644 index 8187a66a2..000000000 --- a/annif/swagger/annif.yaml +++ /dev/null @@ -1,260 +0,0 @@ -swagger: '2.0' -info: - title: Annif REST API - version: v1 -basePath: /v1 -parameters: - project_id: - name: project_id - in: path - description: project identifier - required: true - type: string - x-example: dummy-fi -paths: - /projects: - get: - summary: get a list of projects - operationId: annif.rest.list_projects - produces: - - application/json - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/ProjectList' - tags: - - Project administration - '/projects/{project_id}': - get: - summary: show project information - operationId: annif.rest.show_project - produces: - - application/json - - application/problem+json - parameters: - - $ref: '#/parameters/project_id' - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/Project' - '404': - description: Project not found - schema: - $ref: '#/definitions/Problem' - tags: - - Project administration - '/projects/{project_id}/suggest': - post: - summary: suggest subjects for a given text - operationId: annif.rest.suggest - consumes: - - application/x-www-form-urlencoded - produces: - - application/json - - application/problem+json - parameters: - - $ref: '#/parameters/project_id' - - name: text - in: formData - description: input text - required: true - type: string - - name: limit - in: formData - description: maximum number of results to return - required: false - type: integer - default: 10 - - name: threshold - in: formData - description: 'minimum score threshold, below which results will not be returned' - required: false - type: number - default: 0 - - name: language - in: formData - description: language of subject labels - required: false - type: string - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/SuggestionResultList' - '400': - description: Bad Request - schema: - $ref: '#/definitions/Problem' - '404': - description: Project not found - schema: - $ref: '#/definitions/Problem' - '503': - description: Service Unavailable - schema: - $ref: '#/definitions/Problem' - tags: - - Automatic subject indexing - '/projects/{project_id}/learn': - post: - summary: learn from manually indexed documents - operationId: annif.rest.learn - consumes: - - application/json - produces: - - application/json - - application/problem+json - parameters: - - $ref: '#/parameters/project_id' - - name: documents - in: body - description: documents to learn from - required: true - schema: - type: array - items: - $ref: '#/definitions/IndexedDocument' - responses: - '204': - description: successful operation - '404': - description: Project not found - schema: - $ref: '#/definitions/Problem' - '503': - description: Service Unavailable - schema: - $ref: '#/definitions/Problem' - tags: - - Learning from feedback -definitions: - ProjectBackend: - description: A backend of a project - properties: - backend_id: - type: string - example: my-backend - required: - - backend_id - Project: - description: A project definition - properties: - project_id: - type: string - example: my-project - name: - type: string - example: My Project - language: - type: string - example: en - backend: - $ref: '#/definitions/ProjectBackend' - is_trained: - type: boolean - example: true - modification_time: - type: string - format: date-time - example: '2020-05-19T16:42:42.000000Z' - required: - - project_id - - name - - language - - backend - ProjectList: - description: A list of projects - properties: - projects: - type: array - items: - $ref: '#/definitions/Project' - SuggestionResult: - description: A single candidate subject for a document - properties: - uri: - type: string - example: 'http://example.org/subject1' - label: - type: string - example: Archaeology - notation: - type: string - example: '42.42' - score: - type: number - example: 0.85 - required: - - uri - - label - - score - SuggestionResultList: - description: A list of analysis results - properties: - results: - type: array - items: - $ref: '#/definitions/SuggestionResult' - IndexedDocument: - description: A document with attached, known good subjects - properties: - text: - type: string - example: "A quick brown fox jumped over the lazy dog." - subjects: - type: array - items: - type: object - properties: - uri: - type: string - example: 'http://example.org/subject1' - label: - type: string - example: 'Vulpes vulpes' - Problem: - type: object - properties: - type: - type: string - format: uri - description: | - An absolute URI that identifies the problem type. When dereferenced, - it SHOULD provide human-readable documentation for the problem type - (e.g., using HTML). - default: 'about:blank' - example: 'https://zalando.github.io/problem/constraint-violation' - title: - type: string - description: | - A short, summary of the problem type. Written in english and readable - for engineers (usually not suited for non technical stakeholders and - not localized); example: Service Unavailable - status: - type: integer - format: int32 - description: > - The HTTP status code generated by the origin server for this - occurrence - - of the problem. - minimum: 100 - maximum: 600 - exclusiveMaximum: true - example: 503 - detail: - type: string - description: | - A human readable explanation specific to this occurrence of the - problem. - example: Connection to database timed out - instance: - type: string - format: uri - description: > - An absolute URI that identifies the specific occurrence of the - problem. - - It may or may not yield further information if dereferenced. From 75c447c1ace7a5d671a3eef25e242636059dc20b Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 18 Nov 2022 16:25:25 +0200 Subject: [PATCH 02/10] remove unnecessary response code / mimetype combinations --- annif/openapi/annif.yaml | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/annif/openapi/annif.yaml b/annif/openapi/annif.yaml index 3917c3fbc..335750c29 100644 --- a/annif/openapi/annif.yaml +++ b/annif/openapi/annif.yaml @@ -38,15 +38,9 @@ paths: application/json: schema: $ref: '#/components/schemas/Project' - application/problem+json: - schema: - $ref: '#/components/schemas/Project' 404: description: Project not found content: - application/json: - schema: - $ref: '#/components/schemas/Problem' application/problem+json: schema: $ref: '#/components/schemas/Problem' @@ -94,33 +88,21 @@ paths: application/json: schema: $ref: '#/components/schemas/SuggestionResultList' - application/problem+json: - schema: - $ref: '#/components/schemas/SuggestionResultList' 400: description: Bad Request content: - application/json: - schema: - $ref: '#/components/schemas/Problem' application/problem+json: schema: $ref: '#/components/schemas/Problem' 404: description: Project not found content: - application/json: - schema: - $ref: '#/components/schemas/Problem' application/problem+json: schema: $ref: '#/components/schemas/Problem' 503: description: Service Unavailable content: - application/json: - schema: - $ref: '#/components/schemas/Problem' application/problem+json: schema: $ref: '#/components/schemas/Problem' @@ -153,18 +135,12 @@ paths: 404: description: Project not found content: - application/json: - schema: - $ref: '#/components/schemas/Problem' application/problem+json: schema: $ref: '#/components/schemas/Problem' 503: description: Service Unavailable content: - application/json: - schema: - $ref: '#/components/schemas/Problem' application/problem+json: schema: $ref: '#/components/schemas/Problem' @@ -310,4 +286,3 @@ components: schema: type: string example: dummy-fi - From fe113eeb3ee73b6660dabcb5689cb63daaea2328 Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 18 Nov 2022 16:34:01 +0200 Subject: [PATCH 03/10] use global parameter definition for project_id --- annif/openapi/annif.yaml | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/annif/openapi/annif.yaml b/annif/openapi/annif.yaml index 335750c29..89fe7f897 100644 --- a/annif/openapi/annif.yaml +++ b/annif/openapi/annif.yaml @@ -25,12 +25,7 @@ paths: summary: show project information operationId: annif.rest.show_project parameters: - - name: project_id - in: path - description: project identifier - required: true - schema: - type: string + - $ref: '#/parameters/project_id' responses: 200: description: successful operation @@ -51,12 +46,7 @@ paths: summary: suggest subjects for a given text operationId: annif.rest.suggest parameters: - - name: project_id - in: path - description: project identifier - required: true - schema: - type: string + - $ref: '#/parameters/project_id' requestBody: content: application/x-www-form-urlencoded: @@ -113,12 +103,7 @@ paths: summary: learn from manually indexed documents operationId: annif.rest.learn parameters: - - name: project_id - in: path - description: project identifier - required: true - schema: - type: string + - $ref: '#/parameters/project_id' requestBody: description: documents to learn from content: @@ -277,12 +262,12 @@ components: An absolute URI that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced. format: uri - parameters: - project_id: - name: project_id - in: path - description: project identifier - required: true - schema: - type: string - example: dummy-fi +parameters: + project_id: + name: project_id + in: path + description: project identifier + required: true + schema: + type: string + example: dummy-fi From 80261aefccff9e9240e5c53a7fa959fb29328d69 Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 18 Nov 2022 17:07:47 +0200 Subject: [PATCH 04/10] fix OpenAPI syntax --- annif/openapi/annif.yaml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/annif/openapi/annif.yaml b/annif/openapi/annif.yaml index 89fe7f897..d521ff8d7 100644 --- a/annif/openapi/annif.yaml +++ b/annif/openapi/annif.yaml @@ -25,7 +25,7 @@ paths: summary: show project information operationId: annif.rest.show_project parameters: - - $ref: '#/parameters/project_id' + - $ref: '#/components/parameters/project_id' responses: 200: description: successful operation @@ -46,7 +46,7 @@ paths: summary: suggest subjects for a given text operationId: annif.rest.suggest parameters: - - $ref: '#/parameters/project_id' + - $ref: '#/components/parameters/project_id' requestBody: content: application/x-www-form-urlencoded: @@ -103,7 +103,7 @@ paths: summary: learn from manually indexed documents operationId: annif.rest.learn parameters: - - $ref: '#/parameters/project_id' + - $ref: '#/components/parameters/project_id' requestBody: description: documents to learn from content: @@ -241,9 +241,9 @@ components: for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable status: - maximum: 6E+2 + maximum: 600 exclusiveMaximum: true - minimum: 1E+2 + minimum: 100 type: integer description: | The HTTP status code generated by the origin server for this occurrence @@ -262,12 +262,12 @@ components: An absolute URI that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced. format: uri -parameters: - project_id: - name: project_id - in: path - description: project identifier - required: true - schema: - type: string - example: dummy-fi + parameters: + project_id: + name: project_id + in: path + description: project identifier + required: true + schema: + type: string + example: dummy-fi From c96c53fbfe7a67c2997b165161b2cae0a4fc1615 Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 25 Nov 2022 10:49:56 +0200 Subject: [PATCH 05/10] fix OpenAPI schema and implementation code mismatches --- annif/openapi/annif.yaml | 1 + annif/rest.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/annif/openapi/annif.yaml b/annif/openapi/annif.yaml index d521ff8d7..26ff6d6b7 100644 --- a/annif/openapi/annif.yaml +++ b/annif/openapi/annif.yaml @@ -51,6 +51,7 @@ paths: content: application/x-www-form-urlencoded: schema: + type: object required: - text properties: diff --git a/annif/rest.py b/annif/rest.py index d1a908e7a..a541a2b61 100644 --- a/annif/rest.py +++ b/annif/rest.py @@ -60,7 +60,7 @@ def _suggestion_to_dict(suggestion, subject_index, language): } -def suggest(project_id, text, limit, threshold, language=None): +def suggest(project_id, text="", limit=10, threshold=0.0, language=None): """suggest subjects for the given text and return a dict with results formatted according to Swagger spec""" @@ -107,7 +107,7 @@ def _documents_to_corpus(documents, subject_index): return DocumentList(corpus) -def learn(project_id, documents): +def learn(project_id, documents=[]): """learn from documents and return an empty 204 response if succesful""" try: From e4b1a5e597ce01f32a0c8eb66cb9ae7bf614b435 Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 25 Nov 2022 11:12:40 +0200 Subject: [PATCH 06/10] refer to OpenAPI, not Swagger in Web UI --- annif/templates/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/annif/templates/home.html b/annif/templates/home.html index 0afdc8418..20066eeb1 100644 --- a/annif/templates/home.html +++ b/annif/templates/home.html @@ -34,7 +34,7 @@

Web UI

Welcome!

-

See the Swagger documentation for an interactive REST API specification.

+

See the OpenAPI documentation for an interactive REST API specification.

From 0b115e05285e32c6dfa989a1cb27f5cf8936b12f Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 25 Nov 2022 14:39:32 +0200 Subject: [PATCH 07/10] fix parameter passing in REST suggest method --- annif/rest.py | 9 ++++++--- tests/test_rest.py | 26 ++++++++++---------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/annif/rest.py b/annif/rest.py index a541a2b61..7643ee9bc 100644 --- a/annif/rest.py +++ b/annif/rest.py @@ -60,7 +60,7 @@ def _suggestion_to_dict(suggestion, subject_index, language): } -def suggest(project_id, text="", limit=10, threshold=0.0, language=None): +def suggest(project_id, body): """suggest subjects for the given text and return a dict with results formatted according to Swagger spec""" @@ -70,7 +70,7 @@ def suggest(project_id, text="", limit=10, threshold=0.0, language=None): return project_not_found_error(project_id) try: - lang = language or project.vocab_lang + lang = body.get("language", project.vocab_lang) except AnnifException as err: return server_error(err) @@ -81,9 +81,12 @@ def suggest(project_id, text="", limit=10, threshold=0.0, language=None): detail=f'language "{lang}" not supported by vocabulary', ) + limit = body.get("limit", 10) + threshold = body.get("threshold", 0.0) + try: hit_filter = SuggestionFilter(project.subjects, limit, threshold) - result = project.suggest(text) + result = project.suggest(body["text"]) except AnnifException as err: return server_error(err) diff --git a/tests/test_rest.py b/tests/test_rest.py index b694be1ef..462eda568 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -48,7 +48,7 @@ def test_rest_suggest_public(app): # public projects should be accessible via REST with app.app_context(): result = annif.rest.suggest( - "dummy-fi", text="example text", limit=10, threshold=0.0 + "dummy-fi", {"text": "example text", "limit": 10, "threshold": 0.0} ) assert "results" in result @@ -57,7 +57,7 @@ def test_rest_suggest_hidden(app): # hidden projects should be accessible if you know the project id with app.app_context(): result = annif.rest.suggest( - "dummy-en", text="example text", limit=10, threshold=0.0 + "dummy-en", {"text": "example text", "limit": 10, "threshold": 0.0} ) assert "results" in result @@ -66,7 +66,7 @@ def test_rest_suggest_private(app): # private projects should not be accessible via REST with app.app_context(): result = annif.rest.suggest( - "dummy-private", text="example text", limit=10, threshold=0.0 + "dummy-private", {"text": "example text", "limit": 10, "threshold": 0.0} ) assert result.status_code == 404 @@ -74,7 +74,7 @@ def test_rest_suggest_private(app): def test_rest_suggest_nonexistent(app): with app.app_context(): result = annif.rest.suggest( - "nonexistent", text="example text", limit=10, threshold=0.0 + "nonexistent", {"text": "example text", "limit": 10, "threshold": 0.0} ) assert result.status_code == 404 @@ -82,7 +82,7 @@ def test_rest_suggest_nonexistent(app): def test_rest_suggest_novocab(app): with app.app_context(): result = annif.rest.suggest( - "novocab", text="example text", limit=10, threshold=0.0 + "novocab", {"text": "example text", "limit": 10, "threshold": 0.0} ) assert result.status_code == 503 @@ -91,10 +91,7 @@ def test_rest_suggest_with_language_override(app): with app.app_context(): result = annif.rest.suggest( "dummy-vocablang", - text="example text", - limit=10, - threshold=0.0, - language="en", + {"text": "example text", "limit": 10, "threshold": 0.0, "language": "en"}, ) assert result["results"][0]["label"] == "dummy" @@ -103,10 +100,7 @@ def test_rest_suggest_with_language_override_bad_value(app): with app.app_context(): result = annif.rest.suggest( "dummy-vocablang", - text="example text", - limit=10, - threshold=0.0, - language="xx", + {"text": "example text", "limit": 10, "threshold": 0.0, "language": "xx"}, ) assert result.status_code == 400 @@ -116,7 +110,7 @@ def test_rest_suggest_with_different_vocab_language(app): # vocab language is Finnish - subject labels should be in Finnish with app.app_context(): result = annif.rest.suggest( - "dummy-vocablang", text="example text", limit=10, threshold=0.0 + "dummy-vocablang", {"text": "example text", "limit": 10, "threshold": 0.0} ) assert result["results"][0]["label"] == "dummy-fi" @@ -124,7 +118,7 @@ def test_rest_suggest_with_different_vocab_language(app): def test_rest_suggest_with_notations(app): with app.app_context(): result = annif.rest.suggest( - "dummy-fi", text="example text", limit=10, threshold=0.0 + "dummy-fi", {"text": "example text", "limit": 10, "threshold": 0.0} ) assert result["results"][0]["notation"] is None @@ -147,7 +141,7 @@ def test_rest_learn(app): assert response == (None, 204) # success, no output result = annif.rest.suggest( - "dummy-en", text="example text", limit=10, threshold=0.0 + "dummy-en", {"text": "example text", "limit": 10, "threshold": 0.0} ) assert "results" in result assert result["results"][0]["uri"] == "http://example.org/none" From f9d8f077a02a1d0d531631c9c9283a55335449b5 Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 25 Nov 2022 15:30:09 +0200 Subject: [PATCH 08/10] don't break on empty value for language parameter --- annif/rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/annif/rest.py b/annif/rest.py index 7643ee9bc..da2d37c2a 100644 --- a/annif/rest.py +++ b/annif/rest.py @@ -70,7 +70,7 @@ def suggest(project_id, body): return project_not_found_error(project_id) try: - lang = body.get("language", project.vocab_lang) + lang = body.get("language") or project.vocab_lang except AnnifException as err: return server_error(err) From 91faf2cdd5917ccdf85cf1a0b6b654c56db0c4ed Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 25 Nov 2022 15:38:49 +0200 Subject: [PATCH 09/10] fix parameter handling in REST API learn method --- annif/rest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/annif/rest.py b/annif/rest.py index da2d37c2a..5d000b1c9 100644 --- a/annif/rest.py +++ b/annif/rest.py @@ -110,7 +110,7 @@ def _documents_to_corpus(documents, subject_index): return DocumentList(corpus) -def learn(project_id, documents=[]): +def learn(project_id, body): """learn from documents and return an empty 204 response if succesful""" try: @@ -119,7 +119,7 @@ def learn(project_id, documents=[]): return project_not_found_error(project_id) try: - corpus = _documents_to_corpus(documents, project.subjects) + corpus = _documents_to_corpus(body, project.subjects) project.learn(corpus) except AnnifException as err: return server_error(err) From b8f6b8ce0429a90e9fbb55f89fd1c1f233e028fc Mon Sep 17 00:00:00 2001 From: Osma Suominen Date: Fri, 25 Nov 2022 16:02:53 +0200 Subject: [PATCH 10/10] add minimum and maximum values for limit and threshold parameters --- annif/openapi/annif.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/annif/openapi/annif.yaml b/annif/openapi/annif.yaml index 26ff6d6b7..4b2824575 100644 --- a/annif/openapi/annif.yaml +++ b/annif/openapi/annif.yaml @@ -63,11 +63,14 @@ paths: description: maximum number of results to return format: int32 default: 10 + minimum: 0 threshold: type: number description: minimum score threshold, below which results will not be returned default: 0.0 + minimum: 0.0 + maximum: 1.0 language: type: string description: language of subject labels