Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

mock_openai_server.py 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #!/usr/bin/env python3
  2. import json
  3. import time
  4. import uuid
  5. from collections.abc import Iterator
  6. from typing import Any
  7. from flask import Flask, Response, jsonify, request
  8. app = Flask(__name__)
  9. # Mock models list
  10. MODELS = [
  11. {
  12. "id": "gpt-3.5-turbo",
  13. "object": "model",
  14. "created": 1677649963,
  15. "owned_by": "openai",
  16. },
  17. {"id": "gpt-4", "object": "model", "created": 1687882411, "owned_by": "openai"},
  18. {
  19. "id": "text-embedding-ada-002",
  20. "object": "model",
  21. "created": 1671217299,
  22. "owned_by": "openai-internal",
  23. },
  24. ]
  25. @app.route("/v1/models", methods=["GET"])
  26. def list_models() -> Any:
  27. """List available models."""
  28. return jsonify({"object": "list", "data": MODELS})
  29. @app.route("/v1/chat/completions", methods=["POST"])
  30. def chat_completions() -> Any:
  31. """Handle chat completions."""
  32. data = request.json or {}
  33. model = data.get("model", "gpt-3.5-turbo")
  34. messages = data.get("messages", [])
  35. stream = data.get("stream", False)
  36. # Generate mock response
  37. response_content = "This is a mock response from the OpenAI server."
  38. if messages:
  39. last_message = messages[-1].get("content", "")
  40. response_content = f"Mock response to: {last_message[:100]}..."
  41. if stream:
  42. # Streaming response
  43. def generate() -> Iterator[str]:
  44. # Send initial chunk
  45. chunk = {
  46. "id": f"chatcmpl-{uuid.uuid4().hex[:8]}",
  47. "object": "chat.completion.chunk",
  48. "created": int(time.time()),
  49. "model": model,
  50. "choices": [
  51. {
  52. "index": 0,
  53. "delta": {"role": "assistant", "content": ""},
  54. "finish_reason": None,
  55. }
  56. ],
  57. }
  58. yield f"data: {json.dumps(chunk)}\n\n"
  59. # Send content in chunks
  60. words = response_content.split()
  61. for word in words:
  62. chunk = {
  63. "id": f"chatcmpl-{uuid.uuid4().hex[:8]}",
  64. "object": "chat.completion.chunk",
  65. "created": int(time.time()),
  66. "model": model,
  67. "choices": [
  68. {
  69. "index": 0,
  70. "delta": {"content": word + " "},
  71. "finish_reason": None,
  72. }
  73. ],
  74. }
  75. yield f"data: {json.dumps(chunk)}\n\n"
  76. time.sleep(0.05) # Simulate streaming delay
  77. # Send final chunk
  78. chunk = {
  79. "id": f"chatcmpl-{uuid.uuid4().hex[:8]}",
  80. "object": "chat.completion.chunk",
  81. "created": int(time.time()),
  82. "model": model,
  83. "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}],
  84. }
  85. yield f"data: {json.dumps(chunk)}\n\n"
  86. yield "data: [DONE]\n\n"
  87. return Response(generate(), mimetype="text/event-stream")
  88. else:
  89. # Non-streaming response
  90. return jsonify(
  91. {
  92. "id": f"chatcmpl-{uuid.uuid4().hex[:8]}",
  93. "object": "chat.completion",
  94. "created": int(time.time()),
  95. "model": model,
  96. "choices": [
  97. {
  98. "index": 0,
  99. "message": {"role": "assistant", "content": response_content},
  100. "finish_reason": "stop",
  101. }
  102. ],
  103. "usage": {
  104. "prompt_tokens": len(str(messages)),
  105. "completion_tokens": len(response_content.split()),
  106. "total_tokens": len(str(messages)) + len(response_content.split()),
  107. },
  108. }
  109. )
  110. @app.route("/v1/completions", methods=["POST"])
  111. def completions() -> Any:
  112. """Handle text completions."""
  113. data = request.json or {}
  114. model = data.get("model", "gpt-3.5-turbo-instruct")
  115. prompt = data.get("prompt", "")
  116. response_text = f"Mock completion for prompt: {prompt[:100]}..."
  117. return jsonify(
  118. {
  119. "id": f"cmpl-{uuid.uuid4().hex[:8]}",
  120. "object": "text_completion",
  121. "created": int(time.time()),
  122. "model": model,
  123. "choices": [
  124. {
  125. "text": response_text,
  126. "index": 0,
  127. "logprobs": None,
  128. "finish_reason": "stop",
  129. }
  130. ],
  131. "usage": {
  132. "prompt_tokens": len(prompt.split()),
  133. "completion_tokens": len(response_text.split()),
  134. "total_tokens": len(prompt.split()) + len(response_text.split()),
  135. },
  136. }
  137. )
  138. @app.route("/v1/embeddings", methods=["POST"])
  139. def embeddings() -> Any:
  140. """Handle embeddings requests."""
  141. data = request.json or {}
  142. model = data.get("model", "text-embedding-ada-002")
  143. input_text = data.get("input", "")
  144. # Generate mock embedding (1536 dimensions for ada-002)
  145. mock_embedding = [0.1] * 1536
  146. return jsonify(
  147. {
  148. "object": "list",
  149. "data": [{"object": "embedding", "embedding": mock_embedding, "index": 0}],
  150. "model": model,
  151. "usage": {
  152. "prompt_tokens": len(input_text.split()),
  153. "total_tokens": len(input_text.split()),
  154. },
  155. }
  156. )
  157. @app.route("/v1/models/<model_id>", methods=["GET"])
  158. def get_model(model_id: str) -> tuple[Any, int] | Any:
  159. """Get specific model details."""
  160. for model in MODELS:
  161. if model["id"] == model_id:
  162. return jsonify(model)
  163. return jsonify({"error": "Model not found"}), 404
  164. @app.route("/health", methods=["GET"])
  165. def health() -> Any:
  166. """Health check endpoint."""
  167. return jsonify({"status": "healthy"})
  168. if __name__ == "__main__":
  169. print("🚀 Starting Mock OpenAI Server on http://localhost:5004")
  170. print("Available endpoints:")
  171. print(" - GET /v1/models")
  172. print(" - POST /v1/chat/completions")
  173. print(" - POST /v1/completions")
  174. print(" - POST /v1/embeddings")
  175. print(" - GET /v1/models/<model_id>")
  176. print(" - GET /health")
  177. app.run(host="0.0.0.0", port=5004, debug=True)