kavlab commited on
Commit
1e7f40c
1 Parent(s): dc4c135

merged with github repo

Browse files
README.md CHANGED
@@ -9,7 +9,9 @@ app_file: run.py
9
  pinned: false
10
  ---
11
 
12
- # Программная инженерия. Практические задания №2, №3 и №4
 
 
13
 
14
  Приложение разработано с использованием фреймворка [Streamlit](https://streamlit.io/).
15
  Состоит из двух страниц и Главной страницы:
@@ -48,7 +50,7 @@ streamlit run run.py
48
  ### Генератор аудио
49
  Необходимо ввести текст в текстовое поле и нажать кнопку "Генерировать!!!". В результате появится аудио запись на английском языке с описанием введенного текста.
50
 
51
- ![Результат работы моделей "Генератор аудио / Текст"](https://raw.githubusercontent.com/kavlab/urfu_iml_2023_1_3_hw2/main/mulyavin_aa/audio_gen_image.png)
52
  ![Результат работы моделей "Генератор аудио / Аудио"](https://raw.githubusercontent.com/kavlab/urfu_iml_2023_1_3_hw2/main/kuznetsov_av/text_to_speech_image.png)
53
 
54
  ### Описание изображения
@@ -65,7 +67,7 @@ streamlit run run.py
65
  #### Пример вызова сервиса Определение языка текста
66
  Вызвать url сервиса ```<host>/langdetector/detect``` методом POST
67
 
68
- ![img.png](https://raw.githubusercontent.com/kavlab/urfu_iml_2023_1_3_hw2/main/mulyavin_aa/PostmanLangDetect.png)
69
 
70
  Передаваемые параметры:
71
  ```
@@ -89,7 +91,7 @@ streamlit run run.py
89
  #### Пример вызова сервиса Перевод текста с языка Ru на En
90
  Вызвать url сервиса ```<host>/translator/translate``` методом POST
91
 
92
- ![img.png](https://raw.githubusercontent.com/kavlab/urfu_iml_2023_1_3_hw2/main/mulyavin_aa/PostmanTranslate.png)
93
 
94
  Передаваемые параметры:
95
  ```
@@ -137,3 +139,5 @@ streamlit run run.py
137
  "url": "https://fikiwiki.com/uploads/posts/2022-02/1645000127_53-fikiwiki-com-p-kartinki-krasivie-babochki-narisovannie-55.png"
138
  }
139
  ```
 
 
 
9
  pinned: false
10
  ---
11
 
12
+ [![Tests](https://github.com/kavlab/urfu_iml_2023_1_3_hw2/actions/workflows/python-app.yml/badge.svg)](https://github.com/kavlab/urfu_iml_2023_1_3_hw2/actions/workflows/python-app.yml)
13
+
14
+ # Программная инженерия. Практические задания №2, №3, №4 и №5
15
 
16
  Приложение разработано с использованием фреймворка [Streamlit](https://streamlit.io/).
17
  Состоит из двух страниц и Главной страницы:
 
50
  ### Генератор аудио
51
  Необходимо ввести текст в текстовое поле и нажать кнопку "Генерировать!!!". В результате появится аудио запись на английском языке с описанием введенного текста.
52
 
53
+ ![Результат работы моделей "Генератор аудио / Текст"](https://raw.githubusercontent.com/kavlab/urfu_iml_2023_1_3_hw2/main/mulyavin_aa/screens/audio_gen_image.png)
54
  ![Результат работы моделей "Генератор аудио / Аудио"](https://raw.githubusercontent.com/kavlab/urfu_iml_2023_1_3_hw2/main/kuznetsov_av/text_to_speech_image.png)
55
 
56
  ### Описание изображения
 
67
  #### Пример вызова сервиса Определение языка текста
68
  Вызвать url сервиса ```<host>/langdetector/detect``` методом POST
69
 
70
+ ![img.png](https://raw.githubusercontent.com/kavlab/urfu_iml_2023_1_3_hw2/main/mulyavin_aa/screens/PostmanLangDetect.png)
71
 
72
  Передаваемые параметры:
73
  ```
 
91
  #### Пример вызова сервиса Перевод текста с языка Ru на En
92
  Вызвать url сервиса ```<host>/translator/translate``` методом POST
93
 
94
+ ![img.png](https://raw.githubusercontent.com/kavlab/urfu_iml_2023_1_3_hw2/main/mulyavin_aa/screens/PostmanTranslate.png)
95
 
96
  Передаваемые параметры:
97
  ```
 
139
  "url": "https://fikiwiki.com/uploads/posts/2022-02/1645000127_53-fikiwiki-com-p-kartinki-krasivie-babochki-narisovannie-55.png"
140
  }
141
  ```
142
+
143
+ Тестирует GitHub Actions
kuznetsov_av/test_api.py CHANGED
@@ -1,5 +1,5 @@
1
  from fastapi.testclient import TestClient
2
- from kuznetsov_av.api import Request, Response, app
3
 
4
  client = TestClient(app)
5
 
 
1
  from fastapi.testclient import TestClient
2
+ from kuznetsov_av.api import Request, app
3
 
4
  client = TestClient(app)
5
 
mulyavin_aa/{PostmanLangDetect.png → screens/PostmanLangDetect.png} RENAMED
File without changes
mulyavin_aa/{PostmanTranslate.png → screens/PostmanTranslate.png} RENAMED
File without changes
mulyavin_aa/{audio_gen_image.png → screens/audio_gen_image.png} RENAMED
File without changes
requirements.txt CHANGED
@@ -10,4 +10,5 @@ fastapi==0.104.1
10
  uvicorn==0.24.0
11
  httpx==0.25.2
12
  pillow~=10.1.0
13
- pydantic~=2.5.2
 
 
10
  uvicorn==0.24.0
11
  httpx==0.25.2
12
  pillow~=10.1.0
13
+ pydantic~=2.5.2
14
+ requests~=2.31.0
api.py → run_api.py RENAMED
@@ -1,3 +1,4 @@
 
1
  import uvicorn
2
  from fastapi import FastAPI
3
 
@@ -37,7 +38,7 @@ async def root():
37
  },
38
  {
39
  "descr": "API для описания загруженного изображения",
40
- "base_url": "/get_description_image"
41
  }
42
  ]}
43
 
@@ -75,12 +76,11 @@ async def text_to_speech(entity: Request) -> Response:
75
  @app.post("/get_description_image/predict/")
76
  async def get_description_image_predict(item: develop_api_app.Url):
77
  """
78
- Получение ссылки на изображение. Запись изображения в директорию zvereva_ev
79
- под названием 'image.png для получения его описания
80
  """
81
  response = requests.get(item.url, stream=True)
82
  # сохранение изображения для дальнейшей передачи в модель
83
- with open("image.png", "wb") as f:
84
  f.write(response.content)
85
 
86
  return get_description_image.get_description_image()
 
1
+ import os
2
  import uvicorn
3
  from fastapi import FastAPI
4
 
 
38
  },
