fashxp commited on
Commit
7bac21a
·
1 Parent(s): fef773e

additional tasks

Browse files
src/classification.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ from pydantic import BaseModel
3
+ import logging
4
+ from fastapi import Request, HTTPException
5
+ import json
6
+ from typing import Optional
7
+
8
+
9
+ class ClassificationRequest(BaseModel):
10
+ inputs: str
11
+ parameters: Optional[dict] = None
12
+
13
+ class ClassificationTaskService:
14
+
15
+ __logger: logging.Logger
16
+ __task_name: str
17
+
18
+ def __init__(self, logger: logging.Logger, task_name: str):
19
+ self.__logger = logger
20
+ self.__task_name = task_name
21
+
22
+ async def get_classification_request(
23
+ self,
24
+ request: Request
25
+ ) -> ClassificationRequest:
26
+ content_type = request.headers.get("content-type", "")
27
+ if content_type.startswith("application/json"):
28
+ data = await request.json()
29
+ return ClassificationRequest(**data)
30
+ if content_type.startswith("application/x-www-form-urlencoded"):
31
+ raw = await request.body()
32
+ try:
33
+ data = json.loads(raw)
34
+ return ClassificationRequest(**data)
35
+ except Exception:
36
+ try:
37
+ data = json.loads(raw.decode("utf-8"))
38
+ return ClassificationRequest(**data)
39
+ except Exception:
40
+ raise HTTPException(status_code=400, detail="Invalid request body")
41
+ raise HTTPException(status_code=400, detail="Unsupported content type")
42
+
43
+
44
+ async def classify(
45
+ self,
46
+ request: Request,
47
+ model_name: str
48
+ ):
49
+
50
+ classificationRequest: ClassificationRequest = await self.get_classification_request(request)
51
+
52
+ try:
53
+ pipe = pipeline(self.__task_name, model=model_name)
54
+ except Exception as e:
55
+ self.__logger.error(f"Failed to load model '{model_name}': {str(e)}")
56
+ raise HTTPException(
57
+ status_code=404,
58
+ detail=f"Model '{model_name}' could not be loaded: {str(e)}"
59
+ )
60
+
61
+ try:
62
+
63
+ if self.__task_name == "zero-shot-image-classification" or self.__task_name == "zero-shot-classification":
64
+ candidate_labels = []
65
+
66
+ if classificationRequest.parameters:
67
+ candidate_labels = classificationRequest.parameters.get('candidate_labels', [])
68
+ if isinstance(candidate_labels, str):
69
+ candidate_labels = [label.strip() for label in candidate_labels.split(',')]
70
+ result = pipe(classificationRequest.inputs, candidate_labels=candidate_labels)
71
+
72
+ else: # pretrained classification
73
+ result = pipe(classificationRequest.inputs)
74
+
75
+ except Exception as e:
76
+ self.__logger.error(f"Inference failed for model '{model_name}': {str(e)}")
77
+ raise HTTPException(
78
+ status_code=500,
79
+ detail=f"Inference failed: {str(e)}"
80
+ )
81
+
82
+ return result
src/image_classification.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ from pydantic import BaseModel
3
+ import logging
4
+ from fastapi import Request, HTTPException
5
+ import json
6
+ from typing import Optional
7
+
8
+
9
+ class ImageClassificationRequest(BaseModel):
10
+ inputs: str
11
+ parameters: Optional[dict] = None
12
+
13
+ class ImageClassificationTaskService:
14
+
15
+ __logger: logging.Logger
16
+ __task_name: str
17
+
18
+ def __init__(self, logger: logging.Logger, task_name: str = "image-classification"):
19
+ self.__logger = logger
20
+ self.__task_name = task_name
21
+
22
+ async def get_image_classification_request(
23
+ self,
24
+ request: Request
25
+ ) -> ImageClassificationRequest:
26
+ content_type = request.headers.get("content-type", "")
27
+ if content_type.startswith("application/json"):
28
+ data = await request.json()
29
+ return ImageClassificationRequest(**data)
30
+ if content_type.startswith("application/x-www-form-urlencoded"):
31
+ raw = await request.body()
32
+ try:
33
+ data = json.loads(raw)
34
+ return ImageClassificationRequest(**data)
35
+ except Exception:
36
+ try:
37
+ data = json.loads(raw.decode("utf-8"))
38
+ return ImageClassificationRequest(**data)
39
+ except Exception:
40
+ raise HTTPException(status_code=400, detail="Invalid request body")
41
+ raise HTTPException(status_code=400, detail="Unsupported content type")
42
+
43
+
44
+ async def classify(
45
+ self,
46
+ request: Request,
47
+ model_name: str
48
+ ):
49
+
50
+ imageRequest: ImageClassificationRequest = await self.get_image_classification_request(request)
51
+
52
+ try:
53
+ pipe = pipeline(self.__task_name, model=model_name)
54
+ except Exception as e:
55
+ self.__logger.error(f"Failed to load model '{model_name}': {str(e)}")
56
+ raise HTTPException(
57
+ status_code=404,
58
+ detail=f"Model '{model_name}' could not be loaded: {str(e)}"
59
+ )
60
+
61
+ try:
62
+
63
+ if self.__task_name == "zero-shot-image-classification":
64
+ candidate_labels = []
65
+
66
+ if imageRequest.parameters:
67
+ candidate_labels = imageRequest.parameters.get('candidate_labels', [])
68
+ if isinstance(candidate_labels, str):
69
+ candidate_labels = [label.strip() for label in candidate_labels.split(',')]
70
+ result = pipe(imageRequest.inputs, candidate_labels=candidate_labels)
71
+
72
+ else: # image classification
73
+ result = pipe(imageRequest.inputs)
74
+
75
+ except Exception as e:
76
+ self.__logger.error(f"Inference failed for model '{model_name}': {str(e)}")
77
+ raise HTTPException(
78
+ status_code=500,
79
+ detail=f"Inference failed: {str(e)}"
80
+ )
81
+
82
+ return result
src/main.py CHANGED
@@ -8,21 +8,15 @@
8
  # @license Pimcore Open Core License (POCL)
