Skip to content

Commit 944ea0e

Browse files
committed
feat(api): add sentence processing endpoint
1 parent 33b5a6c commit 944ea0e

22 files changed

Lines changed: 377 additions & 25 deletions

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,7 @@ dmypy.json
129129
.pyre/
130130

131131
#VSCode
132-
.vscode/
132+
.vscode/
133+
134+
# Junit
135+
junit/

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ WORKDIR /usr/src/example-api
1010
COPY . .
1111

1212
RUN pipenv install
13+
RUN pipenv run spacy download en_core_web_sm
1314

1415
EXPOSE 5000
1516

Pipfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ python_version = "3.8"
99
[packages]
1010
fastapi = "*"
1111
uvicorn = "*"
12+
spacy = "*"
1213

1314
[dev-packages]
1415
pytest = "*"

Pipfile.lock

Lines changed: 232 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
[![azure-pipelines-build](https://img.shields.io/azure-devops/build/xaviml93/ControllerX/3/master.svg?style=for-the-badge)](https://dev.azure.com/xaviml93/ControllerX/_build/latest?definitionId=3&branchName=master)
2+
[![azure-pipelines-coverage](https://img.shields.io/azure-devops/coverage/xaviml93/ControllerX/3/master.svg?style=for-the-badge)](https://dev.azure.com/xaviml93/ControllerX/_build/latest?definitionId=3&branchName=master)
3+
[![last-release](https://img.shields.io/github/v/release/xaviml/example-api.svg?style=for-the-badge)](https://github.com/xaviml/controllerx/releases)
4+
15
# Example API
26

37
This project was created for the purpose of an interview test. Its goal is to build an API endpoint that returns name entities given a sentence as an input.
48

59
## Dependencies
610

711
- FastAPI: Web framework to build APIs with Python
12+
- spaCY: Library for NLP in Python
813
- pre-commit: It allows me to run some checks before a git commit is done
914
- commitizen: It gives a standard way to commit code and also allows me to version the code
1015
- pytest: Used to run the tests
11-
- Azure pipelines: Used to run a pipeline everytime there is a commit o a new tag is added for a new release with automated release notes.
16+
- Azure pipelines: Used to run a pipeline everytime there is a commit o a new tag is added for a new release with automated release notes
1217

1318
## Install
1419

@@ -17,13 +22,14 @@ Install [pipenv](https://pipenv.kennethreitz.org/en/latest/install/#installing-p
1722
```
1823
pipenv install --dev
1924
pipenv run pre-commit install
25+
pipenv run spacy download en_core_web_sm
2026
```
2127

22-
### Run
28+
## Run
2329

2430
There are two ways to run the project, via Docker or through python virtual environment.
2531

26-
## With docker
32+
### With docker
2733

2834
If we want to run with Docker, we first need to build an image:
2935

@@ -33,26 +39,43 @@ And then run an instance:
3339

3440
`docker run -i -d -p 8080:5000 example-api`
3541

36-
## Without docker
42+
### Without docker
3743

3844
However, if we want to run without Docker, we can run directly with uvicorn:
3945

4046
```
4147
pipenv run uvicorn --host 0.0.0.0 --port 5000 app.main:app
4248
```
4349

44-
### Tests
50+
## Tests
4551

4652
Run this command to run tests with coverage:
4753

48-
`python -m pytest --cov=app`
54+
`pipenv run pytest --cov=app`
55+
56+
## Formatting
57+
58+
Run the following command to format all the project:
4959

50-
### Deploying
60+
`pipenv run pre-commit run --all-files`
5161

52-
By running `cz bump` it automatically detecs the version to bump - major, minor or patch. It follows [SemVer](https://semver.org/) standard. Then when pushin the code to GitHub, it needs to be done like this:
62+
## Deploying
63+
64+
By running `cz bump` it automatically detecs the version to bump - major, minor or patch. It follows [SemVer](https://semver.org/) standard. Then when pushing the code to GitHub, it needs to be done like this:
5365

5466
```
5567
git push origin master --tags
5668
```
5769

5870
It will then push the code and the Azure Pipeline will create the GitHub release if the pipeline passes.
71+
72+
### API and documentation
73+
74+
The API currently has 2 endpoints:
75+
76+
- `/api/v1/sentence/process`: It processess a sentence
77+
- `/check`: It checks the system is running
78+
79+
Furthermore, FastAPI automatically generates the documentation for you, so when running you can access to `/docs` and you will be able to see in detail all the endpoints with its I/O.
80+
81+
For the sentence processing, I hace used `spacy`, a free open-source library for NLP in Python. [These](https://spacy.io/api/annotation#named-entities) are the named entity types that can be sent by the API.

app/__init__.py

Whitespace-only changes.

app/api/api_v1/__init__.py

Whitespace-only changes.

app/api/api_v1/api.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from fastapi import APIRouter
2+
3+
from app.api.api_v1.endpoints import sentence
4+
5+
api_router = APIRouter()
6+
7+
api_router.include_router(sentence.router, prefix="/sentence", tags=["sentence"])

app/api/api_v1/endpoints/__init__.py

Whitespace-only changes.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import spacy
2+
from fastapi import APIRouter
3+
from starlette.responses import JSONResponse
4+
5+
from app.models.sentence import NamedEntity, ProcessedSentence, Sentence
6+
7+
router = APIRouter()
8+
9+
nlp = spacy.load("en_core_web_sm")
10+
11+
12+
@router.post("/process", response_model=ProcessedSentence)
13+
def extract_name(sentence: Sentence):
14+
"""
15+
This endpoint returns a processed sentence
16+
"""
17+
doc = nlp(sentence.sentence)
18+
named_entities = [
19+
NamedEntity(entity=ent.text, entity_type=ent.label_) for ent in doc.ents
20+
]
21+
return ProcessedSentence(named_entities=named_entities)

0 commit comments

Comments
 (0)