jeanbaptdzd commited on
Commit
f28306b
·
1 Parent(s): 83ffe61

feat: Add input validation and type hints

Browse files

- Add validation for empty messages, temperature range, max_tokens
- Improve type hints with return type annotations
- Better error messages for validation failures

Testing CodeRabbit integration

Files changed (3) hide show
  1. .coderabbit.yaml +30 -0
  2. app/main.py +5 -2
  3. app/routers/openai_api.py +19 -0
.coderabbit.yaml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CodeRabbit configuration
2
+ # See: https://docs.coderabbit.ai/configuration
3
+
4
+ language: python
5
+
6
+ review:
7
+ # Enable/disable review
8
+ enabled: true
9
+
10
+ # Paths to include/exclude
11
+ paths:
12
+ - "app/**"
13
+ - "tests/**"
14
+ - "*.py"
15
+
16
+ # Review settings
17
+ simple: false # Set to true for faster, simpler reviews
18
+ high_level_summary: true
19
+ estimate_time: true
20
+ project_language: python
21
+
22
+ chat:
23
+ enabled: true
24
+ # Allow asking questions about code in PR
25
+
26
+ complaints:
27
+ # What CodeRabbit should focus on
28
+ enabled: true
29
+ # Include security, performance, and code quality checks
30
+
app/main.py CHANGED
@@ -1,3 +1,4 @@
 
1
  from fastapi import FastAPI
2
  from app.middleware import api_key_guard
3
  from app.routers import openai_api
@@ -38,7 +39,8 @@ async def startup_event():
38
  logger.info("Model initialization started in background")
39
 
40
  @app.get("/")
41
- async def root():
 
42
  return {
43
  "status": "ok",
44
  "service": "Qwen Open Finance R 8B Inference",
@@ -48,7 +50,8 @@ async def root():
48
  }
49
 
50
  @app.get("/health")
51
- async def health():
 
52
  return {"status": "healthy", "service": "LLM Pro Finance API"}
53
 
54
 
 
1
+ from typing import Dict
2
  from fastapi import FastAPI
3
  from app.middleware import api_key_guard
4
  from app.routers import openai_api
 
39
  logger.info("Model initialization started in background")
40
 
41
  @app.get("/")
42
+ async def root() -> Dict[str, str]:
43
+ """Root endpoint returning API status and information."""
44
  return {
45
  "status": "ok",
46
  "service": "Qwen Open Finance R 8B Inference",
 
50
  }
51
 
52
  @app.get("/health")
53
+ async def health() -> Dict[str, str]:
54
+ """Health check endpoint."""
55
  return {"status": "healthy", "service": "LLM Pro Finance API"}
56
 
57
 
app/routers/openai_api.py CHANGED
@@ -54,6 +54,13 @@ async def reload_model(force: bool = Query(False, description="Force reload from
54
  async def chat_completions(body: ChatCompletionRequest):
55
  """Chat completions endpoint (OpenAI-compatible)"""
56
  try:
 
 
 
 
 
 
 
57
  # Build payload with all supported parameters
58
  payload: Dict[str, Any] = {
59
  "model": body.model or settings.model,
@@ -63,8 +70,20 @@ async def chat_completions(body: ChatCompletionRequest):
63
  "stream": body.stream or False,
64
  }
65
 
 
 
 
 
 
 
 
66
  # Add optional max_tokens if provided
67
  if body.max_tokens is not None:
 
 
 
 
 
68
  payload["max_tokens"] = body.max_tokens
69
 
70
  logger.info(f"Chat completion request: model={payload['model']}, messages={len(payload['messages'])}, stream={payload['stream']}")
 
54
  async def chat_completions(body: ChatCompletionRequest):
55
  """Chat completions endpoint (OpenAI-compatible)"""
56
  try:
57
+ # Validate messages list is not empty
58
+ if not body.messages:
59
+ return JSONResponse(
60
+ status_code=400,
61
+ content={"error": {"message": "messages list cannot be empty", "type": "invalid_request_error"}}
62
+ )
63
+
64
  # Build payload with all supported parameters
65
  payload: Dict[str, Any] = {
66
  "model": body.model or settings.model,
 
70
  "stream": body.stream or False,
71
  }
72
 
73
+ # Validate temperature range
74
+ if payload["temperature"] < 0 or payload["temperature"] > 2:
75
+ return JSONResponse(
76
+ status_code=400,
77
+ content={"error": {"message": "temperature must be between 0 and 2", "type": "invalid_request_error"}}
78
+ )
79
+
80
  # Add optional max_tokens if provided
81
  if body.max_tokens is not None:
82
+ if body.max_tokens < 1:
83
+ return JSONResponse(
84
+ status_code=400,
85
+ content={"error": {"message": "max_tokens must be at least 1", "type": "invalid_request_error"}}
86
+ )
87
  payload["max_tokens"] = body.max_tokens
88
 
89
  logger.info(f"Chat completion request: model={payload['model']}, messages={len(payload['messages'])}, stream={payload['stream']}")