kerenmasku commited on
Commit
2ef3683
·
verified ·
1 Parent(s): 7b6a76d

Update api.py

Browse files
Files changed (1) hide show
  1. api.py +91 -100
api.py CHANGED
@@ -1,111 +1,102 @@
1
  from flask import Flask, request, jsonify
2
- import traceback
3
- from android import AndroidEditor
4
- from iphone import IPhoneEditor
5
- from all import UnifiedEditor
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  app = Flask(__name__)
8
 
9
- ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
10
-
11
- def allowed_file(filename):
12
- return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
13
-
14
- @app.route('/')
15
- def index():
16
- """
17
- Endpoint utama yang menampilkan pesan selamat datang
18
- """
19
- return "Kelas Kink"
20
-
21
- @app.route('/unified', methods=['POST'])
22
- def process_unified_image():
23
- """
24
- Endpoint untuk memproses gambar dari Unified
25
- """
26
- app.logger.info('Menerima permintaan POST untuk memproses gambar')
27
- anggota = request.form.get('anggota')
28
- image_file = request.files.get('file')
29
-
30
- if not anggota or not image_file:
31
- return jsonify({'status': 'failed', 'message': 'Parameter anggota dan file diperlukan'}), 400
32
-
33
  try:
34
- file_bytes = image_file.read()
35
- editor = UnifiedEditor()
36
- img_b64, theme, platform = editor.process_image_bytes(file_bytes, anggota)
37
- if img_b64 is None:
38
- return jsonify({'status': 'failed', 'message': 'Gagal memproses gambar'}), 500
39
- return jsonify({'status': 'success', 'theme': theme, 'mode': platform, 'image': img_b64})
40
  except Exception as e:
41
- error_message = str(e)
42
- error_traceback = traceback.format_exc()
43
- print("Error occurred:", error_traceback)
44
- return jsonify({'status': 'failed', 'message': error_message, 'traceback': error_traceback}), 500
45
-
46
- @app.route('/android', methods=['POST'])
47
- def process_android_image():
48
- """
49
- Endpoint untuk memproses gambar dari Android
50
-
51
- Parameters:
52
- - anggota: Nama anggota (form data)
53
- - file: File gambar (form data)
54
-
55
- Returns:
56
- - JSON response dengan status, theme, dan gambar yang diproses
57
- """
58
- app.logger.info('Menerima permintaan POST untuk memproses gambar')
59
- anggota = request.form.get('anggota')
60
- image_file = request.files.get('file')
61
-
62
- if not anggota or not image_file:
63
- return jsonify({'status': 'failed', 'message': 'Parameter anggota dan file diperlukan'}), 400
64
-
65
  try:
66
- file_bytes = image_file.read()
67
- editor = AndroidEditor()
68
- img_b64, theme = editor.process_image_bytes(file_bytes, anggota)
69
- if img_b64 is None:
70
- return jsonify({'status': 'failed', 'message': 'Gagal memproses gambar'}), 500
71
- return jsonify({'status': 'success', 'theme': theme, 'image': img_b64})
72
- except Exception as e:
73
- error_message = str(e)
74
- error_traceback = traceback.format_exc()
75
- print("Error occurred:", error_traceback)
76
- return jsonify({'status': 'failed', 'message': error_message, 'traceback': error_traceback}), 500
77
-
78
- @app.route('/iphone', methods=['POST'])
79
- def process_iphone_image():
80
- """
81
- Endpoint untuk memproses gambar dari iPhone
82
-
83
- Parameters:
84
- - anggota: Nama anggota (form data)
85
- - file: File gambar (form data)
86
-
87
- Returns:
88
- - JSON response dengan status, theme, dan gambar yang diproses
89
- """
90
- app.logger.info('Menerima permintaan POST untuk memproses gambar')
91
- anggota = request.form.get('anggota')
92
- image_file = request.files.get('file')
93
-
94
- if not anggota or not image_file:
95
- return jsonify({'status': 'failed', 'message': 'Parameter anggota dan file diperlukan'}), 400
96
 
