Skip to content

Commit

Permalink
Release 1.1.0 (#105)
Browse files Browse the repository at this point in the history
* Run OpenAPI generator

* Update schemas (part 1/2)

* Update codebase (part 2/2)

* Add scripts to package.json

* Update schemas and tool versions

* Patch README
  • Loading branch information
tschaffter authored May 11, 2021
1 parent c0d513d commit 57f01a1
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 72 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ note.

### Specification

- Date Annotator API version: 1.0.2
- Tool version: 1.0.2
- Date Annotator API version: 1.1.0
- Tool version: 1.1.0
- Docker image: [nlpsandbox/date-annotator-example]

## Model
Expand Down Expand Up @@ -53,13 +53,13 @@ You can stop the container run with `Ctrl+C`, followed by `docker-compose down`.

We recommend using a Conda environment to install and run the Date Annotator.

conda create --name date-annotator python=3.9.1
conda create --name date-annotator python=3.9
conda activate date-annotator

Install and start the Date Annotator.

cd server/
pip install -e .
pip install -r requirements.txt
python -m openapi_server

### Accessing the UI
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: "3.8"

services:
date-annotator:
image: nlpsandbox/date-annotator-example:1.0.2
image: nlpsandbox/date-annotator-example:1.1.0
build:
context: server
dockerfile: Dockerfile
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"generate:server:latest": "openapi-generator-cli generate -g python-flask -o server -i https://nlpsandbox.github.io/nlpsandbox-schemas/date-annotator/latest/openapi.json",
"generate:server:edge": "openapi-generator-cli generate -g python-flask -o server -i https://nlpsandbox.github.io/nlpsandbox-schemas/date-annotator/edge/openapi.json",
"lint": "cd server && flake8",
"test": "cd server && tox"
"test": "cd server && tox",
"install:dependencies": "npm ci && cd server && pip install -r requirements.txt",
"start:dev": "cd server && python -m openapi_server",
"start:prod": "docker-compose up --build"
}
}
2 changes: 1 addition & 1 deletion server/openapi_server/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


def main():
app.run(port=8080)
app.run(port=8080, debug=False)


if __name__ == '__main__':
Expand Down
6 changes: 3 additions & 3 deletions server/openapi_server/controllers/tool_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ def get_tool(): # noqa: E501
"""
tool = Tool(
name="date-annotator-example",
version="1.0.2",
version="1.1.0",
license=License.APACHE_2_0,
repository="github:nlpsandbox/date-annotator-example",
description="Example implementation of the NLP Sandbox Date Annotator",
author="The NLP Sandbox Team",
author_email="thomas.schaffter@sagebionetworks.org",
url="https://github.com/nlpsandbox/date-annotator-example",
type="nlpsandbox:date-annotator",
api_version="1.0.2"
api_version="1.1.0"
)
return tool, 200

Expand All @@ -34,4 +34,4 @@ def get_tool_dependencies(): # noqa: E501
:rtype: ToolDependencies
"""
return ToolDependencies(tool_dependencies=[]), 200
return ToolDependencies(tools=[]), 200
36 changes: 18 additions & 18 deletions server/openapi_server/models/tool_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ class ToolDependencies(Model):
Do not edit the class manually.
"""

def __init__(self, tool_dependencies=None): # noqa: E501
def __init__(self, tools=None): # noqa: E501
"""ToolDependencies - a model defined in OpenAPI
:param tool_dependencies: The tool_dependencies of this ToolDependencies. # noqa: E501
:type tool_dependencies: List[Tool]
:param tools: The tools of this ToolDependencies. # noqa: E501
:type tools: List[Tool]
"""
self.openapi_types = {
'tool_dependencies': List[Tool]
'tools': List[Tool]
}

self.attribute_map = {
'tool_dependencies': 'toolDependencies'
'tools': 'tools'
}

self._tool_dependencies = tool_dependencies
self._tools = tools

@classmethod
def from_dict(cls, dikt) -> 'ToolDependencies':
Expand All @@ -45,26 +45,26 @@ def from_dict(cls, dikt) -> 'ToolDependencies':
return util.deserialize_model(dikt, cls)

@property
def tool_dependencies(self):
"""Gets the tool_dependencies of this ToolDependencies.
def tools(self):
"""Gets the tools of this ToolDependencies.
A list of tools # noqa: E501
:return: The tool_dependencies of this ToolDependencies.
:return: The tools of this ToolDependencies.
:rtype: List[Tool]
"""
return self._tool_dependencies
return self._tools

