npv2k1 commited on
Commit
ddca844
·
1 Parent(s): 0f1e5e5

feat: enhance configuration loading and add image processing endpoints

Browse files
src/common/config.py CHANGED
@@ -31,6 +31,9 @@ class AppConfig:
31
  )
32
 
33
 
 
 
 
34
  def load_json_config(path: Path) -> dict[str, Any]:
35
  """Load configuration from JSON file.
36
 
 
31
  )
32
 
33
 
34
+ print("AppConfig loaded from environment variables:", AppConfig.from_env())
35
+
36
+
37
  def load_json_config(path: Path) -> dict[str, Any]:
38
  """Load configuration from JSON file.
39
 
src/modules/api/app.py CHANGED
@@ -1,7 +1,12 @@
1
  """FastAPI application factory."""
2
 
 
3
  from fastapi import FastAPI, WebSocket, WebSocketDisconnect
4
  from fastapi.middleware.cors import CORSMiddleware
 
 
 
 
5
 
6
  from .routes import v1_router
7
 
@@ -21,6 +26,7 @@ class ConnectionManager:
21
  await connection.send_text(message)
22
 
23
  manager = ConnectionManager()
 
24
 
25
  def create_app() -> FastAPI:
26
  """Create and configure the FastAPI application."""
@@ -35,6 +41,8 @@ def create_app() -> FastAPI:
35
  allow_headers=["*"],
36
  )
37
 
 
 
38
  # Include routers
39
  app.include_router(v1_router)
40
 
@@ -60,6 +68,11 @@ def create_app() -> FastAPI:
60
  manager.disconnect(websocket)
61
  await manager.broadcast("A client disconnected")
62
 
 
 
 
 
 
63
  return app
64
 
65
 
 
1
  """FastAPI application factory."""
2
 
3
+ from typing import List
4
  from fastapi import FastAPI, WebSocket, WebSocketDisconnect
5
  from fastapi.middleware.cors import CORSMiddleware
6
+ from fastapi.staticfiles import StaticFiles
7
+ from fastapi.templating import Jinja2Templates
8
+ from fastapi.responses import HTMLResponse
9
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Request
10
 
11
  from .routes import v1_router
12
 
 
26
  await connection.send_text(message)
27
 
28
  manager = ConnectionManager()
29
+ templates = Jinja2Templates(directory="templates")
30
 
31
  def create_app() -> FastAPI:
32
  """Create and configure the FastAPI application."""
 
41
  allow_headers=["*"],
42
  )
43
 
44
+ app.mount("/static", StaticFiles(directory="static"), name="static")
45
+
46
  # Include routers
47
  app.include_router(v1_router)
48
 
 
68
  manager.disconnect(websocket)
69
  await manager.broadcast("A client disconnected")
70
 
71
+
72
+ @app.get("/room/{room_name}", response_class=HTMLResponse)
73
+ async def broadcaster(request: Request, room_name: str):
74
+ return templates.TemplateResponse("broadcaster.html", {"request": request, "room_name": room_name})
75
+
76
  return app
77
 
78
 
src/modules/api/routes/v1.py CHANGED
@@ -1,24 +1,29 @@
1
  """API v1 route handlers."""
2
 
3
- from fastapi import APIRouter, Response
 
 
4
  from typing import Dict, List
5
- from src.modules.transporter import publish_message
6
  from src.modules.models.index import embed_text
7
  import io
8
  # Create v1 router
9
  router = APIRouter(prefix='/v1', tags=['v1'])
10
  import matplotlib.pyplot as plt
 
 
11
 
12
  @router.get("/hello")
13
  async def hello_world():
14
  """Hello world endpoint."""
15
- publish_message("hello-python", "Hello from FastAPI!")
16
- embed = embed_text("Hello, world!")
17
- print(f"Generated embedding: {embed}")
18
- return {"message": "Hello, reloaded!", "embedding": list(embed)}
19
 
