smgc commited on
Commit
0b4f475
·
verified ·
1 Parent(s): b498206

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -20
app.py CHANGED
@@ -3,14 +3,19 @@ import time
3
  import json
4
  import asyncio
5
  import aiohttp
 
6
  from aiohttp import web
7
 
 
 
 
 
8
  PROJECT_ID = os.getenv('PROJECT_ID')
9
  CLIENT_ID = os.getenv('CLIENT_ID')
10
  CLIENT_SECRET = os.getenv('CLIENT_SECRET')
11
  REFRESH_TOKEN = os.getenv('REFRESH_TOKEN')
12
  API_KEY = os.getenv('API_KEY')
13
- MODEL = 'claude-3-5-sonnet@20240620' # 直接在代码中指定 MODEL
14
 
15
  TOKEN_URL = 'https://www.googleapis.com/oauth2/v4/token'
16
 
@@ -24,13 +29,16 @@ async def get_access_token():
24
  now = time.time()
25
 
26
  if token_cache['access_token'] and now < token_cache['expiry'] - 120:
 
27
  return token_cache['access_token']
28
 
29
  if token_cache['refresh_promise']:
 
30
  await token_cache['refresh_promise']
31
  return token_cache['access_token']
32
 
33
  async def refresh_token():
 
34
  async with aiohttp.ClientSession() as session:
