Skip to content

Commit

Permalink
Release 1.1.0 (#55)
Browse files Browse the repository at this point in the history
* Add scripts to package.json

* Run npm run generate:server:edge

* Finalize update
  • Loading branch information
tschaffter committed May 11, 2021
1 parent 3162c9b commit c35c5ac
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 75 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ jobs:
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# NLP Sandbox Person Name Annotator Example

[![GitHub Release](https://img.shields.io/github/release/nlpsandbox/person-name-annotator-example.svg?include_prereleases&color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/nlpsandbox/person-name-annotator-example/releases)
[![GitHub CI](https://img.shields.io/github/workflow/status/nlpsandbox/person-name-annotator-example/ci.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/nlpsandbox/person-name-annotator-example/actions)
[![GitHub CI](https://img.shields.io/github/workflow/status/nlpsandbox/person-name-annotator-example/CI.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/nlpsandbox/person-name-annotator-example/actions)
[![GitHub License](https://img.shields.io/github/license/nlpsandbox/person-name-annotator-example.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/nlpsandbox/person-name-annotator-example/blob/develop/LICENSE)
[![Docker Pulls](https://img.shields.io/docker/pulls/nlpsandbox/person-name-annotator-example.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=pulls&logo=docker)](https://hub.docker.com/r/nlpsandbox/person-name-annotator-example)
[![Discord](https://img.shields.io/discord/770484164393828373.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Discord&logo=discord)](https://nlpsandbox.io/discord "Realtime support / chat with the community and the team")
Expand All @@ -19,8 +19,8 @@ found in the clinical note.

### Specification

- Person Name Annotator API version: 1.0.2
- Tool version: 1.0.2
- Person Name Annotator API version: 1.1.0
- Tool version: 1.1.0
- Docker image: [nlpsandbox/person-name-annotator-example]

## Model
Expand Down Expand Up @@ -52,13 +52,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 Person Name
Annotator.

conda create --name person-name-annotator python=3.9.1
conda create --name person-name-annotator python=3.9.4
conda activate person-name-annotator

Install and start the Person Name 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:
person-name-annotator:
image: nlpsandbox/person-name-annotator-example:1.0.2
image: nlpsandbox/person-name-annotator-example:1.1.0
build:
context: server
dockerfile: Dockerfile
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
"scripts": {
"generate:server": "openapi-generator-cli generate -g python-flask -o server -i $npm_config_specification",
"generate:server:latest": "openapi-generator-cli generate -g python-flask -o server -i https://nlpsandbox.github.io/nlpsandbox-schemas/person-name-annotator/latest/openapi.json",
"generate:server:edge": "openapi-generator-cli generate -g python-flask -o server -i https://nlpsandbox.github.io/nlpsandbox-schemas/person-name-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,7 +13,7 @@ def get_tool(): # noqa: E501
"""
tool = Tool(
name="person-name-annotator-example",
version="1.0.2",
version="1.1.0",
license=License.APACHE_2_0,
repository="github:nlpsandbox/person-name-annotator-example",
description="Example implementation of the NLP Sandbox Person " +
Expand All @@ -22,7 +22,7 @@ def get_tool(): # noqa: E501
author_email="[email protected]",
url="https://github.com/nlpsandbox/person-name-annotator-example",
type="nlpsandbox:person-name-annotator",
api_version="1.0.2"
api_version="1.1.0"
)
return tool, 200

Expand All @@ -35,4 +35,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,32 +1,33 @@
openapi: 3.0.3
info:
contact:
email: [email protected]
name: The NLP Sandbox Team
email: [email protected]
name: NLP Sandbox Team
url: https://nlpsandbox.io
description: |
# Introduction
The Person Name Annotator is one of the first type of NLP Tools that can be benchmarked on [nlpsandbox.io](https://nlpsandbox.io). A Person Name Annotator takes as input a clinical note and outputs a list of predicted person name annotations found in the clinical note. This OpenAPI document describes the specification of a Person Name 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 Person Name Annotator takes as input a clinical note and outputs a list of predicted person name annotations found in the clinical note. This OpenAPI document describes the specification of a Person Name 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/person-name-annotator-example](https://github.com/nlpsandbox/person-name-annotator-example) provides a simple example implementation of a Python-Flask Person Name Annotator. By the end of the tutorial available in this repository, you will have built a Docker image for a simple Person Name Annotator. You will then be able to submit this image to [nlpsandbox.io](https://nlpsandbox.io) to benchmark its performance.
The GitHub repository [nlpsandbox/person-name-annotator-example](https://github.com/nlpsandbox/person-name-annotator-example) provides a simple example implementation of a Python-Flask Person Name Annotator. By the end of the tutorial available in the README, you will have built a Docker image for a simple Person Name 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 Person Name 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
- [Person Name Annotator Example (Python)](https://github.com/nlpsandbox/person-name-annotator-example)
license:
name: Apache 2.0
url: https://github.com/nlpsandbox/nlpsandbox-schemas/blob/develop/LICENSE
title: NLP Sandbox Person Name 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 @@ -394,7 +395,7 @@ components:
authorEmail: [email protected]
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 @@ -454,7 +455,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 @@ -464,7 +465,7 @@ components:
authorEmail: [email protected]
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 @@ -474,13 +475,13 @@ components:
authorEmail: [email protected]
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
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
16 changes: 0 additions & 16 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_person_name_annotation_request import TextPersonNameAnnotationRequest # noqa: E501
from openapi_server.models.text_person_name_annotation_response import TextPersonNameAnnotationResponse # noqa: E501
from openapi_server.test import BaseTestCase


class TestTextPersonNameAnnotationController(BaseTestCase):
Expand All @@ -17,14 +21,14 @@ def test_create_text_person_name_annotations(self):
Annotate person names in a clinical note
"""
text_person_name_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 c35c5ac

Please sign in to comment.