20
  @router.get("/health")
21
- async def health_check() -> Dict[str, str]:
 
22
  """Health check endpoint."""
23
  return {"status": "healthy"}
24
 
@@ -49,4 +54,58 @@ async def get_plot():
49
  buf.seek(0)
50
 
51
  # Trả về dưới dạng ảnh PNG
52
- return Response(content=buf.getvalue(), media_type="image/png")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """API v1 route handlers."""
2
 
3
+ from fastapi import APIRouter, Response, File, UploadFile
4
+ import numpy as np
5
+ from fastapi.responses import StreamingResponse
6
  from typing import Dict, List
7
+ from src.modules.transporter import add_to_queue
8
  from src.modules.models.index import embed_text
9
  import io
10
  # Create v1 router
11
  router = APIRouter(prefix='/v1', tags=['v1'])
12
  import matplotlib.pyplot as plt
13
+ from src.modules.transporter.redis_client import pubsub
14
+ from src.modules.transporter.kafka import kafka_pubsub
15
 
16
  @router.get("/hello")
17
  async def hello_world():
18
  """Hello world endpoint."""
19
+ add_to_queue("hello-python", "Hello from FastAPI!")
20
+ await pubsub.publish('chat', "message")
21
+ await kafka_pubsub.publish('chat', "messagejbdjchsjdhcjsdchbsjdch")
22
+ return {"message": "Hello, reloaded!"}
23
 
24
  @router.get("/health")
25
+ async def health_check(msg) -> Dict[str, str]:
26
+ print("[chat rehealthdis] Received: message")
27
  """Health check endpoint."""
28
  return {"status": "healthy"}
29
 
 
54
  buf.seek(0)
55
 
56
  # Trả về dưới dạng ảnh PNG
57
+ return Response(content=buf.getvalue(), media_type="image/png")
58
+
59
+ import cv2
60
+ @router.post("/edit-image/")
61
+ async def edit_image(file: UploadFile = File(...)):
62
+ import cv2
63
+ # Đọc file ảnh từ request
64
+ contents = await file.read()
65
+ nparr = np.frombuffer(contents, np.uint8)
66
+ img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
67
+
68
+ # Xử lý ảnh: ví dụ chuyển sang ảnh xám
69
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
70
+
71
+ # Chuyển lại thành ảnh màu để trả về (nếu cần)
72
+ result = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
73
+
74
+ # Encode ảnh thành bytes
75
+ _, img_encoded = cv2.imencode('.jpg', result)
76
+ return StreamingResponse(io.BytesIO(img_encoded.tobytes()), media_type="image/jpeg")
77
+
78
+
79
+ # Load bộ phân loại khuôn mặt Haar Cascade
80
+ face_cascade = cv2.CascadeClassifier(
81
+ cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
82
+ )
83
+
84
+ @router.post("/detect-faces/")
85
+ async def detect_faces(file: UploadFile = File(...)):
86
+ # Đọc dữ liệu ảnh
87
+ contents = await file.read()
88
+ nparr = np.frombuffer(contents, np.uint8)
89
+ img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
90
+
91
+ # Chuyển sang ảnh xám để nhận diện
92
+ gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
93
+
94
+ # Phát hiện khuôn mặt
95
+ faces = face_cascade.detectMultiScale(
96
+ gray,
97
+ scaleFactor=1.1,
98
+ minNeighbors=5,
99
+ minSize=(30, 30)
100
+ )
101
+
102
+ # Vẽ hình chữ nhật quanh khuôn mặt
103
+ for (x, y, w, h) in faces:
104
+ cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
105
+
106
+ # Chuyển ảnh kết quả thành bytes
107
+ _, img_encoded = cv2.imencode('.jpg', img)
108
+ return StreamingResponse(
109
+ io.BytesIO(img_encoded.tobytes()),
110
+ media_type="image/jpeg"
111
+ )