shikibu9419 commited on
Commit
0380f70
·
1 Parent(s): 833d26b

Use FastAPI instead of Flask

Browse files
Files changed (2) hide show
  1. app.py +100 -83
  2. requirements.txt +1 -0
app.py CHANGED
@@ -1,6 +1,8 @@
1
  # from flask import Flask, request, jsonify, render_template, make_response
2
  # from flask_cors import CORS
3
- from fastapi import FastAPI
 
 
4
  import numpy as np
5
  import cv2
6
 
@@ -10,6 +12,11 @@ from src.prediction import predict_img, optimize_img, update_patch
10
  from src.utils import cv_to_pil, pil_to_cv
11
 
12
  app = FastAPI()
 
 
 
 
 
13
 
14
  # UPLOAD_FOLDER = './uploads'
15
  # app = Flask(__name__, template_folder='/client', static_folder='/client')
@@ -21,90 +28,100 @@ app = FastAPI()
21
  # supports_credentials=True
22
  # )
23
 
 
24
  @app.get("/api/health_check")
25
  def read_root():
26
  return {"status": "ok"}
27
 
28
 
29
- # @app.route('/api/process', methods=['POST'])
30
- # def process():
31
- # imgfile = request.files['img']
32
- # img_array = np.asarray(bytearray(imgfile.stream.read()), dtype=np.uint8)
33
- # img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
34
- #
35
- # data = request.form
36
- # hue = int(data["hue"])
37
- # saturation = float(data["saturation"])
38
- # lightness = float(data["lightness"])
39
- # contrast = int(data["contrast"])
40
- # kelvin = int(data["kelvin"])
41
- #
42
- # img = control_contrast(img, contrast)
43
- # img = control_HSV(img, hue, saturation, lightness)
44
- #
45
- # img_pil = cv_to_pil(img)
46
- # img_pil = control_kelvin(img_pil, kelvin)
47
- # img = pil_to_cv(img_pil)
48
- #
49
- # response = make_response(cv2.imencode('.png', img)[1].tobytes())
50
- # response.headers.set('Content-Type', 'image/png')
51
- #
52
- # return response
53
- #
54
- #
55
- # @app.route('/api/predict/<process_name>', methods=['POST'])
56
- # def predict(process_name):
57
- # if not process_name in ['cyanotype_mono', 'cyanotype_full', 'salt', 'platinum']:
58
- # return jsonify({ 'error': 'process name is invalid' })
59
- #
60
- # imgfile = request.files['img']
61
- # img_array = np.asarray(bytearray(imgfile.stream.read()), dtype=np.uint8)
62
- # img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
63
- #
64
- # # if 'colorpatch' in request.files:
65
- # # patchfile = request.files['colorpatch']
66
- # # patch_array = np.asarray(bytearray(patchfile.stream.read()), dtype=np.uint8)
67
- # # colorpatch = cv2.imdecode(colorpatch_array, cv2.IMREAD_COLOR)
68
- # # update_patch(process_name, colorpatch)
69
- #
70
- # img = predict_img(process_name, img)
71
- #
72
- # response = make_response(cv2.imencode('.png', img)[1].tobytes())
73
- # response.headers.set('Content-Type', 'image/png')
74
- #
75
- # return response
76
- #
77
- #
78
- # @app.route('/api/optimize/<process_name>', methods=['POST'])
79
- # def optimize(process_name):
80
- # if not process_name in ['cyanotype_mono', 'cyanotype_full', 'salt', 'platinum']:
81
- # return jsonify({ 'error': 'process name is invalid' })
82
- #
83
- # imgfile = request.files['img']
84
- # img_array = np.asarray(bytearray(imgfile.stream.read()), dtype=np.uint8)
85
- # img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
86
- #
87
- # # if 'colorpatch' in request.files:
88
- # # patchfile = request.files['colorpatch']
89
- # # patch_array = np.asarray(bytearray(patchfile.stream.read()), dtype=np.uint8)
90
- # # colorpatch = cv2.imdecode(colorpatch_array, cv2.IMREAD_COLOR)
91
- # # update_patch(process_name, colorpatch)
92
- #
93
- # (opt_img, preview_img) = optimize_img(process_name, img)
94
- #
95
- # h, w = preview_img.shape[:2]
96
- # if process_name.endswith('full'):
97
- # opt_img = np.reshape(opt_img, (h, w, 3))
98
- # else:
99
- # opt_img = np.reshape(opt_img, (h, w, 1))
100
- # opt_img = np.array([[[i[0]] * 3 for i in j] for j in opt_img], dtype=np.uint8)
101
- #
102
- # img = cv2.hconcat([opt_img, preview_img])
103
- # response = make_response(cv2.imencode('.png', img)[1].tobytes())
104
- # response.headers.set('Content-Type', 'image/png')
105
- #
106
- # return response
107
- #
108
- #
109
- # if __name__ == "__main__":
110
- # app.run(debug=True, host="0.0.0.0", port=8000)
 
 
 
 
 
 
 
 
 
 
1
  # from flask import Flask, request, jsonify, render_template, make_response
2
  # from flask_cors import CORS
3
+ import uvicorn
4
+ import logging
5
+ from fastapi import FastAPI, File, UploadFile, Form, Response
6
  import numpy as np
7
  import cv2
8
 
 
12
  from src.utils import cv_to_pil, pil_to_cv
