Spaces:
Running
Running
File size: 4,069 Bytes
2889205 e4e9ad6 2889205 e4e9ad6 b0e1d6e e4e9ad6 2889205 e4e9ad6 7f84064 2889205 7f84064 2889205 177a238 2889205 dd4dc21 7f84064 e4e9ad6 dd4dc21 e4e9ad6 dd4dc21 e4e9ad6 dd4dc21 65e323a 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 |
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
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 timestamp = moment().tz("Asia/Tbilisi").format("DD-MMM-YYYY HH:mm");
const displayKey = req.apiKey.substring(0, 4);
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 text "${requestData.text}"`;
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
}); |