39
  {
40
  "descr": "API для описания загруженного изображения",
41
+ "base_url": "/get_description_image/predict/"
42
  }
43
  ]}
44
 
 
76
  @app.post("/get_description_image/predict/")
77
  async def get_description_image_predict(item: develop_api_app.Url):
78
  """
79
+ Получение ссылки на изображение. Запись изображения под названием 'image_predict_test_image.png для получения его описания
 
80
  """
81
  response = requests.get(item.url, stream=True)
82
  # сохранение изображения для дальнейшей передачи в модель
83
+ with open(f"{os.path.dirname(__file__)}/zvereva_ev/image_predict_tmp.png", "wb") as f:
84
  f.write(response.content)
85
 
86
  return get_description_image.get_description_image()
test/test_api.py ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import kuznetsov_av
2
+ from fastapi.testclient import TestClient
3
+ from run_api import app
4
+
5
+ client = TestClient(app)
6
+
7
+
8
+ def test_get_description_image_predict() -> None:
9
+ """
10
+ Тест API Описание загруженного изображения
11
+ """
12
+ from zvereva_ev.develop_api_app import Url
13
+
14
+ response = client.post(
15
+ url="/get_description_image/predict/",
16
+ json=Url(url="https://fikiwiki.com/uploads/posts/2022-02/1645000127_53-"
17
+ "fikiwiki-com-p-kartinki-krasivie-babochki"
18
+ "-narisovannie-55.png"
19
+ ).model_dump())
20
+
21
+ assert response.status_code == 200
22
+ assert response.text == '"Фото бабочки с оранжевыми крыльями и белыми точками"'
23
+
24
+
25
+ def test_langdetector_api_ru() -> None:
26
+ """
27
+ Тест API определения языка текста RU (mulyavin_aa)
28
+ """
29
+ import mulyavin_aa.model.langdetector
30
+
31
+ api_resp = client.post(
32
+ url="/langdetector/detect",
33
+ json=mulyavin_aa.model.langdetector.Request(
34
+ text='Доброго дня всем котам!').model_dump())
35
+
36
+ response = mulyavin_aa.model.langdetector.Response.model_validate_json(api_resp.text)
37
+
38
+ assert api_resp.status_code == 200
39
+ assert len(response.langs) > 0
40
+ assert response.langs[0].label == 'ru'
41
+
42
+
43
+ def test_langdetector_api_en() -> None:
44
+ """
45
+ Тест API определения языка текста EN (mulyavin_aa)
46
+ """
47
+ import mulyavin_aa.model.langdetector
48
+
49
+ api_resp = client.post(
50
+ url="/langdetector/detect",
51
+ json=mulyavin_aa.model.langdetector.Request(
52
+ text='So I checked functions in the class model').model_dump())
53
+
54
+ response = mulyavin_aa.model.langdetector.Response.model_validate_json(api_resp.text)
55
+
56
+ assert api_resp.status_code == 200
57
+ assert len(response.langs) > 0
58
+ assert response.langs[0].label == 'en'
59
+
60
+
61
+ def test_langdetector_api_err() -> None:
62
+ """
63
+ Тест API определения языка текста не Ru и En (mulyavin_aa)
64
+ Модель не ограничена только Ru и En
65
+ """
66
+ import mulyavin_aa.model.langdetector
67
+
68
+ api_resp = client.post(
69
+ url="/langdetector/detect",
70
+ json=mulyavin_aa.model.langdetector.Request(
71
+ text='').model_dump())
72
+
73
+ response = mulyavin_aa.model.langdetector.Response.model_validate_json(api_resp.text)
74
+
75
+ assert api_resp.status_code == 200
76
+ assert len(response.langs) > 0
77
+ assert response.langs[0].label != 'en'
78
+ assert response.langs[0].label != 'ru'
79
+
80
+
81
+ def test_translator_ru_to_en() -> None:
82
+ """
83
+ Тест API Перевод текста с языка Ru на En (mulyavin_aa)
84
+ """
85
+ import mulyavin_aa.model.translator
86
+
87
+ api_resp = client.post(
88
+ url="/translator/translate",
89
+ json=mulyavin_aa.model.translator.Request(
90
+ text='Доброго деня всем котам!').model_dump())
91
+
92
+ response = mulyavin_aa.model.translator.Response.model_validate_json(api_resp.text)
93
+
94
+ assert api_resp.status_code == 200
95
+ assert len(response.text) > 0
96
+ assert response.text == 'Good day to all cats!'
97
+
98
+
99
+ def test_translator_en_to_en() -> None:
100
+ """
101
+ Тест API Перевод текста с языка En на En (mulyavin_aa)
102
+ """
103
+ import mulyavin_aa.model.translator
104
+
105
+ api_resp = client.post(
106
+ url="/translator/translate",
107
+ json=mulyavin_aa.model.translator.Request(
108
+ text='Good day to all cats!').model_dump())
109
+
110
+ response = mulyavin_aa.model.translator.Response.model_validate_json(api_resp.text)
111
+
112
+ assert api_resp.status_code == 200
113
+ assert len(response.text) > 0
114
+ assert response.text == 'Good day to all cats!'
115
+
116
+
117
+ def test_text_to_speech_ok():
118
+ """
119
+ Тест API преобразования текста в речь
120
+ """
121
+ response = client.post(
122
+ url='/text-to-speech/convert/',
123
+ json=kuznetsov_av.api.Request(text='Test').model_dump()
124
+ )
125
+
126
+ assert response.status_code == 200
127
+ assert response.json().get('audio') is not None
128
+ assert type(response.json().get('audio')) == str
129
+ assert len(response.json().get('audio')) > 0
130
+ assert response.json().get('sampling_rate') is not None
131
+ assert type(response.json().get('sampling_rate')) == int
132
+
133
+
134
+ def test_text_to_speech_error422():
135
+ """
136
+ Тест API преобразования текста в речь
137
+ """
138
+ response = client.post(
139
+ url='/text-to-speech/convert/',
140
+ json=''
141
+ )
142
+
143
+ assert response.status_code == 422
144
+
145
+
146
+ def test_root():
147
+ response = client.get('/')
148
+
149
+ assert response.status_code == 200
150
+ assert response.json().get('message') is not None
151
+ assert len(response.json().get('message')) > 0
zvereva_ev/get_description_image.py CHANGED
@@ -20,7 +20,7 @@ def load_image():
20
  st.image(image_data)