97
- try:
98
- file_bytes = image_file.read()
99
- editor = IPhoneEditor()
100
- img_b64, theme = editor.process_image_bytes(file_bytes, anggota)
101
- if img_b64 is None:
102
- return jsonify({'status': 'failed', 'message': 'Gagal memproses gambar'}), 500
103
- return jsonify({'status': 'success', 'theme': theme, 'image': img_b64})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  except Exception as e:
105
- error_message = str(e)
106
- error_traceback = traceback.format_exc()
107
- print("Error occurred:", error_traceback)
108
- return jsonify({'status': 'failed', 'message': error_message, 'traceback': error_traceback}), 500
 
 
 
 
 
 
 
 
 
 
109
 
110
  if __name__ == '__main__':
111
- app.run(port=7860, debug=True, host='0.0.0.0')
 
 
 
 
 
 
 
 
1
  from flask import Flask, request, jsonify
2
+ from ocr import OcrPriceExtractor
3
+ import io
4
+ from gevent.pywsgi import WSGIServer
5
+ from gevent import monkey
6
+ import multiprocessing
7
+ from concurrent.futures import ThreadPoolExecutor
8
+ import logging
9
+ import os
10
+
11
+ # Patch all for gevent
12
+ monkey.patch_all()
13
+
14
+ # Setup logging
15
+ logging.basicConfig(level=logging.INFO)
16
+ logger = logging.getLogger(__name__)
17
 
18
  app = Flask(__name__)
19
 
20
+ # Thread pool untuk OCR processing
21
+ ocr_pool = ThreadPoolExecutor(max_workers=multiprocessing.cpu_count())
22
+ ocr = OcrPriceExtractor()
23
+
24
+ # ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'bmp'}
25
+
26
+ # def allowed_file(filename):
27
+ # return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
28
+
29
+ def process_ocr_task(bytes_io):
30
+ """Process OCR in a separate thread"""
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  try:
32
+ text, prices = ocr.extract_text(bytes_io)
33
+ return text, prices
 
 
 
 
34
  except Exception as e:
35
+ logger.error(f"OCR processing error: {str(e)}")
36
+ return None, None
37
+
38
+ @app.route('/ocr', methods=['POST'])
39
+ def process_image():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  try:
41
+ if 'image' not in request.files:
42
+ return jsonify({
43
+ 'success': False,
44
+ 'error': 'No image file provided'
45
+ }), 400
46
+
47
+ file = request.files['image']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ if file.filename == '':
50
+ return jsonify({
51
+ 'success': False,
52
+ 'error': 'No selected file'
53
+ }), 400
54
+
55
+ # Read file to BytesIO
56
+ bytes_io = io.BytesIO(file.read())
57
+
58
+ # Submit OCR task to thread pool
59
+ future = ocr_pool.submit(process_ocr_task, bytes_io)
60
+ text, prices = future.result(timeout=30) # 30 seconds timeout
61
+
62
+ if text is None:
63
+ return jsonify({
64
+ 'success': False,
65
+ 'error': 'Failed to process image'
66
+ }), 500
67
+
68
+ response = {
69
+ 'success': True,
70
+ 'data': {
71
+ 'text': text,
72
+ 'prices': prices
73
+ }
74
+ }
75
+
76
+ return jsonify(response)
77
+
78
  except Exception as e:
79
+ logger.error(f"API error: {str(e)}")
80
+ return jsonify({
81
+ 'success': False,
82
+ 'error': str(e)
83
+ }), 500
84
+
85
+ @app.route('/health', methods=['GET'])
86
+ def health_check():
87
+ return jsonify({
88
+ 'status': 'healthy',
89
+ 'service': 'ocr-api',
90
+ 'workers': ocr_pool._max_workers,
91
+ 'active_threads': len(ocr_pool._threads)
92
+ })
93
 
94
  if __name__ == '__main__':
95
+ # Development mode
96
+ if os.environ.get('FLASK_ENV') == 'development':
97
+ app.run(host='0.0.0.0', port=5000, debug=True)
98
+ else:
99
+ # Production mode with gevent
100
+ logger.info(f"Starting server with {ocr_pool._max_workers} workers")
101
+ http_server = WSGIServer(('0.0.0.0', 5000), app)
102
+ http_server.serve_forever()