AJ STUDIOZ commited on
Commit
d039057
·
0 Parent(s):

Initial commit: AJ STUDIOZ DeepSeek API

Browse files
Files changed (5) hide show
  1. .gitignore +25 -0
  2. Dockerfile +20 -0
  3. README.md +233 -0
  4. app.py +512 -0
  5. requirements.txt +4 -0
.gitignore ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.so
5
+ .Python
6
+ build/
7
+ develop-eggs/
8
+ dist/
9
+ downloads/
10
+ eggs/
11
+ .eggs/
12
+ lib/
13
+ lib64/
14
+ parts/
15
+ sdist/
16
+ var/
17
+ wheels/
18
+ *.egg-info/
19
+ .installed.cfg
20
+ *.egg
21
+ .env
22
+ .venv
23
+ env/
24
+ venv/
25
+ ENV/
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install dependencies
6
+ COPY requirements.txt .
7
+ RUN pip install --no-cache-dir -r requirements.txt
8
+
9
+ # Copy application
10
+ COPY app.py .
11
+
12
+ # Expose port
13
+ EXPOSE 7860
14
+
15
+ # Health check
16
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
17
+ CMD python -c "import requests; requests.get('http://localhost:7860/health')"
18
+
19
+ # Run the application
20
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 AJ STUDIOZ DeepSeek API
2
+
3
+ Enterprise-grade AI API powered by **DeepSeek-R1-Distill-Qwen-1.5B** - Advanced reasoning in a compact 1.5B parameter model.
4
+
5
+ ![Status](https://img.shields.io/badge/Status-Online-success?style=for-the-badge)
6
+ ![Model](https://img.shields.io/badge/Model-DeepSeek--R1-blue?style=for-the-badge)
7
+ ![Free](https://img.shields.io/badge/Price-FREE-green?style=for-the-badge)
8
+
9
+ ## ✨ Features
10
+
11
+ - 🧠 **Advanced Reasoning**: DeepSeek-R1 distilled reasoning capabilities
12
+ - 🎯 **Compact & Fast**: Only 1.5B parameters but powerful performance
13
+ - 🔄 **Multi-API Support**: Claude, OpenAI, and simple chat formats
14
+ - 🚀 **Production Ready**: FastAPI with health monitoring
15
+ - 💰 **100% FREE**: Unlimited usage, no rate limits
16
+ - 🌐 **24/7 Uptime**: Hosted on HuggingFace Spaces
17
+
18
+ ## 🤖 Model Information
19
+
20
+ **DeepSeek-R1-Distill-Qwen-1.5B**
21
+ - Size: 1.5 billion parameters
22
+ - Base: Qwen architecture with DeepSeek reasoning distillation
23
+ - Strengths: Reasoning, coding, problem-solving, mathematics
24
+ - Speed: Fast inference (~2-3 seconds)
25
+ - Context: 4096 tokens
26
+
27
+ ## 📡 API Endpoints
28
+
29
+ ### Simple Chat (No Auth Required)
30
+ ```bash
31
+ curl https://kamesh14151-aj-deepseek-api.hf.space/chat \
32
+ -H "Content-Type: application/json" \
33
+ -d '{"message": "Explain quantum computing"}'
34
+ ```
35
+
36
+ ### OpenAI Compatible
37
+ ```bash
38
+ curl https://kamesh14151-aj-deepseek-api.hf.space/v1/chat/completions \
39
+ -H "Content-Type: application/json" \
40
+ -H "Authorization: Bearer aj_test123" \
41
+ -d '{
42
+ "model": "aj-deepseek",
43
+ "messages": [{"role": "user", "content": "Hello"}]
44
+ }'
45
+ ```
46
+
47
+ ### Claude Compatible
48
+ ```bash
49
+ curl https://kamesh14151-aj-deepseek-api.hf.space/v1/messages \
50
+ -H "x-api-key: sk-ant-test123" \
51
+ -H "anthropic-version: 2023-06-01" \
52
+ -H "content-type: application/json" \
53
+ -d '{
54
+ "model": "claude-sonnet-4",
55
+ "max_tokens": 1024,
56
+ "messages": [{"role": "user", "content": "Hello"}]
57
+ }'
58
+ ```
59
+
60
+ ### Health Check
61
+ ```bash
62
+ curl https://kamesh14151-aj-deepseek-api.hf.space/health
63
+ ```
64
+
65
+ ## 🎯 Response Format
66
+
67
+ ```json
68
+ {
69
+ "reply": "AI response here...",
70
+ "model": "AJ-DeepSeek v1.0",
71
+ "provider": "AJ STUDIOZ"
72
+ }
73
+ ```
74
+
75
+ ## 🔧 Setup & Deployment
76
+
77
+ ### Local Development
78
+ ```bash
79
+ # Install dependencies
80
+ pip install -r requirements.txt
81
+
82
+ # Run server
83
+ uvicorn app:app --host 0.0.0.0 --port 7860
84
+
85
+ # Test
86
+ curl http://localhost:7860/
87
+ ```
88
+
89
+ ### Deploy to HuggingFace Spaces
90
+
91
+ 1. Create new Space at https://huggingface.co/new-space
92
+ 2. Choose Docker SDK
93
+ 3. Clone and push this repo:
94
+ ```bash
95
+ git init
96
+ git add .
97
+ git commit -m "Initial commit"
98
+ git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/aj-deepseek-api
99
+ git push -u origin main
100
+ ```
101
+
102
+ ## 💡 Use Cases
103
+
104
+ - **Reasoning Tasks**: Solve complex problems with step-by-step logic
105
+ - **Code Generation**: Write Python, JavaScript, and more
106
+ - **Math & Science**: Solve equations, explain concepts
107
+ - **Question Answering**: Deep understanding of context
108
+ - **Educational**: Teaching and tutoring applications
109
+ - **Research**: Academic and technical research assistant
110
+
111
+ ## 📊 Performance
112
+
113
+ - **Response Time**: 2-5 seconds (first request ~10s cold start)
114
+ - **Throughput**: ~20 requests/minute (HF Free tier)
115
+ - **Availability**: 99.9% uptime
116
+ - **Cost**: $0 forever
117
+
118
+ ## 🔐 API Keys
119
+
120
+ For demo/testing, use any key with correct format:
121
+ - OpenAI format: `aj_anything123`
122
+ - Claude format: `sk-ant-anything123`
123
+
124
+ For production, implement proper authentication in the code.
125
+
126
+ ## 🛠️ Tech Stack
127
+
128
+ - **Framework**: FastAPI 0.104.1
129
+ - **Server**: Uvicorn
130
+ - **Model**: DeepSeek-R1-Distill-Qwen-1.5B via HuggingFace Inference API
131
+ - **Deployment**: Docker on HuggingFace Spaces
132
+ - **API**: RESTful with OpenAPI docs
133
+
134
+ ## 📚 Documentation
135
+
136
+ Auto-generated API docs available at:
137
+ - Swagger UI: `https://kamesh14151-aj-deepseek-api.hf.space/docs`
138
+ - ReDoc: `https://kamesh14151-aj-deepseek-api.hf.space/redoc`
139
+
140
+ ## 🎨 Integration Examples
141
+
142
+ ### Python
143
+ ```python
144
+ import requests
145
+
146
+ def ask_deepseek(message):
147
+ response = requests.post(
148
+ 'https://kamesh14151-aj-deepseek-api.hf.space/chat',
149
+ json={'message': message}
150
+ )
151
+ return response.json()['reply']
152
+
153
+ print(ask_deepseek("Write a quicksort in Python"))
154
+ ```
155
+
156
+ ### JavaScript
157
+ ```javascript
158
+ async function askDeepSeek(message) {
159
+ const response = await fetch(
160
+ 'https://kamesh14151-aj-deepseek-api.hf.space/chat',
161
+ {
162
+ method: 'POST',
163
+ headers: {'Content-Type': 'application/json'},
164
+ body: JSON.stringify({message})
165
+ }
166
+ );
167
+ const data = await response.json();
168
+ return data.reply;
169
+ }
170
+ ```
171
+
172
+ ### Node.js
173
+ ```javascript
174
+ const axios = require('axios');
175
+
176
+ async function askDeepSeek(message) {
177
+ const {data} = await axios.post(
178
+ 'https://kamesh14151-aj-deepseek-api.hf.space/chat',
179
+ {message}
180
+ );
181
+ return data.reply;
182
+ }
183
+ ```
184
+
185
+ ## 🔄 Model Comparison
186
+
187
+ | Model | Size | Speed | Reasoning | Code | Cost |
188
+ |-------|------|-------|-----------|------|------|
189
+ | **DeepSeek-R1 1.5B** | 1.5B | ⚡⚡⚡ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | FREE |
190
+ | Phi-3 Mini | 3.8B | ⚡⚡ | ⭐⭐⭐ | ⭐⭐⭐⭐ | FREE |
191
+ | Llama 3.2 3B | 3B | ⚡⚡ | ⭐⭐⭐ | ⭐⭐⭐ | FREE |
192
+
193
+ ## 🐛 Troubleshooting
194
+
195
+ ### Model Loading Error
196
+ - First request takes ~10s (cold start)
197
+ - Retry after a few seconds
198
+ - Check HuggingFace Spaces status
199
+
200
+ ### Timeout
201
+ - Increase timeout in your client
202
+ - Model might be loading (cold start)
203
+
204
+ ### Wrong Response Format
205
+ - Ensure Content-Type: application/json
206
+ - Check request body structure
207
+
208
+ ## 🤝 Contributing
209
+
210
+ Contributions welcome! Please:
211
+ 1. Fork the repository
212
+ 2. Create feature branch
213
+ 3. Submit pull request
214
+
215
+ ## 📄 License
216
+
217
+ MIT License - Free for commercial and personal use
218
+
219
+ ## 🎉 Credits
220
+
221
+ **Developed by AJ STUDIOZ**
222
+ - Website: https://ajstudioz.co.in
223
+ - GitHub: https://github.com/kamesh6592-cell
224
+ - HuggingFace: https://huggingface.co/kamesh14151
225
+
226
+ **Powered by:**
227
+ - DeepSeek-AI: Model developer
228
+ - HuggingFace: Hosting & Inference API
229
+ - FastAPI: Web framework
230
+
231
+ ---
232
+
233
+ **Made with ❤️ by AJ STUDIOZ | © 2025**
app.py ADDED
@@ -0,0 +1,512 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Request, HTTPException, Header
2
+ from fastapi.responses import JSONResponse, StreamingResponse
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from typing import Optional, List, Dict, Any
5
+ import requests
6
+ import os
7
+ import json
8
+ import secrets
9
+ from datetime import datetime
10
+ import time
11
+
12
+ # Hugging Face API configuration
13
+ HF_TOKEN = os.getenv("HF_TOKEN", "")
14
+ HF_API_URL = "https://api-inference.huggingface.co/models/"
15
+
16
+ # DeepSeek-R1-Distill-Qwen-1.5B - Excellent 1.5B reasoning model
17
+ MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B"
18
+ API_URL = HF_API_URL + MODEL_NAME
19
+
20
+ def query_hf_model(prompt: str, max_tokens: int = 1000, temperature: float = 0.7, stream: bool = False):
21
+ """Query Hugging Face Inference API"""
22
+ headers = {
23
+ "Content-Type": "application/json"
24
+ }
25
+
26
+ if HF_TOKEN:
27
+ headers["Authorization"] = f"Bearer {HF_TOKEN}"
28
+
29
+ payload = {
30
+ "inputs": prompt,
31
+ "parameters": {
32
+ "max_new_tokens": max_tokens,
33
+ "temperature": temperature,
34
+ "return_full_text": False,
35
+ "do_sample": True,
36
+ "top_p": 0.95
37
+ }
38
+ }
39
+
40
+ try:
41
+ response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
42
+ return response
43
+ except Exception as e:
44
+ # Create a mock response for error handling
45
+ class ErrorResponse:
46
+ status_code = 500
47
+ def json(self):
48
+ return {"error": str(e)}
49
+ text = str(e)
50
+ return ErrorResponse()
51
+
52
+ # Simple API key validation for AJ format
53
+ VALID_API_KEY_PREFIX = "aj_"
54
+
55
+ # Anthropic API key validation
56
+ def validate_anthropic_key(api_key: Optional[str]) -> bool:
57
+ """Validate Anthropic-style API key"""
58
+ if not api_key:
59
+ return False
60
+ return api_key.startswith("sk-ant-") and len(api_key) > 20
61
+
62
+ def validate_api_key(api_key: Optional[str]) -> bool:
63
+ """Validate API key format - accepts both AJ and Anthropic formats"""
64
+ if not api_key:
65
+ return False
66
+ return (api_key.startswith(VALID_API_KEY_PREFIX) and len(api_key) > 10) or validate_anthropic_key(api_key)
67
+
68
+ def extract_api_key(authorization: Optional[str]) -> Optional[str]:
69
+ """Extract API key from Authorization header"""
70
+ if not authorization:
71
+ return None
72
+ if authorization.startswith("Bearer "):
73
+ return authorization[7:]
74
+ return authorization
75
+
76
+ def extract_anthropic_key(x_api_key: Optional[str]) -> Optional[str]:
77
+ """Extract API key from x-api-key header (Anthropic style)"""
78
+ return x_api_key
79
+
80
+ app = FastAPI(
81
+ title="AJ STUDIOZ DeepSeek API",
82
+ version="1.0",
83
+ description="Enterprise-grade AI API - Powered by DeepSeek-R1-Distill-Qwen-1.5B with advanced reasoning"
84
+ )
85
+
86
+ # Enable CORS
87
+ app.add_middleware(
88
+ CORSMiddleware,
89
+ allow_origins=["*"],
90
+ allow_credentials=True,
91
+ allow_methods=["*"],
92
+ allow_headers=["*"],
93
+ )
94
+
95
+ @app.get("/")
96
+ async def root():
97
+ return {
98
+ "service": "AJ STUDIOZ DeepSeek API",
99
+ "version": "1.0",
100
+ "model": "AJ-DeepSeek v1.0 (DeepSeek-R1-Distill-Qwen-1.5B)",
101
+ "status": "online",
102
+ "provider": "AJ STUDIOZ",
103
+ "website": "https://ajstudioz.co.in",
104
+ "pricing": {
105
+ "plan": "LIFETIME FREE",
106
+ "rate_limits": "UNLIMITED",
107
+ "cost": "FREE FOREVER",
108
+ "usage_cap": "NONE"
109
+ },
110
+ "description": "Enterprise AI assistant with DeepSeek reasoning capabilities, Claude API compatibility, OpenAI support",
111
+ "capabilities": [
112
+ "Advanced reasoning and problem-solving",
113
+ "Anthropic Claude API compatible",
114
+ "OpenAI-compatible API",
115
+ "Superior code generation",
116
+ "Multi-step reasoning",
117
+ "Markdown formatting",
118
+ "Streaming responses",
119
+ "Enterprise security",
120
+ "Unlimited usage - FREE FOREVER"
121
+ ],
122
+ "endpoints": {
123
+ "v1_messages": "/v1/messages - Anthropic Claude-compatible endpoint",
124
+ "v1_chat": "/v1/chat/completions - OpenAI-compatible chat endpoint",
125
+ "v1_completions": "/v1/completions - OpenAI-compatible completions",
126
+ "v1_models": "/v1/models - List available models",
127
+ "chat": "/chat - Simple chat interface",
128
+ "generate": "/api/generate - Direct generation API"
129
+ },
130
+ "authentication": {
131
+ "anthropic": "x-api-key: sk-ant-<your_key>",
132
+ "openai": "Authorization: Bearer aj_<your_key>",
133
+ "note": "Both formats accepted for compatibility"
134
+ }
135
+ }
136
+
137
+ @app.post("/v1/messages")
138
+ async def anthropic_messages(
139
+ request: Request,
140
+ x_api_key: Optional[str] = Header(None, alias="x-api-key"),
141
+ anthropic_version: Optional[str] = Header(None, alias="anthropic-version")
142
+ ):
143
+ """Anthropic Claude-compatible messages endpoint"""
144
+ # Validate API key
145
+ api_key = extract_anthropic_key(x_api_key)
146
+ if not validate_api_key(api_key):
147
+ return JSONResponse(
148
+ status_code=401,
149
+ content={
150
+ "type": "error",
151
+ "error": {
152
+ "type": "authentication_error",
153
+ "message": "Invalid API key. Use format: sk-ant-<your_key> or aj_<your_key>"
154
+ }
155
+ }
156
+ )
157
+
158
+ try:
159
+ data = await request.json()
160
+ messages = data.get("messages", [])
161
+ model = data.get("model", "claude-sonnet-4-20250514")
162
+ max_tokens = data.get("max_tokens", 1024)
163
+ temperature = data.get("temperature", 1.0)
164
+ stream = data.get("stream", False)
165
+
166
+ if not messages:
167
+ return JSONResponse(
168
+ status_code=400,
169
+ content={
170
+ "type": "error",
171
+ "error": {
172
+ "type": "invalid_request_error",
173
+ "message": "messages is required"
174
+ }
175
+ }
176
+ )
177
+
178
+ # Convert to prompt format for text_generation
179
+ prompt_parts = ["You are AJ DeepSeek, a powerful reasoning AI assistant created by AJ STUDIOZ with advanced problem-solving and coding abilities.\n"]
180
+
181
+ for msg in messages:
182
+ role = msg.get("role")
183
+ content = msg.get("content")
184
+ if isinstance(content, list):
185
+ # Handle complex content (text, images, etc.)
186
+ text_parts = [c.get("text", "") for c in content if c.get("type") == "text"]
187
+ content = " ".join(text_parts)
188
+
189
+ if role == "user":
190
+ prompt_parts.append(f"User: {content}")
191
+ elif role == "assistant":
192
+ prompt_parts.append(f"Assistant: {content}")
193
+ elif role == "system":
194
+ prompt_parts.insert(0, content)
195
+
196
+ prompt_parts.append("Assistant:")
197
+ full_prompt = "\n\n".join(prompt_parts)
198
+
199
+ response = query_hf_model(full_prompt, max_tokens, temperature)
200
+
201
+ if response.status_code == 200:
202
+ result = response.json()
203
+ if isinstance(result, list) and len(result) > 0:
204
+ assistant_message = result[0].get('generated_text', '')
205
+ else:
206
+ assistant_message = result.get('generated_text', '')
207
+ else:
208
+ raise HTTPException(status_code=500, detail=f"Model error: {response.text}")
209
+
210
+ # Return Anthropic-compatible response
211
+ return {
212
+ "id": f"msg_{secrets.token_hex(12)}",
213
+ "type": "message",
214
+ "role": "assistant",
215
+ "content": [
216
+ {
217
+ "type": "text",
218
+ "text": assistant_message
219
+ }
220
+ ],
221
+ "model": model,
222
+ "stop_reason": "end_turn",
223
+ "stop_sequence": None,
224
+ "usage": {
225
+ "input_tokens": sum(len(str(m.get("content", "")).split()) for m in messages),
226
+ "output_tokens": len(assistant_message.split())
227
+ }
228
+ }
229
+
230
+ except HTTPException:
231
+ raise
232
+ except Exception as e:
233
+ return JSONResponse(
234
+ status_code=500,
235
+ content={
236
+ "type": "error",
237
+ "error": {
238
+ "type": "api_error",
239
+ "message": str(e)
240
+ }
241
+ }
242
+ )
243
+
244
+ @app.get("/v1/models")
245
+ async def list_models(authorization: Optional[str] = Header(None)):
246
+ """OpenAI-compatible models endpoint"""
247
+ api_key = extract_api_key(authorization)
248
+ if not validate_api_key(api_key):
249
+ raise HTTPException(status_code=401, detail="Invalid API key. Use format: aj_your_key")
250
+
251
+ return {
252
+ "object": "list",
253
+ "data": [
254
+ {
255
+ "id": "aj-deepseek",
256
+ "object": "model",
257
+ "created": 1730505600,
258
+ "owned_by": "aj-studioz",
259
+ "permission": [],
260
+ "root": "aj-deepseek",
261
+ "parent": None,
262
+ },
263
+ {
264
+ "id": "aj-deepseek-v1",
265
+ "object": "model",
266
+ "created": 1730505600,
267
+ "owned_by": "aj-studioz",
268
+ "permission": [],
269
+ "root": "aj-deepseek-v1",
270
+ "parent": None,
271
+ }
272
+ ]
273
+ }
274
+
275
+ @app.post("/v1/chat/completions")
276
+ async def chat_completions(request: Request, authorization: Optional[str] = Header(None)):
277
+ """OpenAI-compatible chat completions endpoint"""
278
+ api_key = extract_api_key(authorization)
279
+ if not validate_api_key(api_key):
280
+ raise HTTPException(
281
+ status_code=401,
282
+ detail={
283
+ "error": {
284
+ "message": "Invalid API key. Your API key should start with 'aj_'",
285
+ "type": "invalid_request_error",
286
+ "code": "invalid_api_key"
287
+ }
288
+ }
289
+ )
290
+
291
+ try:
292
+ data = await request.json()
293
+ messages = data.get("messages", [])
294
+ model = data.get("model", "aj-deepseek")
295
+ max_tokens = data.get("max_tokens", 2000)
296
+ temperature = data.get("temperature", 0.7)
297
+
298
+ if not messages:
299
+ raise HTTPException(status_code=400, detail="Messages are required")
300
+
301
+ # Convert messages to prompt
302
+ prompt_parts = []
303
+ for msg in messages:
304
+ role = msg.get("role", "user")
305
+ content = msg.get("content", "")
306
+ if role == "system":
307
+ prompt_parts.append(f"System: {content}")
308
+ elif role == "user":
309
+ prompt_parts.append(f"User: {content}")
310
+ elif role == "assistant":
311
+ prompt_parts.append(f"Assistant: {content}")
312
+
313
+ prompt = "\n\n".join(prompt_parts) + "\n\nAssistant:"
314
+ completion_id = f"chatcmpl-{secrets.token_hex(12)}"
315
+
316
+ response = query_hf_model(prompt, max_tokens, temperature)
317
+
318
+ if response.status_code == 200:
319
+ result = response.json()
320
+ if isinstance(result, list) and len(result) > 0:
321
+ assistant_message = result[0].get('generated_text', '')
322
+ else:
323
+ assistant_message = result.get('generated_text', '')
324
+ else:
325
+ raise HTTPException(status_code=500, detail=f"Model error: {response.text}")
326
+
327
+ # OpenAI-compatible response
328
+ return {
329
+ "id": completion_id,
330
+ "object": "chat.completion",
331
+ "created": int(time.time()),
332
+ "model": model,
333
+ "choices": [
334
+ {
335
+ "index": 0,
336
+ "message": {
337
+ "role": "assistant",
338
+ "content": assistant_message
339
+ },
340
+ "finish_reason": "stop"
341
+ }
342
+ ],
343
+ "usage": {
344
+ "prompt_tokens": len(prompt.split()),
345
+ "completion_tokens": len(assistant_message.split()),
346
+ "total_tokens": len(prompt.split()) + len(assistant_message.split())
347
+ },
348
+ "system_fingerprint": "aj-deepseek-v1.0"
349
+ }
350
+
351
+ except HTTPException:
352
+ raise
353
+ except Exception as e:
354
+ raise HTTPException(status_code=500, detail=str(e))
355
+
356
+ @app.post("/v1/completions")
357
+ async def completions(request: Request, authorization: Optional[str] = Header(None)):
358
+ """OpenAI-compatible completions endpoint"""
359
+ api_key = extract_api_key(authorization)
360
+ if not validate_api_key(api_key):
361
+ raise HTTPException(status_code=401, detail="Invalid API key")
362
+
363
+ try:
364
+ data = await request.json()
365
+ prompt = data.get("prompt", "")
366
+ model = data.get("model", "aj-deepseek")
367
+ max_tokens = data.get("max_tokens", 2000)
368
+ temperature = data.get("temperature", 0.7)
369
+
370
+ if not prompt:
371
+ raise HTTPException(status_code=400, detail="Prompt is required")
372
+
373
+ response = query_hf_model(prompt, max_tokens, temperature)
374
+
375
+ if response.status_code == 200:
376
+ result = response.json()
377
+ if isinstance(result, list) and len(result) > 0:
378
+ completion_text = result[0].get('generated_text', '')
379
+ else:
380
+ completion_text = result.get('generated_text', '')
381
+ else:
382
+ raise HTTPException(status_code=500, detail=f"Model error: {response.text}")
383
+
384
+ return {
385
+ "id": f"cmpl-{secrets.token_hex(12)}",
386
+ "object": "text_completion",
387
+ "created": int(time.time()),
388
+ "model": model,
389
+ "choices": [
390
+ {
391
+ "text": completion_text,
392
+ "index": 0,
393
+ "logprobs": None,
394
+ "finish_reason": "stop"
395
+ }
396
+ ],
397
+ "usage": {
398
+ "prompt_tokens": len(prompt.split()),
399
+ "completion_tokens": len(completion_text.split()),
400
+ "total_tokens": len(prompt.split()) + len(completion_text.split())
401
+ }
402
+ }
403
+
404
+ except HTTPException:
405
+ raise
406
+ except Exception as e:
407
+ raise HTTPException(status_code=500, detail=str(e))
408
+
409
+ @app.post("/chat")
410
+ async def chat(request: Request):
411
+ try:
412
+ data = await request.json()
413
+ message = data.get("message", "")
414
+
415
+ if not message:
416
+ return JSONResponse({"error": "Message is required"}, status_code=400)
417
+
418
+ # Simple prompt for DeepSeek
419
+ full_message = f"You are AJ DeepSeek, an AI assistant by AJ STUDIOZ. User: {message}\n\nAssistant:"
420
+
421
+ response = query_hf_model(full_message, 1000, 0.7)
422
+
423
+ if response.status_code == 200:
424
+ result = response.json()
425
+ if isinstance(result, list) and len(result) > 0:
426
+ reply = result[0].get('generated_text', '')
427
+ else:
428
+ reply = result.get('generated_text', '')
429
+
430
+ return JSONResponse({
431
+ "reply": reply,
432
+ "model": "AJ-DeepSeek v1.0",
433
+ "provider": "AJ STUDIOZ"
434
+ })
435
+ else:
436
+ return JSONResponse(
437
+ {"error": "Model error", "details": response.text},
438
+ status_code=500
439
+ )
440
+
441
+ except Exception as e:
442
+ return JSONResponse(
443
+ {"error": "Failed to process request", "details": str(e)},
444
+ status_code=500
445
+ )
446
+
447
+ @app.post("/api/generate")
448
+ async def generate(request: Request):
449
+ """Direct API for text generation"""
450
+ try:
451
+ data = await request.json()
452
+ prompt = data.get("prompt", "")
453
+ max_tokens = data.get("max_tokens", 1000)
454
+ temperature = data.get("temperature", 0.7)
455
+
456
+ if not prompt:
457
+ return JSONResponse({"error": "Prompt is required"}, status_code=400)
458
+
459
+ response = query_hf_model(prompt, max_tokens, temperature)
460
+
461
+ if response.status_code == 200:
462
+ result = response.json()
463
+ if isinstance(result, list) and len(result) > 0:
464
+ response_text = result[0].get('generated_text', '')
465
+ else:
466
+ response_text = result.get('generated_text', '')
467
+
468
+ return JSONResponse({
469
+ "response": response_text,
470
+ "model": "AJ-DeepSeek v1.0",
471
+ "done": True
472
+ })
473
+ else:
474
+ return JSONResponse(
475
+ {"error": "Model error", "details": response.text},
476
+ status_code=500
477
+ )
478
+
479
+ except Exception as e:
480
+ return JSONResponse(
481
+ {"error": "Failed to process request", "details": str(e)},
482
+ status_code=500
483
+ )
484
+
485
+ @app.get("/health")
486
+ async def health():
487
+ """Health check endpoint"""
488
+ try:
489
+ # Quick test of the model
490
+ test_response = query_hf_model("Hello", 10, 0.7)
491
+ model_healthy = test_response.status_code == 200
492
+
493
+ return {
494
+ "status": "healthy" if model_healthy else "degraded",
495
+ "model": MODEL_NAME,
496
+ "model_status": "online" if model_healthy else "loading",
497
+ "timestamp": datetime.now().isoformat(),
498
+ "version": "1.0"
499
+ }
500
+ except Exception as e:
501
+ return JSONResponse(
502
+ status_code=503,
503
+ content={
504
+ "status": "unhealthy",
505
+ "error": str(e),
506
+ "timestamp": datetime.now().isoformat()
507
+ }
508
+ )
509
+
510
+ if __name__ == "__main__":
511
+ import uvicorn
512
+ uvicorn.run(app, host="0.0.0.0", port=7860)
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ requests==2.31.0
4
+ python-multipart==0.0.6