Page tree
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 24 Next »

modules/FetchEventSource.js
const { fetch, Headers, Request, Response } = require('fetch-undici');

if (!globalThis.fetch) {
    globalThis.fetch = fetch;
    globalThis.Headers = Headers;
    globalThis.Request = Request;
    globalThis.Response = Response;
}

module.exports = require('@waylaidwanderer/fetch-event-source');
server.js
const express = require('express');
const bodyParser = require('body-parser');
const { fetchEventSource } = require('./modules/FetchEventSource');

const GPT_API_URL = ''; // API URL ex) 'https://api.openai.com/v1/chat/completions'
const GPT_API_KEY = ''; // API KEY

const app = express();
const router = express.Router();

router.post('/request', (request, response) => {
    const bodyData = Object.assign({}, request.body, {
        model: 'gpt-3.5-turbo',
        stream: true
    });

    requestGPT(response, bodyData)
        .then(() => response.end())
        .catch((error) => response.status(error.status).json(error).end());
});

/**
 * GPT 서버로 요청합니다.
 * @param {Response} response
 * @param {Object} bodyData
 * @returns {Promise}
 */
function requestGPT(response, bodyData) {
    const abortController = new AbortController();
    return new Promise(async (resolve, reject) => {
        try {
            await fetchEventSource(GPT_API_URL, {
                method: 'post',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${GPT_API_KEY}` // OpenAI
                    // 'Api-Key': GPT_API_KEY` // Azure OpenAI
                },
                body: JSON.stringify(bodyData),
                signal: abortController.signal,
                onopen: async (openResponse) => {
                    if (openResponse.status === 200) {
                        response.on('close', () => {
                            abortController.abort();
                            resolve();
                        });
                        response.set({
                            'Cache-Control': 'no-cache',
                            'Connection': 'keep-alive',
                            'Content-Type': 'text/event-stream'
                        });
                        response.flushHeaders();
                        return;
                    }
                    let error;
                    try {
                        const json = await openResponse.json();
                        error = json;
                    } catch (e) {
                        error = e;
                    }
                    error.status = openResponse.status;
                    throw error;
                },
                onclose: () => resolve(),
                onerror: (error) => {
                    reject(error);
                    throw error;
                },
                onmessage: (message) => {
                    if (!message.data || message.event === 'ping') {
                        return;
                    }
                    response.write('data:' + message.data + '\n\n');
                },
            });
        } catch (e) {
            reject(e);
        }
    });
}

app.use(bodyParser.json());
app.use('/', router);
app.listen(8080);
  • DALL-E

server.js
const express = require('express');
const axios = require('axios');
const bodyParser = require('body-parser');

const DALLE_URL = ''; // API URL ex) 'https://api.openai.com/v1/images/generations'
const DALLE_API_KEY = ''; // API KEY

const app = express();
const router = express.Router();

router.post('/request', (request, response) => {
    const bodyData = request.body;

    requestDALLEServer(response, bodyData)
        .then(() => response.end())
        .catch((error) => response.status(error.status).json(error).end());
});

/**
 * DALL·E 서버로 요청을 합니다.
 * @param {Response} response
 * @param {Object} bodyData 
 * @returns {Promise}
 */
function requestDALLEServer(response, bodyData) {
    const source = axios.CancelToken.source();
    const url = DALLE_URL;

    return new Promise((resolve, reject) => {
        try {
            axios.post(url, body, {
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${DALLE_API_KEY}`
                },
                responseType: 'stream',
                cancelToken: source.token
            }).then(response => {
                response.data.pipe(response);
            }).catch(error => {
                reject({
                    status: error.response ? error.response.status : 500,
                    message: error.message
                });
            });

            response.on('close', () => {
                source.cancel('요청을 취소합니다.');
                resolve();
            });
        } catch (e) {
            reject(e);
        }
    });
}


app.use(bodyParser.json());
app.use('/', router);
app.listen(8080);
  • 하이퍼클로바 X
server.js
const express = require('express');
const axios = require('axios');
const bodyParser = require('body-parser');

const HCX_API_URL = ''; // API URL - CLOVA Studio에서 url 확인 ex)https://clovastudio.apigw.ntruss.com/testapp/v1/chat-completions/HCX-003
const HCX_API_KEY = ''; // API KEY
const HCX_GATEWAY_KEY = '';// GATEWAY KEY

const app = express();
const router = express.Router();

router.post('/request', (request, response) => {
    const bodyData = request.body;

    requestHCX(response, bodyData)
        .then(() => response.end())
        .catch(err => {
        	console.error('[ERROR] requestHCX chat completion failed: ' + err);
            return response.status(err.status || 500).json(err).end();
        });
});

/**
 * 하이퍼클로바 X 서버로 요청합니다.
 * @param {Response} response
 * @param {Object} body
 * @returns {Promise}
 */
function requestHCX(response, bodyData) {
    const source = axios.CancelToken.source();
    const url = HCX_API_URL;
	const headers= {
		'Content-Type': 'application/json',
        'Accept': 'text/event-stream',
		'X-NCP-CLOVASTUDIO-API-KEY': HCX_API_KEY,
        'X-NCP-APIGW-API-KEY': HCX_GATEWAY_KEY
	}
    return new Promise(async (resolve, reject) => {
        try {
            axios.post(url, bodyData, {
                headers,
                responseType: 'stream',
                cancelToken: source.token
            }).then(hcxRes => {
                hcxRes.data.pipe(response);
            }).catch(reject);

            response.on('close', () => {
                source.cancel('요청을 취소합니다.');
                resolve();
            });
        } catch (e) {
            reject(e);
        }
    });
}

app.use(bodyParser.json());
app.use('/', router);
app.listen(8080);




  • No labels