Building a GenAI Service
The Reason
-
The Gemini API is undoubtedly the best free LLM API, with a large quota and few restrictions.
-
I used to think that it was not compatible with the OpenAI API.
-
Yesterday, I accidentally saw on the official website of the Gemini API that if you use the following base_url:
βhttps://generativelanguage.googleapis.com/v1beta/openai/β
You can use the OpenAI library (Python and TypeScript/JavaScript) and the REST API to access the Gemini model.
-
This makes the Gemini API much more playable π.
Building the Service
- The first thing I thought of was to deploy it on Deno Deploy, so I can connect directly after reverse proxying π.
- This time I didnβt use Claude 3.5 sonnet, but Gemini-1.5-pro, after all, itβs their own thing.
- The funny thing is, at the beginning, Gemini flatly denied the existence of such a compatible API;
- I directly threw the base_url to it, and then it started to work;
- After writing the code, it kept reminding me that this compatible API may not exist, so the code may not work properly, and I should use Geminiβs own API instead. π
- Fortunately, it only ran into an error once before it worked normally. It is indeed one of the top three LLMs at present π.
Source Code
-
The code was all written by Gemini and entered directly in the Deno Deploy playground;
-
Then go to settings to set two environment variables:
- REAL_GEMINI_API_KEY is your real Gemini API key;
- CUSTOM_AUTH_KEY is the verification code used to replace the real Gemini API key;
-
In this way, when using this reverse proxy API, you can hide your own real Gemini API key and add a layer of security protection.
-
The code is as follows:
const GEMINI_API_BASE_URL = "https://generativelanguage.googleapis.com/";
const CUSTOM_AUTH_KEY = Deno.env.get("CUSTOM_AUTH_KEY");
const REAL_GEMINI_API_KEY = Deno.env.get("REAL_GEMINI_API_KEY");
const OPENAI_COMPATIBLE_PREFIX = "/v1beta/openai";
Deno.serve(async (request) => {
const url = new URL(request.url);
// 1. Verify the user's API key
const authHeader = request.headers.get("Authorization");
if (!authHeader?.startsWith("Bearer ") || authHeader.substring(7) !== CUSTOM_AUTH_KEY) {
return new Response("Unauthorized: Invalid API key", { status: 401 });
}
// 2. Build the new URL
const newPathname = url.pathname.startsWith(OPENAI_COMPATIBLE_PREFIX)
? url.pathname.substring(OPENAI_COMPATIBLE_PREFIX.length)
: url.pathname;
const newURL = new URL(OPENAI_COMPATIBLE_PREFIX + newPathname, GEMINI_API_BASE_URL);
// 3. Modify the request headers
const headers = new Headers(request.headers);
headers.set("Authorization", `Bearer ${REAL_GEMINI_API_KEY}`);
// 4. Create a new request and forward it
const newRequest = new Request(newURL.toString(), {
method: request.method,
headers: headers,
body: request.body,
redirect: "follow",
});
// 5. Forward the request and return the response
const response = await fetch(newRequest);
return new Response(response.body, {
status: response.status,
headers: response.headers,
});
});