13
 
14
  app = FastAPI()
15
+ logger = logging.getLogger('uvicorn')
16
+
17
+
18
+ def to_byte_response(img):
19
+ return cv2.imencode('.png', img)[1].tobytes()
20
 
21
  # UPLOAD_FOLDER = './uploads'
22
  # app = Flask(__name__, template_folder='/client', static_folder='/client')
 
28
  # supports_credentials=True
29
  # )
30
 
31
+
32
  @app.get("/api/health_check")
33
  def read_root():
34
  return {"status": "ok"}
35
 
36
 
37
+ @app.post('/api/process')
38
+ async def process(
39
+ hue: str = Form(...),
40
+ saturation: str = Form(...),
41
+ lightness: str = Form(...),
42
+ contrast: str = Form(...),
43
+ kelvin: str = Form(...),
44
+ img: UploadFile = File(...)
45
+ ):
46
+ # logger.info(img)
47
+ # imgfile = request.files['img']
48
+ # img_array = np.asarray(bytearray(imgfile.stream.read()), dtype=np.uint8)
49
+ img_array = np.frombuffer(await img.read(), dtype=np.uint8)
50
+ img_array = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
51
+
52
+ logger.info(img)
53
+ logger.info(img_array)
54
+ logger.info(img_array.shape)
55
+
56
+ # data = request.form
57
+ hue_int = int(hue)
58
+ saturation_int = float(saturation)
59
+ lightness_int = float(lightness)
60
+ contrast_int = int(contrast)
61
+ kelvin_int = int(kelvin)
62
+
63
+ img_array = control_contrast(img_array, contrast_int)
64
+ img_array = control_HSV(img_array, hue_int, saturation_int, lightness_int)
65
+
66
+ img_pil = cv_to_pil(img_array)
67
+ img_pil = control_kelvin(img_pil, kelvin_int)
68
+ processed_img = pil_to_cv(img_pil)
69
+
70
+ return Response(content=to_byte_response(processed_img), media_type="image/png")
71
+
72
+
73
+ @app.post('/api/predict/{process_name}')
74
+ async def predict(
75
+ process_name: str,
76
+ img: UploadFile = File(...)
77
+ ):
78
+ if not process_name in ['cyanotype_mono', 'cyanotype_full', 'salt', 'platinum']:
79
+ return { 'error': 'process name is invalid' }
80
+
81
+ img_array = np.frombuffer(await img.read(), dtype=np.uint8)
82
+ img_array = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
83
+
84
+ # if 'colorpatch' in request.files:
85
+ # patchfile = request.files['colorpatch']
86
+ # patch_array = np.asarray(bytearray(patchfile.stream.read()), dtype=np.uint8)
87
+ # colorpatch = cv2.imdecode(colorpatch_array, cv2.IMREAD_COLOR)
88
+ # update_patch(process_name, colorpatch)
89
+
90
+ predicted_img = predict_img(process_name, img_array)
91
+
92
+ return Response(content=to_byte_response(predicted_img), media_type="image/png")
93
+
94
+
95
+ @app.post('/api/optimize/{process_name}')
96
+ async def optimize(
97
+ process_name: str,
98
+ img: UploadFile = File(...)
99
+ ):
100
+ if not process_name in ['cyanotype_mono', 'cyanotype_full', 'salt', 'platinum']:
101
+ return { 'error': 'process name is invalid' }
102
+
103
+ img_array = np.frombuffer(await img.read(), dtype=np.uint8)
104
+ img_array = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
105
+
106
+ # if 'colorpatch' in request.files:
107
+ # patchfile = request.files['colorpatch']
108
+ # patch_array = np.asarray(bytearray(patchfile.stream.read()), dtype=np.uint8)
109
+ # colorpatch = cv2.imdecode(colorpatch_array, cv2.IMREAD_COLOR)
110
+ # update_patch(process_name, colorpatch)
111
+
112
+ (opt_img, preview_img) = optimize_img(process_name, img_array)
113
+
114
+ h, w = preview_img.shape[:2]
115
+ if process_name.endswith('full'):
116
+ opt_img = np.reshape(opt_img, (h, w, 3))
117
+ else:
118
+ opt_img = np.reshape(opt_img, (h, w, 1))
119
+ opt_img = np.array([[[i[0]] * 3 for i in j] for j in opt_img], dtype=np.uint8)
120
+
121
+ optimized_img = cv2.hconcat([opt_img, preview_img])
122
+
123
+ return Response(content=to_byte_response(optimized_img), media_type="image/png")
124
+
125
+
126
+ if __name__ == "__main__":
127
+ uvicorn.run(app, host="0.0.0.0", port=8000)
requirements.txt CHANGED
@@ -1,6 +1,7 @@
1
  -i https://pypi.org/simple
2
  fastapi==0.74.*
3
  uvicorn[standard]==0.17.*
 
4
  absl-py==1.2.0; python_version >= '3.6'
5
  astunparse==1.6.3
6
  cachetools==5.2.0; python_version ~= '3.7'
 
1
  -i https://pypi.org/simple
2
  fastapi==0.74.*
3
  uvicorn[standard]==0.17.*
4
+ python-multipart
5
  absl-py==1.2.0; python_version >= '3.6'
6
  astunparse==1.6.3
7
  cachetools==5.2.0; python_version ~= '3.7'