Spaces:
Running
Running
File size: 3,249 Bytes
2889205 e4e9ad6 2889205 e4e9ad6 b0e1d6e e4e9ad6 2889205 e4e9ad6 7f84064 2889205 7f84064 2889205 177a238 2889205 c4cb864 cb7ac8f c4cb864 cb7ac8f e5b45d3 e4e9ad6 dd4dc21 e4e9ad6 dd4dc21 cb7ac8f dd4dc21 c4cb864 dd4dc21 c4cb864 dd4dc21 65e323a dd4dc21 cb7ac8f dd4dc21 cb7ac8f c4cb864 dd4dc21 cb7ac8f e5b45d3 cb7ac8f dd4dc21 cb7ac8f dd4dc21 65e323a 3e0d39c cb7ac8f 2889205 e4e9ad6 dd4dc21 cb7ac8f 3e0d39c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
const express = require('express');
const http = require('http');
const proxy = require('express-http-proxy');
const socketIo = require('socket.io');
const moment = require('moment-timezone');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
const targetUrl = 'https://api.openai.com';
const openaiKey = process.env.OPENAI_KEY;
const port = 7860;
const baseUrl = getExternalUrl(process.env.SPACE_ID);
let requestDetails = [];
let apiKeyDetails = {}; // Track API key usage and first use timestamp
// Allowed models array
const allowedModels = [
'gpt-3.5-turbo-0125',
'gpt-3.5-turbo',
'gpt-3.5-turbo-1106',
'gpt-3.5-turbo-instruct',
'gpt-3.5-turbo-16k',
'gpt-3.5-turbo-0613',
'gpt-3.5-turbo-16k-0613'
];
io.on('connection', (socket) => {
console.log('A user connected to the websocket for live logs.');
});
function logAndEmit(message, includeTotal = false) {
if (includeTotal) {
const totalRequests = getTotalRequests();
message += ` Total requests so far: ${totalRequests}`;
}
console.log(message);
io.emit('log', message);
}
function getTotalRequests() {
return Object.values(apiKeyDetails).reduce((acc, details) => acc + details.count, 0);
}
function authenticateApiKey(req, res, next) {
const receivedApiKey = req.headers['authorization'];
if (!receivedApiKey) {
return res.status(401).send('Unauthorized: No API key provided');
}
const validApiKeys = (process.env.SECRET_API_KEYS || '').split(',');
const apiKeyMatch = validApiKeys.find(key => `Bearer ${key.trim()}` === receivedApiKey);
if (!apiKeyMatch) {
return res.status(401).send('Unauthorized: API key is invalid');
}
const displayKey = apiKeyMatch.trim().substring(0, 7);
if (!apiKeyDetails[apiKeyMatch]) {
apiKeyDetails[apiKeyMatch] = {
count: 0,
firstUse: moment()
};
}
if (moment().diff(apiKeyDetails[apiKeyMatch].firstUse, 'weeks') >= 1) {
return res.status(429).send(`API Key ${displayKey}... is blocked after one week of use.`);
}
apiKeyDetails[apiKeyMatch].count++;
const logMessage = `API Key ${displayKey}... used ${apiKeyDetails[apiKeyMatch].count} times so far.`;
logAndEmit(logMessage, true);
req.apiKey = apiKeyMatch;
next();
}
function validateModel(req, res, next) {
const pathComponents = req.path.split('/');
const modelUsed = pathComponents.filter(component => allowedModels.includes(component))[0];
if (!modelUsed) {
return res.status(403).send("Access to this model is not allowed.");
}
next();
}
app.use('/api', authenticateApiKey, validateModel, proxy(targetUrl, {
proxyReqPathResolver: function(req) {
return require('url').parse(req.url).path;
},
proxyReqOptDecorator: function(proxyReqOpts, srcReq) {
proxyReqOpts.headers['Authorization'] = 'Bearer ' + openaiKey;
return proxyReqOpts;
}
}));
// Additional server endpoints remain unchanged
server.listen(port, () => {
const message = `Reverse proxy server and WebSocket running on port ${port}`;
logAndEmit(message, true); // true to include total requests in the log
}); |