@tool_dependencies.setter
def tool_dependencies(self, tool_dependencies):
"""Sets the tool_dependencies of this ToolDependencies.
@tools.setter
def tools(self, tools):
"""Sets the tools of this ToolDependencies.
A list of tools # noqa: E501
:param tool_dependencies: The tool_dependencies of this ToolDependencies.
:type tool_dependencies: List[Tool]
:param tools: The tools of this ToolDependencies.
:type tools: List[Tool]
"""
if tool_dependencies is None:
raise ValueError("Invalid value for `tool_dependencies`, must not be `None`") # noqa: E501
if tools is None:
raise ValueError("Invalid value for `tools`, must not be `None`") # noqa: E501

self._tool_dependencies = tool_dependencies
self._tools = tools
31 changes: 16 additions & 15 deletions server/openapi_server/openapi/openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
openapi: 3.0.3
info:
contact:
email: thomas.schaffter@sagebionetworks.org
name: The NLP Sandbox Team
email: team@nlpsandbox.io
name: NLP Sandbox Team
url: https://nlpsandbox.io
description: |
# Introduction
The Date Annotator is one of the first type of NLP Tools that can be benchmarked on [nlpsandbox.io](https://nlpsandbox.io). A Date Annotator takes as input a clinical note and outputs a list of predicted date annotations found in the clinical note. This OpenAPI document describes the specification of a Date Annotator. This specification includes the schemas of the input and output data, and the conditions that this annotator must meet if you want to benchmark its performance on [nlpsandbox.io](https://nlpsandbox.io).
A Date Annotator takes as input a clinical note and outputs a list of predicted date annotations found in the clinical note. This OpenAPI document describes the specification of a Date Annotator. This specification includes the schemas of the input and output data, and the conditions that this annotator must meet if you want to benchmark its performance on [nlpsandbox.io](https://nlpsandbox.io).
# Getting Started
The GitHub repository [nlpsandbox/date-annotator-example](https://github.com/nlpsandbox/date-annotator-example) provides a simple example implementation of a Python-Flask Date Annotator. By the end of the tutorial available in this repository, you will have built a Docker image for a simple Date Annotator. You will then be able to submit this image to [nlpsandbox.io](https://nlpsandbox.io) to benchmark its performance.
The GitHub repository [nlpsandbox/date-annotator-example](https://github.com/nlpsandbox/date-annotator-example) provides a simple example implementation of a Python-Flask Date Annotator. By the end of the tutorial available in the README, you will have built a Docker image for a simple Date Annotator. You will then be able to submit this image to [nlpsandbox.io](https://nlpsandbox.io) to benchmark its performance.
# Benchmarking Requirements
The following conditions must be met by your Date Annotator if you want to benchmark its performance on [nlpsandbox.io](https://nlpsandbox.io).
Your NLP Sandbox tool must meet the following conditions before evaluating its performance on [nlpsandbox.io](https://nlpsandbox.io).
- The endpoint `/` must redirect to `/api/v1/tool`.
- The endpoint `/ui` must redirect to the web interface (UI).
- The output of this tool must be reproducible: a given input should always
generate the same output.
- This tool must not attempt to connect to remote server for reproducibility,
robustness, and security reasons. When benchmarked on [nlpsandbox.io](https://nlpsandbox.io),
this tool will not be able to connect to remote servers.
- To ensure the results are reproducible and robust, and the data are
secured, this tool must not connect to any remote server. When benchmarked
on [nlpsandbox.io](https://nlpsandbox.io), this tool will not be able to
connect to remote servers.
# Examples
- [Date Annotator Example (Python)](https://github.com/nlpsandbox/date-annotator-example)
Expand All @@ -27,7 +28,7 @@ info:
name: Apache 2.0
url: https://github.com/nlpsandbox/nlpsandbox-schemas/blob/develop/LICENSE
title: NLP Sandbox Date Annotator API
version: 1.0.2
version: 1.1.0
x-logo:
url: https://nlpsandbox.github.io/nlpsandbox-schemas/logo.png
servers:
Expand Down Expand Up @@ -399,7 +400,7 @@ components:
authorEmail: author@example.com
url: https://example.com
type: nlpsandbox:date-annotator
apiVersion: 1.0.2
apiVersion: 1.1.0
properties:
name:
description: The tool name
Expand Down Expand Up @@ -459,7 +460,7 @@ components:
ToolDependencies:
description: A list of tool dependencies
example:
toolDependencies:
tools:
- name: awesome-nlp-tool
version: 1.0.6
license: apache-2.0
Expand All @@ -469,7 +470,7 @@ components:
authorEmail: author@example.com
url: https://example.com
type: nlpsandbox:date-annotator
apiVersion: 1.0.2
apiVersion: 1.1.0
- name: awesome-nlp-tool
version: 1.0.6
license: apache-2.0
Expand All @@ -479,15 +480,15 @@ components:
authorEmail: author@example.com
url: https://example.com
type: nlpsandbox:date-annotator
apiVersion: 1.0.2
apiVersion: 1.1.0
properties:
toolDependencies:
tools:
description: A list of tools
items:
$ref: '#/components/schemas/Tool'
type: array
required:
- toolDependencies
- tools
type: object
TextDateAnnotation_allOf:
properties:
Expand Down
16 changes: 16 additions & 0 deletions server/openapi_server/test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import logging

import connexion
from flask_testing import TestCase

from openapi_server.encoder import JSONEncoder


class BaseTestCase(TestCase):

def create_app(self):
logging.getLogger('connexion.operation').setLevel('ERROR')
app = connexion.App(__name__, specification_dir='../openapi/')
app.app.json_encoder = JSONEncoder
app.add_api('openapi.yaml', pythonic_params=True)
return app.app
15 changes: 0 additions & 15 deletions server/openapi_server/test/integration/__init__.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
from __future__ import absolute_import
import unittest

from openapi_server.test.integration import BaseTestCase
from flask import json
from six import BytesIO

from openapi_server.models.error import Error # noqa: E501
from openapi_server.models.health_check import HealthCheck # noqa: E501
from openapi_server.test import BaseTestCase


class TestHealthCheckController(BaseTestCase):
Expand All @@ -14,7 +19,7 @@ def test_get_health_check(self):
Get health check information
"""
headers = {
headers = {
'Accept': 'application/json',
}
response = self.client.open(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
import unittest

from flask import json
from six import BytesIO

from openapi_server.test.integration import BaseTestCase
from openapi_server.models.error import Error # noqa: E501
from openapi_server.models.text_date_annotation_request import TextDateAnnotationRequest # noqa: E501
from openapi_server.models.text_date_annotation_response import TextDateAnnotationResponse # noqa: E501
from openapi_server.test import BaseTestCase


class TestTextDateAnnotationController(BaseTestCase):
Expand All @@ -17,14 +21,14 @@ def test_create_text_date_annotations(self):
Annotate dates in a clinical note
"""
text_date_annotation_request = {
"note": {
"identifier": "awesome-note",
"type": "loinc:LP29684-5",
"patientId": "awesome-patient",
"text": "On 12/26/2020, Ms. Chloe Price met with Dr. Prescott."
}
}
headers = {
"note" : {
"identifier" : "awesome-note",
"text" : "On 12/26/2020, Ms. Chloe Price met with Dr. Prescott in Seattle.",
"type" : "loinc:LP29684-5",
"patientId" : "awesome-patient"
}
}
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
from __future__ import absolute_import
import unittest

from openapi_server.test.integration import BaseTestCase
from flask import json
from six import BytesIO

from openapi_server.models.error import Error # noqa: E501
from openapi_server.models.tool import Tool # noqa: E501
from openapi_server.models.tool_dependencies import ToolDependencies # noqa: E501
from openapi_server.test import BaseTestCase


class TestToolController(BaseTestCase):
Expand All @@ -14,7 +20,7 @@ def test_get_tool(self):
Get tool information
"""
headers = {
headers = {
'Accept': 'application/json',
}
response = self.client.open(
Expand All @@ -29,7 +35,7 @@ def test_get_tool_dependencies(self):
Get tool dependencies
"""
headers = {
headers = {
'Accept': 'application/json',
}
response = self.client.open(
Expand Down
1 change: 1 addition & 0 deletions server/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ max-line-length: 80
exclude =
.*
openapi_server/models/*.py
openapi_server/test/*.py

[coverage:run]
omit =
Expand Down

0 comments on commit 57f01a1

Please sign in to comment.