-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathindex.ts
More file actions
103 lines (93 loc) · 2.42 KB
/
Copy pathindex.ts
File metadata and controls
103 lines (93 loc) · 2.42 KB
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
import {
Config,
HandleRequest,
HttpRequest,
HttpResponse,
InferencingOptions,
Llm,
Router,
} from "@fermyon/spin-sdk";
/** Returns true if a valid authorization header is provided. */
function isValidRequest(headers: Record<string, string>): boolean {
if (headers["authorization"] === `bearer ${Config.get("auth_token")}`) {
return true;
}
return false;
}
/** Response for unauthorized requests. */
const unauthorized = {
status: 403,
body: "Please provide valid authorization header",
};
/** Response for bad requests. */
const badRequest = {
status: 400,
body: "Please provide valid JSON in the request body",
};
/** Proxy a call to the Fermyon Serverless AI. */
function proxy<T, R>(
data: HttpRequest,
operationType: string,
exec: (params: T) => R
): HttpResponse {
if (!isValidRequest(data.headers)) {
console.log("403 - Unauthorized");
return unauthorized;
}
try {
let params = data.json() as T;
let response = exec(params);
console.log(`200 - ${operationType} successful`);
return {
status: 200,
headers: { "content-type": "text/html" },
body: JSON.stringify(response),
};
} catch (error) {
console.log("400 - Bad request");
return badRequest;
}
}
/** The expected input parameters for an inference request. */
interface InferenceParams {
model: string;
prompt: string;
options?: InferencingOptions;
}
/** Handle the proxying of an inference request. */
function infer(data: HttpRequest): HttpResponse {
return proxy(data, "Inference", (params: InferenceParams) => {
return Llm.infer(params.model, params.prompt, params.options);
});
}
/** The expected input parameters for an embedding request. */
interface EmbeddingParams {
model: string;
input: string[];
}
/** Handle the proxying of an embedding request. */
function embed(data: HttpRequest): HttpResponse {
return proxy(data, "Embedding", (params: EmbeddingParams) => {
return Llm.generateEmbeddings(params.model, params.input);
});
}
// Setup routing logic
let router = Router();
router.post("/infer", (_, req) => {
return infer(req);
});
router.post("/embed", (_, req) => {
return embed(req);
});
// Catch all 404
router.all("*", () => {
return {
status: 404
}
})
// Entrypoint to Spin app
export const handleRequest: HandleRequest = async function (
request: HttpRequest
): Promise<HttpResponse> {
return await router.handleRequest(request, request);
};