playmak3r commited on
Commit
20f16a7
·
1 Parent(s): 85262ec

feat: add separated route for handling batch translations

Browse files
Files changed (3) hide show
  1. server/app.py +53 -16
  2. src/Home/index.tsx +1 -1
  3. test.sh +5 -0
server/app.py CHANGED
@@ -1,38 +1,56 @@
1
  from threading import Thread
2
- import redis, time
3
  from flask import Flask, jsonify, send_from_directory, Response, request
4
  from waitress import serve
5
  from flask_cors import CORS, cross_origin
6
  from model import SugoiTranslator
7
- from typing import List
 
 
8
 
9
 
10
  queue_key = "translation_queue"
11
  translated_key = "translated_temp_store"
12
  redis_client = redis.Redis(host='localhost', port=6379, db=0)
 
 
 
 
 
13
 
14
  def queue_process():
15
  while True:
16
  task_list = []
17
  for _ in range(5):
18
- task = redis_client.rpop(queue_key) # right pop
19
- if task: task_list.append(task)
20
- else: break
 
 
 
 
21
 
22
  if len(task_list): task_process(task_list)
23
  time.sleep(0.2)
24
 
25
- def task_process(input_text_list: List[str]):
 
 
 
 
 
26
  sugoiTranslator = SugoiTranslator()
27
  translations = sugoiTranslator.translate(input_text_list)
 
 
28
  for index, translation in enumerate(translations):
29
- redis_client.hset(translated_key, input_text_list[index], translation)
30
 
31
- def query_translation(input_text: str):
32
  for _ in range(30):
33
- translated_text = redis_client.hget(translated_key, input_text)
34
  if translated_text is not None:
35
- redis_client.hdel(translated_key, input_text)
36
  try: return translated_text.decode('utf-8')
37
  except AttributeError: return translated_text
38
  time.sleep(1)
@@ -55,23 +73,42 @@ def download_file(filename):
55
  def download_assets(filename):
56
  return send_from_directory('dist/assets', filename)
57
 
58
- @app.route('/api/translate', methods= ['POST'])
59
  @cross_origin()
60
- def translate_api():
61
  input_text = request.args.get('text')
62
  if isinstance(input_text, str) and len(input_text) > 0:
63
- redis_client.lpush(queue_key, input_text) # left push
64
- result = query_translation(input_text)
 
 
 
 
65
  if result is not None: return jsonify({ "text": result })
66
  else: return Response(status= 529, response= "Error 529: Server overloaded")
67
  return Response(status= 400)
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  if __name__ == '__main__':
71
  Thread(target=queue_process, daemon=True).start()
72
- print("Starting server...")
73
  try: serve(app, port= 7860)
74
  except BaseException as e:
75
- print(e)
76
 
77
 
 
1
  from threading import Thread
2
+ import redis, time, logging, sys, ast
3
  from flask import Flask, jsonify, send_from_directory, Response, request
4
  from waitress import serve
5
  from flask_cors import CORS, cross_origin
6
  from model import SugoiTranslator
7
+ import uuid, json
8
+ from typing import List, Dict, Any, Union
9
+
10
 
11
 
12
  queue_key = "translation_queue"
13
  translated_key = "translated_temp_store"
14
  redis_client = redis.Redis(host='localhost', port=6379, db=0)
15
+ logging.basicConfig(
16
+ level=logging.INFO,
17
+ format="%(asctime)s [%(levelname)s] %(message)s",
18
+ stream=sys.stdout
19
+ )
20
 
21
  def queue_process():
22
  while True:
23
  task_list = []
24
  for _ in range(5):
25
+ json_string = redis_client.rpop(queue_key) # right pop
26
+ if isinstance(json_string, (bytes, bytearray)):
27
+ task: Dict[str, Any] = json.loads(json_string.decode("utf-8"))
28
+ if isinstance(task["input"], list): task_process([ task ])
29
+ elif isinstance(task["input"], str): task_list.append(task)
30
+ elif task is not None: logging.info(task)
31
+ elif json_string is not None: logging.info(json_string)
32
 
