Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/client/api.ts
Views: 687
/*1Use the api v2 endpoint from the app frontend. This is everything defined2in @cocalc/next/pages/api/v234We always use POST requests here.56The v1 api is also exported here.78This doesn't know anything about types, etc.9*/1011import { join } from "path";12import { appBasePath } from "@cocalc/frontend/customize/app-base-path";13import { delay } from "awaiting";14import { trunc } from "@cocalc/util/misc";1516export default async function api(endpoint: string, args?: object) {17return await callApi(join("v2", endpoint), args);18}1920// also the old v1 api21export async function v1(endpoint: string, args?: object) {22return await callApi(join("v1", endpoint), args);23}2425// if api call fails (typically 5xx due to a temporary restart of26// backend servers e.g., in kubernetes) we wait RETRY_DELAY_MS, then give27// it NUM_RETRIES many ties before showing the user an error.28// Setting the third numRetriesOnFail argument to 0 below29// can be used to disable this behavior.30// This "api call fails" isn't where you get an error json31// back, but when actually making the request really is32// failing, e.g., due to network or server issues.33const RETRY_DELAY_MS = 2000;34const NUM_RETRIES = 3;3536// NOTE: I made this complicated with respClone, so I can see37// what the response is if it is not JSON.38async function callApi(39endpoint: string,40args?: object,41numRetriesOnFail?: number,42) {43const url = join(appBasePath, "api", endpoint);44const resp = await fetch(url, {45method: "POST",46headers: {47"Content-Type": "application/json",48},49...(args != null ? { body: JSON.stringify(args) } : undefined),50});51const respClone = resp.clone();52let json: any = null;53try {54json = await resp.json();55} catch (e) {56console.log(e);57const r = await respClone.text();58console.log(trunc(r, 2000));59if (numRetriesOnFail != null && numRetriesOnFail == 0) {60throw Error("API server is down -- try again later");61}62numRetriesOnFail = numRetriesOnFail ?? NUM_RETRIES;63console.log(64`waiting 3s then trying again up to ${numRetriesOnFail} more times`,65);66await delay(RETRY_DELAY_MS);67return await callApi(endpoint, args, numRetriesOnFail - 1);68}69if (json == null) {70throw Error("timeout -- try again later");71}72if (typeof json == "object" && json.error) {73throw Error(json.error);74}75return json;76}777879