21
  image_data_open = Image.open(io.BytesIO(image_data))
22
  # Сохранение изображения из буффера
23
- image_data_open.save("image.png")
24
  return image_data_open
25
  else:
26
  return None
@@ -39,7 +39,7 @@ def get_description_image():
39
  """
40
  processor, model = load_models()
41
 
42
- raw_image = Image.open("image.png")
43
 
44
  text = "a photography of"
45
  inputs = processor(raw_image, text, return_tensors="pt")
@@ -53,7 +53,7 @@ def get_description_image():
53
 
54
 
55
  # Получение полного пути к сохраненному изображению из буффера
56
- file_path = "urfu_iml_2023_1_3_hw2/zvereva_ev/image.png"
57
  absolute_path = os.path.abspath(file_path)
58
 
59
 
@@ -71,7 +71,7 @@ def run_():
71
  st.warning("Загрузите изображение, чтобы получить описание", icon="🚀")
72
  else:
73
  exit()
74
- if "image.png" in absolute_path:
75
- os.remove("image.png")
76
  except FileNotFoundError:
77
  return "Изображение не загружено"
 
20
  st.image(image_data)
21
  image_data_open = Image.open(io.BytesIO(image_data))
22
  # Сохранение изображения из буффера
23
+ image_data_open.save(f"{os.path.dirname(__file__)}/image_predict_tmp.png")
24
  return image_data_open
25
  else:
26
  return None
 
39
  """
40
  processor, model = load_models()
41
 
42
+ raw_image = Image.open(f"{os.path.dirname(__file__)}/image_predict_tmp.png")
43
 
44
  text = "a photography of"
45
  inputs = processor(raw_image, text, return_tensors="pt")
 
53
 
54
 
55
  # Получение полного пути к сохраненному изображению из буффера
56
+ file_path = f"{os.path.dirname(__file__)}/image_predict_tmp.png"
57
  absolute_path = os.path.abspath(file_path)
58
 
59
 
 
71
  st.warning("Загрузите изображение, чтобы получить описание", icon="🚀")
72
  else:
73
  exit()
74
+ if f"{os.path.dirname(__file__)}/image_predict_tmp.png" in absolute_path:
75
+ os.remove(f"{os.path.dirname(__file__)}/image_predict_tmp.png")
76
  except FileNotFoundError:
77
  return "Изображение не загружено"