9
  # -------------------------------------------------------------------
10
 
11
- import os
12
  import torch
13
 
14
- from fastapi import FastAPI, Path, Depends, HTTPException, UploadFile, Form, File, status, Request
15
- from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
16
- from pydantic import BaseModel
17
- from typing import Annotated
18
- import json
19
-
20
  import logging
21
  import sys
22
- import base64
23
-
24
 
25
- from transformers import pipeline
 
 
26
 
27
  app = FastAPI(
28
  title="Pimcore Local Inference Service",
@@ -51,14 +45,6 @@ class StreamToLogger(object):
51
  sys.stdout = StreamToLogger(logger, logging.INFO)
52
  sys.stderr = StreamToLogger(logger, logging.ERROR)
53
 
54
-
55
-
56
- class ResponseModel(BaseModel):
57
- """ Default response model for endpoints. """
58
- message: str
59
- success: bool = True
60
-
61
-
62
  @app.get("/gpu_check")
63
  async def gpu_check():
64
  """ Check if a GPU is available """
@@ -73,41 +59,9 @@ async def gpu_check():
73
  return {'success': True, 'gpu': gpu}
74
 
75
 
76
- from typing import Optional
77
-
78
-
79
-
80
  # =========================
81
  # Translation Task
82
  # =========================
83
-
84
- class TranslationRequest(BaseModel):
85
- inputs: str
86
- parameters: Optional[dict] = None
87
- options: Optional[dict] = None
88
-
89
- async def get_translation_request(
90
- request: Request
91
- ) -> TranslationRequest:
92
- content_type = request.headers.get("content-type", "")
93
- if content_type.startswith("application/json"):
94
- data = await request.json()
95
- return TranslationRequest(**data)
96
- if content_type.startswith("application/x-www-form-urlencoded"):
97
- raw = await request.body()
98
- try:
99
- data = json.loads(raw)
100
- return TranslationRequest(**data)
101
- except Exception:
102
- try:
103
- data = json.loads(raw.decode("utf-8"))
104
- return TranslationRequest(**data)
105
- except Exception:
106
- raise HTTPException(status_code=400, detail="Invalid request body")
107
- raise HTTPException(status_code=400, detail="Unsupported content type")
108
-
109
-
110
-
111
  @app.post(
112
  "/translation/{model_name:path}/",
113
  openapi_extra={
@@ -138,60 +92,13 @@ async def translate(
138
  list: The translation result(s) as returned by the pipeline.
139
  """
140
 
141
- translationRequest: TranslationRequest = await get_translation_request(request)
142
-
143
- try:
144
- pipe = pipeline("translation", model=model_name)
145
- except Exception as e:
146
- logger.error(f"Failed to load model '{model_name}': {str(e)}")
147
- raise HTTPException(
148
- status_code=404,
149
- detail=f"Model '{model_name}' could not be loaded: {str(e)}"
150
- )
151
-
152
- try:
153
- result = pipe(translationRequest.inputs, **(translationRequest.parameters or {}))
154
- except Exception as e:
155
- logger.error(f"Inference failed for model '{model_name}': {str(e)}")
156
- raise HTTPException(
157
- status_code=500,
158
- detail=f"Inference failed: {str(e)}"
159
- )
160
-
161
- return result
162
 
163
 
164
  # =========================
165
  # Zero-Shot Image Classification Task
166
  # =========================
167
-
168
-
169
- class ZeroShotImageClassificationRequest(BaseModel):
170
- inputs: str
171
- parameters: Optional[dict] = None
172
-
173
- async def get_zero_shot_image_classification_request(
174
- request: Request
175
- ) -> ZeroShotImageClassificationRequest:
176
- content_type = request.headers.get("content-type", "")
177
- if content_type.startswith("application/json"):
178
- data = await request.json()
179
- return ZeroShotImageClassificationRequest(**data)
180
- if content_type.startswith("application/x-www-form-urlencoded"):
181
- raw = await request.body()
182
- try:
183
- data = json.loads(raw)
184
- return ZeroShotImageClassificationRequest(**data)
185
- except Exception:
186
- try:
187
- data = json.loads(raw.decode("utf-8"))
188
- return ZeroShotImageClassificationRequest(**data)
189
- except Exception:
190
- raise HTTPException(status_code=400, detail="Invalid request body")
191
- raise HTTPException(status_code=400, detail="Unsupported content type")
192
-
193
-
194
-
195
  @app.post(
196
  "/zero-shot-image-classification/{model_name:path}/",
197
  openapi_extra={
@@ -222,58 +129,126 @@ async def zero_shot_image_classification(
222
  list: The classification result(s) as returned by the pipeline.
223
  """
224
 
225
- zeroShotRequest: ZeroShotImageClassificationRequest = await get_zero_shot_image_classification_request(request)
 
 
226
 
227
- try:
228
- pipe = pipeline("zero-shot-image-classification", model=model_name)
229
- except Exception as e:
230
- logger.error(f"Failed to load model '{model_name}': {str(e)}")
231
- raise HTTPException(
232
- status_code=404,
233
- detail=f"Model '{model_name}' could not be loaded: {str(e)}"
234
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
- try:
237
- candidate_labels = []
238
- if zeroShotRequest.parameters:
239
- candidate_labels = zeroShotRequest.parameters.get('candidate_labels', [])
240
- if isinstance(candidate_labels, str):
241
- candidate_labels = [label.strip() for label in candidate_labels.split(',')]
242
- result = pipe(zeroShotRequest.inputs, candidate_labels=candidate_labels)
243
- except Exception as e:
244
- logger.error(f"Inference failed for model '{model_name}': {str(e)}")
245
- raise HTTPException(
246
- status_code=500,
247
- detail=f"Inference failed: {str(e)}"
248
- )
249
 
250
- return result
 
251
 
252
 
253
 
254
  # =========================
255
- # Image to Text Task
256
  # =========================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
 
 
 
 
258
 
259
- async def get_encoded_image(
260
- request: Request
261
- ) -> str:
262
- content_type = request.headers.get("content-type", "")
263
- if content_type.startswith("multipart/form-data"):
264
- form = await request.form()
265
- image = form.get("image")
266
- if image:
267
- image_bytes = await image.read()
268
- return base64.b64encode(image_bytes).decode("utf-8")
269
- if content_type.startswith("image/"):
270
- image_bytes = await request.body()
271
- return base64.b64encode(image_bytes).decode("utf-8")
272
 
273
- raise HTTPException(status_code=400, detail="Unsupported content type")
274
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
 
276
 
 
 
 
 
 
 
277
  @app.post(
278
  "/image-to-text/{model_name:path}/",
279
  openapi_extra={
@@ -311,24 +286,5 @@ async def image_to_text(
311
  list: The generated text as returned by the pipeline.
312
  """
313
 
314
- encoded_image = await get_encoded_image(request)
315
-
316
- try:
317
- pipe = pipeline("image-to-text", model=model_name, use_fast=True)
318
- except Exception as e:
319
- logger.error(f"Failed to load model '{model_name}': {str(e)}")
320
- raise HTTPException(
321
- status_code=404,
322
- detail=f"Model '{model_name}' could not be loaded: {str(e)}"
323
- )
324
-
325
- try:
326
- result = pipe(encoded_image)
327
- except Exception as e:
328
- logger.error(f"Inference failed for model '{model_name}': {str(e)}")
329
- raise HTTPException(
330
- status_code=500,
331
- detail=f"Inference failed: {str(e)}"
332
- )
333
-
334
- return result
 
8
  # @license Pimcore Open Core License (POCL)
9
  # -------------------------------------------------------------------
10
 
 
11
  import torch
12
 
13
+ from fastapi import FastAPI, Path, Request
 
 
 
 
 
14
  import logging
15
  import sys
 
 
16
 
17
+ from .translation_task import TranslationTaskService
18
+ from .classification import ClassificationTaskService
19
+ from .text_to_image import TextToImageTaskService
20
 
21
  app = FastAPI(
22
  title="Pimcore Local Inference Service",
 
45
  sys.stdout = StreamToLogger(logger, logging.INFO)
46
  sys.stderr = StreamToLogger(logger, logging.ERROR)
47
 
 
 
 
 
 
 
 
 
48
  @app.get("/gpu_check")
49
  async def gpu_check():
50
  """ Check if a GPU is available """
 
59
  return {'success': True, 'gpu': gpu}
60
 
61
 
 
 
 
 
62
  # =========================
63
  # Translation Task
64
  # =========================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  @app.post(
66
  "/translation/{model_name:path}/",
67
  openapi_extra={
 
92
  list: The translation result(s) as returned by the pipeline.
93
  """
94
 
95
+ translationTaskService = TranslationTaskService(logger)
96
+ return await translationTaskService.translate(request, model_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
 
99
  # =========================
100
  # Zero-Shot Image Classification Task
101
  # =========================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  @app.post(
103
  "/zero-shot-image-classification/{model_name:path}/",
104
  openapi_extra={
 
129
  list: The classification result(s) as returned by the pipeline.
130
  """
131
 
132
+ zeroShotTask = ClassificationTaskService(logger, 'zero-shot-image-classification')
133
+ return await zeroShotTask.classify(request, model_name)
134
+
135
 
136
+ # =========================
137
+ # Image Classification Task
138
+ # =========================
139
+ @app.post(
140
+ "/image-classification/{model_name:path}/",
141
+ openapi_extra={
142
+ "requestBody": {
143
+ "content": {
144
+ "application/json": {
145
+ "example": {
146
+ "inputs": "base64_encoded_image_string"
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+ )
153
+ async def image_classification(
154
+ request: Request,
155
+ model_name: str = Path(
156
+ ...,
157
+ description="The name of the image classification model (e.g., pimcore/car-countries-classification)",
158
+ example="pimcore/car-countries-classification"
159
+ )
160
+ ):
161
+ """
162
+ Execute image classification tasks.
163
 
164
+ Returns:
165
+ list: The classification result(s) as returned by the pipeline.
166
+ """
 
 
 
 
 
 
 
 
 
 
167
 
168
+ imageTask = ClassificationTaskService(logger, 'image-classification')
169
+ return await imageTask.classify(request, model_name)
170
 
171
 
172
 
173
  # =========================
174
+ # Zero-Shot Text Classification Task
175
  # =========================
176
+ @app.post(
177
+ "/zero-shot-text-classification/{model_name:path}/",
178
+ openapi_extra={
179
+ "requestBody": {
180
+ "content": {
181
+ "application/json": {
182
+ "example": {
183
+ "inputs": "text to classify",
184
+ "parameters": {"candidate_labels": "green, yellow, blue, white, silver"}
185
+ }
186
+ }
187
+ }
188
+ }
189
+ }
190
+ )
191
+ async def zero_shot_text_classification(
192
+ request: Request,
193
+ model_name: str = Path(
194
+ ...,
195
+ description="The name of the zero-shot text classification model (e.g., facebook/bart-large-mnli)",
196
+ example="facebook/bart-large-mnli"
197
+ )
198
+ ):
199
+ """
200
+ Execute zero-shot text classification tasks.
201
 
202
+ Returns:
203
+ list: The classification result(s) as returned by the pipeline.
204
+ """
205
 
206
+ zeroShotTask = ClassificationTaskService(logger, 'zero-shot-classification')
207
+ return await zeroShotTask.classify(request, model_name)
 
 
 
 
 
 
 
 
 
 
 
208
 
 
209
 
210
+ # =========================
211
+ # Text Classification Task
212
+ # =========================
213
+ @app.post(
214
+ "/text-classification/{model_name:path}/",
215
+ openapi_extra={
216
+ "requestBody": {
217
+ "content": {
218
+ "application/json": {
219
+ "example": {
220
+ "inputs": "text to classify"
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ )
227
+ async def text_classification(
228
+ request: Request,
229
+ model_name: str = Path(
230
+ ...,
231
+ description="The name of the text classification model (e.g., pimcore/car-class-classification)",
232
+ example="pimcore/car-class-classification"
233
+ )
234
+ ):
235
+ """
236
+ Execute text classification tasks.
237
+
238
+ Returns:
239
+ list: The classification result(s) as returned by the pipeline.
240
+ """
241
+
242
+ textTask = ClassificationTaskService(logger, 'text-classification')
243
+ return await textTask.classify(request, model_name)
244
 
245
 
246
+
247
+
248
+
249
+ # =========================
250
+ # Image to Text Task
251
+ # =========================
252
  @app.post(
253
  "/image-to-text/{model_name:path}/",
254
  openapi_extra={
 
286
  list: The generated text as returned by the pipeline.
287
  """
288
 
289
+ imageToTextTask = TextToImageTaskService(logger)
290
+ return await imageToTextTask.extract(request, model_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/text_to_image.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ import logging
3
+ from fastapi import Request, HTTPException
4
+ import base64
5
+
6
+
7
+ class TextToImageTaskService:
8
+
9
+ __logger: logging.Logger
10
+
11
+ def __init__(self, logger: logging.Logger):
12
+ self.__logger = logger
13
+
14
+ async def get_encoded_image(
15
+ self,
16
+ request: Request
17
+ ) -> str:
18
+ content_type = request.headers.get("content-type", "")
19
+ if content_type.startswith("multipart/form-data"):
20
+ form = await request.form()
21
+ image = form.get("image")
22
+ if image:
23
+ image_bytes = await image.read()
24
+ return base64.b64encode(image_bytes).decode("utf-8")
25
+ if content_type.startswith("image/"):
26
+ image_bytes = await request.body()
27
+ return base64.b64encode(image_bytes).decode("utf-8")
28
+
29
+ raise HTTPException(status_code=400, detail="Unsupported content type")
30
+
31
+ async def extract(
32
+ self,
33
+ request: Request,
34
+ model_name: str
35
+ ):
36
+ encoded_image = await self.get_encoded_image(request)
37
+
38
+ try:
39
+ pipe = pipeline("image-to-text", model=model_name, use_fast=True)
40
+ except Exception as e:
41
+ self.__logger.error(f"Failed to load model '{model_name}': {str(e)}")
42
+ raise HTTPException(
43
+ status_code=404,
44
+ detail=f"Model '{model_name}' could not be loaded: {str(e)}"
45
+ )
46
+
47
+ try:
48
+ result = pipe(encoded_image)
49
+ except Exception as e:
50
+ self.__logger.error(f"Inference failed for model '{model_name}': {str(e)}")
51
+ raise HTTPException(
52
+ status_code=500,
53
+ detail=f"Inference failed: {str(e)}"
54
+ )
55
+
56
+ return result
src/translation_task.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ from pydantic import BaseModel
3
+ import logging
4
+ from fastapi import Request, HTTPException
5
+ import json
6
+ from typing import Optional
7
+
8
+ class TranslationRequest(BaseModel):
9
+ inputs: str
10
+ parameters: Optional[dict] = None
11
+ options: Optional[dict] = None
12
+
13
+ class TranslationTaskService:
14
+
15
+ __logger: logging.Logger
16
+
17
+ def __init__(self, logger: logging.Logger):
18
+ self.__logger = logger
19
+
20
+ async def get_translation_request(
21
+ self,
22
+ request: Request
23
+ ) -> TranslationRequest:
24
+ content_type = request.headers.get("content-type", "")
25
+ if content_type.startswith("application/json"):
26
+ data = await request.json()
27
+ return TranslationRequest(**data)
28
+ if content_type.startswith("application/x-www-form-urlencoded"):
29
+ raw = await request.body()
30
+ try:
31
+ data = json.loads(raw)
32
+ return TranslationRequest(**data)
33
+ except Exception:
34
+ try:
35
+ data = json.loads(raw.decode("utf-8"))
36
+ return TranslationRequest(**data)
37
+ except Exception:
38
+ raise HTTPException(status_code=400, detail="Invalid request body")
39
+ raise HTTPException(status_code=400, detail="Unsupported content type")
40
+
41
+
42
+ async def translate(
43
+ self,
44
+ request: Request,
45
+ model_name: str
46
+ ):
47
+
48
+ translationRequest: TranslationRequest = await self.get_translation_request(request)
49
+
50
+ try:
51
+ pipe = pipeline("translation", model=model_name)
52
+ except Exception as e:
53
+ self.__logger.error(f"Failed to load model '{model_name}': {str(e)}")
54
+ raise HTTPException(
55
+ status_code=404,
56
+ detail=f"Model '{model_name}' could not be loaded: {str(e)}"
57
+ )
58
+
59
+ try:
60
+ result = pipe(translationRequest.inputs, **(translationRequest.parameters or {}))
61
+ return result
62
+ except Exception as e:
63
+ self.__logger.error(f"Inference failed for model '{model_name}': {str(e)}")
64
+ raise HTTPException(
65
+ status_code=500,
66
+ detail=f"Inference failed: {str(e)}"
67
+ )