Spaces:
Running
Running
File size: 4,585 Bytes
2889205 e4e9ad6 2889205 e4e9ad6 b0e1d6e e4e9ad6 2889205 e4e9ad6 7f84064 2889205 7f84064 2889205 177a238 2889205 e5b45d3 dd4dc21 7f84064 e4e9ad6 dd4dc21 e4e9ad6 dd4dc21 e4e9ad6 dd4dc21 65e323a dd4dc21 e5b45d3 dd4dc21 e5b45d3 dd4dc21 e5b45d3 dd4dc21 65e323a dd4dc21 65e323a 3e0d39c 177a238 dd4dc21 3e0d39c e4e9ad6 177a238 65e323a d5b575b 65e323a 315c31e 65e323a 2889205 e4e9ad6 dd4dc21 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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
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);
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'
];
let requestDetails = [];
let apiKeyDetails = {}; // Track API key usage and first use timestamp
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); // Only use the first four characters for display
if (!apiKeyDetails[apiKeyMatch]) {
apiKeyDetails[apiKeyMatch] = {
count: 0,
firstUse: moment() // Set the first use to now if it's not already set
};
}
// Check if more than a week has passed since the first use
if (moment().diff(apiKeyDetails[apiKeyMatch].firstUse, 'weeks') >= 1) {
return res.status(429).send(`API Key ${displayKey}... is blocked after one week of use.`);
}
// Increment the request count
apiKeyDetails[apiKeyMatch].count++;
const logMessage = `API Key ${displayKey}... used ${apiKeyDetails[apiKeyMatch].count} times so far.`;
logAndEmit(logMessage, true);
req.apiKey = apiKeyMatch; // Store the API key for the request
next();
}
app.use('/api', authenticateApiKey, (req, res, next) => {
const urlParts = req.url.split('/');
const modelId = urlParts.length > 1 ? urlParts[1] : null;
// Check if the model ID is part of the allowed models.
if (!modelId || !allowedModels.includes(modelId)) {
return res.status(403).send("Access Denied: This model is not allowed.");
}
const timestamp = moment().tz("Asia/Tbilisi").format("DD-MMM-YYYY HH:mm");
const displayKey = req.apiKey.substring(0, 10);
const requestData = {
requestNumber: apiKeyDetails[req.apiKey].count,
apiKey: displayKey,
timestamp: timestamp,
text: req.method + ' ' + req.url
};
requestDetails.push(requestData);
const detailedLog = `Request ${requestData.requestNumber} on ${requestData.timestamp} from API Key ${displayKey}... with method "${req.method}" and URL line "${req.url}"`;
logAndEmit(detailedLog, true);
next();
}, proxy(targetUrl, {
proxyReqOptDecorator: function(proxyReqOpts, srcReq) {
proxyReqOpts.headers['Authorization'] = 'Bearer ' + openaiKey;
return proxyReqOpts;
}
}));
app.get("/", (req, res) => {
let requestsInfo = requestDetails.map(detail =>
`Request ${detail.requestNumber} on ${detail.timestamp} from API Key ${detail.apiKey}... with text "${detail.text}"`).join('<br>');
res.send(`This is your OpenAI Reverse Proxy URL: ${baseUrl}.<br><br>Requests Overview:<br>${requestsInfo}`);
});
app.get('/logs', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
function getExternalUrl(spaceId) {
try {
const [username, spacename] = spaceId.split("/");
return `https://${username}-${spacename.replace(/_/g, "-")}.hf.space/api/v1`;
} catch (e) {
return "Error generating external URL";
}
}
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
}); |