35
  async with session.post(TOKEN_URL, json={
36
  'client_id': CLIENT_ID,
@@ -41,6 +49,7 @@ async def get_access_token():
41
  data = await response.json()
42
  token_cache['access_token'] = data['access_token']
43
  token_cache['expiry'] = now + data['expires_in']
 
44
 
45
  token_cache['refresh_promise'] = refresh_token()
46
  await token_cache['refresh_promise']
@@ -49,10 +58,14 @@ async def get_access_token():
49
 
50
  def get_location():
51
  current_seconds = time.localtime().tm_sec
52
- return 'europe-west1' if current_seconds < 30 else 'us-east5'
 
 
53
 
54
  def construct_api_url(location, model):
55
- return f'https://{location}-aiplatform.googleapis.com/v1/projects/{PROJECT_ID}/locations/{location}/publishers/anthropic/models/{model}:streamRawPredict'
 
 
56
 
57
  def format_model_name(model):
58
  if model == 'claude-3-5-sonnet-20240620':
@@ -60,32 +73,33 @@ def format_model_name(model):
60
  return model
61
 
62
  async def handle_request(request):
 
 
63
  if request.method == 'OPTIONS':
 
64
  return handle_options()
65
 
66
  api_key = request.headers.get('x-api-key')
67
  if api_key != API_KEY:
68
- error_response = web.Response(
69
- text=json.dumps({
70
- 'type': 'error',
71
- 'error': {
72
- 'type': 'permission_error',
73
- 'message': 'Your API key does not have permission to use the specified resource.'
74
- }
75
- }),
76
- status=403,
77
- content_type='application/json'
78
- )
79
- error_response.headers['Access-Control-Allow-Origin'] = '*'
80
- error_response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, DELETE, HEAD'
81
- error_response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, x-api-key, anthropic-version, model'
82
- return error_response
83
 
84
  access_token = await get_access_token()
85
  location = get_location()
86
 
87
- request_body = await request.json()
88
- model = format_model_name(request_body.get('model', MODEL)) # 使用 format_model_name 处理模型名称
89
 
90
  if 'anthropic_version' in request_body:
91
  del request_body['anthropic_version']
@@ -101,11 +115,13 @@ async def handle_request(request):
101
  'Content-Type': 'application/json; charset=utf-8'
102
  }
103
 
 
104
  async with aiohttp.ClientSession() as session:
105
  async with session.post(api_url, json=request_body, headers=headers) as response:
106
  response_body = await response.read()
107
  response_headers = response.headers
108
  response_status = response.status
 
109
 
110
  modified_response = web.Response(
111
  body=response_body,
@@ -116,9 +132,29 @@ async def handle_request(request):
116
  modified_response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
117
  modified_response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, x-api-key, anthropic-version, model'
118
 
 
119
  return modified_response
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  def handle_options():
 
122
  headers = {
123
  'Access-Control-Allow-Origin': '*',
124
  'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
@@ -130,4 +166,5 @@ app = web.Application()
130
  app.router.add_route('*', '/ai/v1/messages', handle_request)
131
 
132
  if __name__ == '__main__':
 
133
  web.run_app(app, port=8080)
 
3
  import json
4
  import asyncio
5
  import aiohttp
6
+ import logging
7
  from aiohttp import web
8
 
9
+ # 设置日志
10
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
11
+ logger = logging.getLogger(__name__)
12
+
13
  PROJECT_ID = os.getenv('PROJECT_ID')
14
  CLIENT_ID = os.getenv('CLIENT_ID')
15
  CLIENT_SECRET = os.getenv('CLIENT_SECRET')
16
  REFRESH_TOKEN = os.getenv('REFRESH_TOKEN')
17
  API_KEY = os.getenv('API_KEY')
18
+ MODEL = 'claude-3-5-sonnet@20240620'
19
 
20
  TOKEN_URL = 'https://www.googleapis.com/oauth2/v4/token'
21
 
 
29
  now = time.time()
30
 
31
  if token_cache['access_token'] and now < token_cache['expiry'] - 120:
32
+ logger.info("Using cached access token")
33
  return token_cache['access_token']
34
 
35
  if token_cache['refresh_promise']:
36
+ logger.info("Waiting for ongoing token refresh")
37
  await token_cache['refresh_promise']
38
  return token_cache['access_token']
39
 
40
  async def refresh_token():
41
+ logger.info("Refreshing access token")
42
  async with aiohttp.ClientSession() as session:
43
  async with session.post(TOKEN_URL, json={
44
  'client_id': CLIENT_ID,
 
49
  data = await response.json()
50
  token_cache['access_token'] = data['access_token']
51
  token_cache['expiry'] = now + data['expires_in']
52
+ logger.info("Access token refreshed successfully")
53
 
54
  token_cache['refresh_promise'] = refresh_token()
55
  await token_cache['refresh_promise']
 
58
 
59
  def get_location():
60
  current_seconds = time.localtime().tm_sec
61
+ location = 'europe-west1' if current_seconds < 30 else 'us-east5'
62
+ logger.info(f"Selected location: {location}")
63
+ return location
64
 
65
  def construct_api_url(location, model):
66
+ url = f'https://{location}-aiplatform.googleapis.com/v1/projects/{PROJECT_ID}/locations/{location}/publishers/anthropic/models/{model}:streamRawPredict'
67
+ logger.info(f"Constructed API URL: {url}")
68
+ return url
69
 
70
  def format_model_name(model):
71
  if model == 'claude-3-5-sonnet-20240620':
 
73
  return model
74
 
75
  async def handle_request(request):
76
+ logger.info(f"Received {request.method} request to {request.path}")
77
+
78
  if request.method == 'OPTIONS':
79
+ logger.info("Handling OPTIONS request")
80
  return handle_options()
81
 
82
  api_key = request.headers.get('x-api-key')
83
  if api_key != API_KEY:
84
+ logger.warning("Invalid API key")
85
+ return create_error_response('Your API key does not have permission to use the specified resource.', 403)
86
+
87
+ try:
88
+ request_body = await request.json()
89
+ logger.info(f"Received request body: {json.dumps(request_body)}")
90
+ except json.JSONDecodeError:
91
+ logger.error("Invalid JSON in request body")
92
+ return create_error_response('Invalid JSON in request body', 400)
93
+
94
+ if not request_body:
95
+ logger.error("Empty request body")
96
+ return create_error_response('Empty request body', 400)
 
 
97
 
98
  access_token = await get_access_token()
99
  location = get_location()
100
 
101
+ model = format_model_name(request_body.get('model', MODEL))
102
+ logger.info(f"Using model: {model}")
103
 
104
  if 'anthropic_version' in request_body:
105
  del request_body['anthropic_version']
 
115
  'Content-Type': 'application/json; charset=utf-8'
116
  }
117
 
118
+ logger.info(f"Sending request to Anthropic API: {api_url}")
119
  async with aiohttp.ClientSession() as session:
120
  async with session.post(api_url, json=request_body, headers=headers) as response:
121
  response_body = await response.read()
122
  response_headers = response.headers
123
  response_status = response.status
124
+ logger.info(f"Received response from Anthropic API. Status: {response_status}")
125
 
126
  modified_response = web.Response(
127
  body=response_body,
 
132
  modified_response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
133
  modified_response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, x-api-key, anthropic-version, model'
134
 
135
+ logger.info("Sending response back to client")
136
  return modified_response
137
 
138
+ def create_error_response(message, status_code):
139
+ logger.error(f"Creating error response: {message} (Status: {status_code})")
140
+ response = web.Response(
141
+ text=json.dumps({
142
+ 'type': 'error',
143
+ 'error': {
144
+ 'type': 'request_error',
145
+ 'message': message
146
+ }
147
+ }),
148
+ status=status_code,
149
+ content_type='application/json'
150
+ )
151
+ response.headers['Access-Control-Allow-Origin'] = '*'
152
+ response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, DELETE, HEAD'
153
+ response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, x-api-key, anthropic-version, model'
154
+ return response
155
+
156
  def handle_options():
157
+ logger.info("Handling OPTIONS request")
158
  headers = {
159
  'Access-Control-Allow-Origin': '*',
160
  'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
 
166
  app.router.add_route('*', '/ai/v1/messages', handle_request)
167
 
168
  if __name__ == '__main__':
169
+ logger.info("Starting server on port 8080")
170
  web.run_app(app, port=8080)