Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions python/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#
FROM python:3.10

#
WORKDIR /code

#
COPY ./requirements.txt /code/requirements.txt

#
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

#
COPY ./app /code/app
#
ENV PYTHONPATH="/code/app"
#
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
58 changes: 6 additions & 52 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,7 @@
# Тестовое задание для Python разработчика
## Рекомендации по выполнению задания
1. Использовать python для выполнения задания
2. Применить для разработки API сервиса фреймворк FastAPI
4. Использовать библиотеки FastAPI, torch, transformers
5. Для запуска FastAPI использовать uvicorn
Для запуска приложения необходимо установить и включить Docker Desktop последней версии
Находясь в директории с Dockerfile запустить следующие команды:
docker build -t myimage .
docker run -d --name mycontainer -p 8000:8000 myimage

## Задание
1. Встроить модель (https://huggingface.co/Aniemore/rubert-tiny2-russian-emotion-detection) в API сервис. Модель выполняет анализ тональности (sentiment analysis) предложения.
2. В API сервисе нужно реализовать endpoint на который методом POST будет отправляться предложение для анализа. Название эндпоинта придумать самостоятельно.
### Пример:
#### Запрос:
````
{"text": "Это API сервис"}
````
#### Ответ:
````
{
"results": [
{
"label": "neutral",
"score": 0.9809684157371521
},
{
"label": "enthusiasm",
"score": 0.006884392816573381
},
{
"label": "anger",
"score": 0.006308802869170904
},
{
"label": "sadness",
"score": 0.006137280724942684
},
{
"label": "happiness",
"score": 0.004910049494355917
},
{
"label": "fear",
"score": 0.004772619344294071
},
{
"label": "disgust",
"score": 0.002789509715512395
}
]
}
````
3. В сервисе реализовать сборку документации(swagger) которая должны быть доступна по URL `/docs`.
4. Сделать ПР с кодом и Dockerfile для сборки контейнера с сервисом. После запуска контейнера сервис должен быть доступен на порту 8000. (localhost:8000). Версии пакетов зафиксировать в requirements.txt.
5. Написать краткую инструкцию по запуску.
Приложение принимает POST запросы по адресу localhost:8000/analyze/{text}
Документация доступная по localhost:8000/docs
6 changes: 6 additions & 0 deletions python/app/OutFormating.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def decorate(dictionary):
output = {"results" : []}
for key, value in dictionary.items():
output["results"].append({"label" : key, "score" : value})
return output

16 changes: 16 additions & 0 deletions python/app/emotion_analyzer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import torch
from transformers import BertForSequenceClassification, AutoTokenizer

LABELS = ["neutral", "happiness", "sadness", "enthusiasm", "fear", "anger", "disgust"]
tokenizer = AutoTokenizer.from_pretrained('Aniemore/rubert-tiny2-russian-emotion-detection')
model = BertForSequenceClassification.from_pretrained('Aniemore/rubert-tiny2-russian-emotion-detection')

@torch.no_grad()
def predict_emotions(text: str) -> list:
inputs = tokenizer(text, max_length=512, padding=True, truncation=True, return_tensors="pt")
outputs = model(**inputs)
predicted = torch.nn.functional.softmax(outputs.logits, dim=1)
emotions_list = {}
for i in range(len(predicted.numpy()[0].tolist())):
emotions_list[LABELS[i]] = predicted.numpy()[0].tolist()[i]
return emotions_list
12 changes: 12 additions & 0 deletions python/app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from fastapi import FastAPI
import emotion_analyzer
import OutFormating

app = FastAPI()

@app.post("/analyze/{text}")
def analyze_text(text: str):
""" Принимает строку и возвращает анализ эмоций введённого сообщения """
analysis_result = emotion_analyzer.predict_emotions(text)
return OutFormating.decorate(analysis_result)

6 changes: 6 additions & 0 deletions python/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fastapi==0.85.0
huggingface-hub==0.10.0
pydantic==1.10.2
torch==1.12.1
transformers==4.22.2
uvicorn==0.18.3