33
  if len(task_list): task_process(task_list)
34
  time.sleep(0.2)
35
 
36
+ def task_process(task: List[Dict[str, Any]]):
37
+ logging.info(f"translating: {task}")
38
+ input_text_list: List[str] = (
39
+ task[0]["input"] if len(task)==1 and isinstance(task[0]["input"], list)
40
+ else list(map(lambda item: item["input"], task))
41
+ )
42
  sugoiTranslator = SugoiTranslator()
43
  translations = sugoiTranslator.translate(input_text_list)
44
+ if len(task)==1 and isinstance(task[0]["input"], list):
45
+ return redis_client.hset(translated_key, task[0]["id"], str(translations))
46
  for index, translation in enumerate(translations):
47
+ redis_client.hset(translated_key, task[index]["id"], translation)
48
 
49
+ def query_translation(key: str) -> Union[str, None]:
50
  for _ in range(30):
51
+ translated_text = redis_client.hget(translated_key, key)
52
  if translated_text is not None:
53
+ redis_client.hdel(translated_key, key)
54
  try: return translated_text.decode('utf-8')
55
  except AttributeError: return translated_text
56
  time.sleep(1)
 
73
  def download_assets(filename):
74
  return send_from_directory('dist/assets', filename)
75
 
76
+ @app.route('/api/translate', methods= ["GET"])
77
  @cross_origin()
78
+ def translate_get():
79
  input_text = request.args.get('text')
80
  if isinstance(input_text, str) and len(input_text) > 0:
81
+ task_id = str(uuid.uuid4())
82
+ redis_client.lpush(queue_key, json.dumps({
83
+ "id": task_id,
84
+ "input": input_text
85
+ })) # left push
86
+ result = query_translation(task_id)
87
  if result is not None: return jsonify({ "text": result })
88
  else: return Response(status= 529, response= "Error 529: Server overloaded")
89
  return Response(status= 400)
90
 
91
+ @app.route('/api/translate', methods= ["POST"])
92
+ @cross_origin()
93
+ def translate_post():
94
+ input_texts = request.get_json().get("input_texts")
95
+ if isinstance(input_texts, list) and len(input_texts):
96
+ task_id = str(uuid.uuid4())
97
+ redis_client.lpush(queue_key, json.dumps({
98
+ "id": task_id,
99
+ "input": input_texts
100
+ })) # left push
101
+ result = query_translation(task_id)
102
+ if result is not None: return jsonify({ "translations": ast.literal_eval(result) })
103
+ else: return Response(status= 529, response= "Error 529: Server overloaded")
104
+ return Response(status= 400)
105
+
106
 
107
  if __name__ == '__main__':
108
  Thread(target=queue_process, daemon=True).start()
109
+ logging.info("Starting server...")
110
  try: serve(app, port= 7860)
111
  except BaseException as e:
112
+ logging.info(e)
113
 
114
 
src/Home/index.tsx CHANGED
@@ -22,7 +22,7 @@ export default function App() {
22
  const { text } = input
23
  if (!text || translation.loading) { return null }
24
  if (translation()) { mutate(null) }
25
- const response = await fetch(`/api/translate?text=${text}`, { method: "POST" })
26
  .then(response => response.status===200? response.json() : response.text())
27
  .then(response => response?.text ?? response)
28
  .catch(() => null)
 
22
  const { text } = input
23
  if (!text || translation.loading) { return null }
24
  if (translation()) { mutate(null) }
25
+ const response = await fetch(`/api/translate?text=${text}`)
26
  .then(response => response.status===200? response.json() : response.text())
27
  .then(response => response?.text ?? response)
28
  .catch(() => null)
test.sh ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ docker stop $(docker ps -q)
2
+ docker container prune #-f
3
+ docker image prune -a
4
+ docker build -t sugoi-v4:1.0 .
5
+ docker run -p 7860:7860 sugoi-v4:1.0