Deploy Spacy Ner With Fast Api
January 28, 2021
SpaCy
NER
NLP
SpaCy
In my previous post here: https://yudanta.github.io/posts/train-an-indonesian-ner-from-a-blank-spacy-model/, I shared about how to train simple Indonesian NER model with SpaCy. The detail of training process can be found in that article. In this post, we will focus on how to deploy the model as a REST API with FastAPI, so the users can query to our NER model via REST API. However, in this tutorial, will focus on how to create simple FastAPI project and load pre-trained NER model, if you are not familiar with FastAPI yet, please go to the FastAPI documentation site here: https://fastapi.tiangolo.com/tutorial/.
First, I already prepare the trained model here in this directory nlp_models/nlp_id_checkpoint_2021-01-12
, for the example, so you don’t have to train the model, except you are have your own model previously or more datasets then use your own model.
We structured the FastAPI model as below:
├── README.md
├── app
│ ├── __init__.py
│ ├── apis
│ │ └── nlp
│ │ ├── __init__.py
│ │ └── ner.py
│ ├── core
│ │ └── __init__.py
│ ├── main.py
│ ├── routes
│ │ ├── __init__.py
│ │ └── nlp.py
│ └── tests
│ └── __init__.py
├── config.py
├── logging.conf
├── nlp_models
│ └── nlp_id_checkpoint_2021-01-12
└── requirements.txt
To load pre-trained spacy model in ```main.py``
from pathlib import Path
import spacy
model_dir = Path('nlp_models/nlp_id_checkpoint_2021-01-12')
id_nlp = spacy.load(model_dir)
I add ner.py
under app/apis/nlp
for handling query from users to SpaCy model
from typing import List, Dict
from ...main import id_nlp
def get_entities(sentence) -> List[Dict]:
doc = id_nlp(sentence)
return [(ent.text, ent.label_) for ent in doc.ents]
and for handling the http route/request, the script for http routing is in nlp.py
file
from typing import Optional
from fastapi import APIRouter
from pydantic import BaseModel
class NerQuery(BaseModel):
sentence: str
from ..apis.nlp.ner import get_entities
router = APIRouter(
prefix='/nlp/id',
tags=['nlp'],
responses={
404: {'description': 'Not Found'}
}
)
@router.post('/ner')
async def api_ner(query: NerQuery):
result = get_entities(query.sentence)
return result
Lastly, we add the router to the main.py
file with include_router
app = FastAPI()
from .routes import nlp
app.include_router(nlp.router)
to run the project with uvicorn:
uvicorn app.main:app --reload
wait a moments, some time required for loading SpaCy model.
You can access the generated documentation here: http://localhost:8000/docs#/nlp/api_ner_nlp_id_ner_post, try to query directly from the swagger or using curl like below
curl -X POST "http://localhost:8000/nlp/id/ner" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"sentence\":\"Bekas Anggota BPK Rizal Djalil Didakwa Menerima Suap Rp 1 Miliar.\"}"
result
[
[
"Rizal Djalil",
"PERSON"
]
]
the complete codes for this project can be found on this repository: https://github.com/yudanta/id-ner-spacy-fast-api, maybe, later I will add docker file for this project and maybe provide an online demo (but not promise :D)