NitinBot001 commited on
Commit
67eb214
·
verified ·
1 Parent(s): 731fbf6

Upload 4 files

Browse files
app/routers/__init__.py ADDED
File without changes
app/routers/auth_router.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Depends, HTTPException, status
2
+ from sqlalchemy.orm import Session
3
+
4
+ from ..database import get_db
5
+ from .. import models
6
+ from ..auth import verify_password, hash_password, create_access_token, get_current_user
7
+ from ..schemas import UserCreate, UserOut, Token, LoginRequest
8
+
9
+ router = APIRouter(prefix="/auth", tags=["Authentication"])
10
+
11
+
12
+ @router.post("/signup", response_model=Token, status_code=status.HTTP_201_CREATED)
13
+ def signup(payload: UserCreate, db: Session = Depends(get_db)):
14
+ if db.query(models.User).filter(models.User.username == payload.username).first():
15
+ raise HTTPException(status_code=400, detail="Username already taken")
16
+ if db.query(models.User).filter(models.User.email == payload.email).first():
17
+ raise HTTPException(status_code=400, detail="Email already registered")
18
+
19
+ user = models.User(
20
+ username=payload.username,
21
+ email=payload.email,
22
+ hashed_password=hash_password(payload.password),
23
+ )
24
+ db.add(user)
25
+ db.commit()
26
+ db.refresh(user)
27
+
28
+ token = create_access_token({"sub": user.username})
29
+ return Token(access_token=token, user=UserOut.model_validate(user))
30
+
31
+
32
+ @router.post("/login", response_model=Token)
33
+ def login(payload: LoginRequest, db: Session = Depends(get_db)):
34
+ user = db.query(models.User).filter(models.User.username == payload.username).first()
35
+ if not user or not verify_password(payload.password, user.hashed_password):
36
+ raise HTTPException(status_code=401, detail="Invalid username or password")
37
+
38
+ token = create_access_token({"sub": user.username})
39
+ return Token(access_token=token, user=UserOut.model_validate(user))
40
+
41
+
42
+ @router.get("/me", response_model=UserOut)
43
+ def me(current_user: models.User = Depends(get_current_user)):
44
+ return current_user
app/routers/proxy_config_router.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import secrets
3
+ from fastapi import APIRouter, Depends, HTTPException, Request
4
+ from sqlalchemy.orm import Session
5
+
6
+ from ..database import get_db
7
+ from .. import models
8
+ from ..auth import get_current_user, encrypt_api_key
9
+ from ..schemas import ProxyCreate, ProxyUpdate, ProxyOut
10
+
11
+ router = APIRouter(prefix="/proxies", tags=["Proxy Management"])
12
+
13
+
14
+ def _proxy_out_with_url(proxy: models.ProxyConfig, request: Request) -> dict:
15
+ base = str(request.base_url).rstrip("/")
16
+ return {
17
+ **ProxyOut.model_validate(proxy).model_dump(),
18
+ "proxy_url": f"{base}/{proxy.proxy_token}",
19
+ }
20
+
21
+
22
+ @router.post("", status_code=201)
23
+ def create_proxy(
24
+ payload: ProxyCreate,
25
+ request: Request,
26
+ db: Session = Depends(get_db),
27
+ current_user: models.User = Depends(get_current_user),
28
+ ):
29
+ token = secrets.token_urlsafe(24)
30
+ proxy = models.ProxyConfig(
31
+ user_id=current_user.id,
32
+ proxy_token=token,
33
+ name=payload.name,
34
+ openai_base_url=payload.openai_base_url.rstrip("/"),
35
+ encrypted_api_key=encrypt_api_key(payload.openai_api_key),
36
+ model_mapping=json.dumps(payload.model_mapping or {}),
37
+ )
38
+ db.add(proxy)
39
+ db.commit()
40
+ db.refresh(proxy)
41
+ return _proxy_out_with_url(proxy, request)
42
+
43
+
44
+ @router.get("", response_model=list)
45
+ def list_proxies(
46
+ request: Request,
47
+ db: Session = Depends(get_db),
48
+ current_user: models.User = Depends(get_current_user),
49
+ ):
50
+ proxies = db.query(models.ProxyConfig).filter(
51
+ models.ProxyConfig.user_id == current_user.id
52
+ ).all()
53
+ return [_proxy_out_with_url(p, request) for p in proxies]
54
+
55
+
56
+ @router.get("/{proxy_id}")
57
+ def get_proxy(
58
+ proxy_id: int,
59
+ request: Request,
60
+ db: Session = Depends(get_db),
61
+ current_user: models.User = Depends(get_current_user),
62
+ ):
63
+ proxy = db.query(models.ProxyConfig).filter(
64
+ models.ProxyConfig.id == proxy_id,
65
+ models.ProxyConfig.user_id == current_user.id,
66
+ ).first()
67
+ if not proxy:
68
+ raise HTTPException(status_code=404, detail="Proxy not found")
69
+ return _proxy_out_with_url(proxy, request)
70
+
71
+
72
+ @router.patch("/{proxy_id}")
73
+ def update_proxy(
74
+ proxy_id: int,
75
+ payload: ProxyUpdate,
76
+ request: Request,
77
+ db: Session = Depends(get_db),
78
+ current_user: models.User = Depends(get_current_user),
79
+ ):
80
+ proxy = db.query(models.ProxyConfig).filter(
81
+ models.ProxyConfig.id == proxy_id,
82
+ models.ProxyConfig.user_id == current_user.id,
83
+ ).first()
84
+ if not proxy:
85
+ raise HTTPException(status_code=404, detail="Proxy not found")
86
+
87
+ if payload.name is not None:
88
+ proxy.name = payload.name
89
+ if payload.openai_base_url is not None:
90
+ proxy.openai_base_url = payload.openai_base_url.rstrip("/")
91
+ if payload.openai_api_key is not None:
92
+ proxy.encrypted_api_key = encrypt_api_key(payload.openai_api_key)
93
+ if payload.model_mapping is not None:
94
+ proxy.model_mapping = json.dumps(payload.model_mapping)
95
+
96
+ db.commit()
97
+ db.refresh(proxy)
98
+ return _proxy_out_with_url(proxy, request)
99
+
100
+
101
+ @router.delete("/{proxy_id}", status_code=204)
102
+ def delete_proxy(
103
+ proxy_id: int,
104
+ db: Session = Depends(get_db),
105
+ current_user: models.User = Depends(get_current_user),
106
+ ):
107
+ proxy = db.query(models.ProxyConfig).filter(
108
+ models.ProxyConfig.id == proxy_id,
109
+ models.ProxyConfig.user_id == current_user.id,
110
+ ).first()
111
+ if not proxy:
112
+ raise HTTPException(status_code=404, detail="Proxy not found")
113
+ db.delete(proxy)
114
+ db.commit()
app/routers/proxy_endpoint_router.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Depends, HTTPException, Request
2
+ from fastapi.responses import JSONResponse
3
+ from sqlalchemy.orm import Session
4
+
5
+ from ..database import get_db
6
+ from .. import models
7
+ from ..proxy_handler import handle_messages_request
8
+
9
+ router = APIRouter(tags=["Proxy Endpoint"])
10
+
11
+
12
+ def _get_proxy(token: str, db: Session) -> models.ProxyConfig:
13
+ proxy = db.query(models.ProxyConfig).filter(
14
+ models.ProxyConfig.proxy_token == token
15
+ ).first()
16
+ if not proxy:
17
+ raise HTTPException(status_code=404, detail="Invalid proxy token")
18
+ return proxy
19
+
20
+
21
+ @router.post("/{token}/v1/messages")
22
+ async def messages(
23
+ token: str,
24
+ request: Request,
25
+ db: Session = Depends(get_db),
26
+ ):
27
+ proxy = _get_proxy(token, db)
28
+ try:
29
+ body = await request.json()
30
+ except Exception:
31
+ raise HTTPException(status_code=400, detail="Invalid JSON body")
32
+
33
+ result = await handle_messages_request(body, proxy)
34
+ if isinstance(result, dict):
35
+ return JSONResponse(content=result)
36
+ return result
37
+
38
+
39
+ @router.get("/{token}/v1/models")
40
+ def models_list(token: str, db: Session = Depends(get_db)):
41
+ _get_proxy(token, db)
42
+ return JSONResponse(content={
43
+ "object": "list",
44
+ "data": [
45
+ {"id": "claude-3-opus-20240229", "object": "model"},
46
+ {"id": "claude-3-sonnet-20240229", "object": "model"},
47
+ {"id": "claude-3-haiku-20240307", "object": "model"},
48
+ {"id": "claude-3-5-sonnet-20240620","object": "model"},
49
+ ],
50
+ })