Skip to content

Commit 48c11dc

Browse files
authored
Merge pull request #1 from RRosio/make-btn
add make button to run artifact commands
2 parents bdd2d38 + ab75a00 commit 48c11dc

File tree

14 files changed

+1499
-91
lines changed

14 files changed

+1499
-91
lines changed

jupyter_projspec/routes.py

Lines changed: 470 additions & 31 deletions
Large diffs are not rendered by default.

jupyter_projspec/tests/test_routes.py

Lines changed: 601 additions & 0 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jupyter-projspec",
3-
"version": "0.1.0",
3+
"version": "0.2.0",
44
"description": "A Jupyter interface for projspec",
55
"keywords": [
66
"jupyter",

src/api.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { ServerConnection } from '@jupyterlab/services';
2+
import { requestAPI } from './request';
3+
4+
/**
5+
* Request body for the make endpoint.
6+
* Sends artifact identifiers instead of raw commands for security.
7+
*/
8+
export interface IMakeRequest {
9+
/** Relative path from server root (empty string for root). */
10+
path: string;
11+
/** The projspec spec type (e.g., "python_library", "node"). */
12+
spec_type: string;
13+
/** The artifact name (e.g., "wheel", "build"). */
14+
artifact_name: string;
15+
}
16+
17+
/**
18+
* Response from the make endpoint.
19+
*/
20+
interface IMakeResponse {
21+
stdout: string;
22+
stderr: string;
23+
returncode: number;
24+
/** True when stdout or stderr was truncated by the server. */
25+
truncated: boolean;
26+
}
27+
28+
/**
29+
* Execute an artifact's build command via the backend.
30+
*
31+
* The backend resolves the actual shell command from projspec's artifact
32+
* registry, ensuring only valid, known commands can be executed.
33+
*
34+
* @param request - Artifact identifiers (path, spec_type, artifact_name)
35+
* @returns The command execution result with stdout, stderr, and returncode
36+
*/
37+
export async function make(request: IMakeRequest): Promise<IMakeResponse> {
38+
try {
39+
const response = await requestAPI<IMakeResponse>('make', {
40+
method: 'POST',
41+
headers: { 'Content-Type': 'application/json' },
42+
body: JSON.stringify(request)
43+
});
44+
if (response === undefined) {
45+
throw new Error('Make request returned an empty response');
46+
}
47+
return response;
48+
} catch (err) {
49+
if (err instanceof ServerConnection.ResponseError) {
50+
const status = err.response.status;
51+
let detail = err.message;
52+
53+
// Truncate HTML responses for cleaner error messages
54+
if (
55+
typeof detail === 'string' &&
56+
(detail.includes('<!DOCTYPE') || detail.includes('<html'))
57+
) {
58+
detail = `HTML error page (${detail.substring(0, 100)}...)`;
59+
}
60+
61+
throw new Error(`Make request failed (${status}): ${detail}`);
62+
}
63+
64+
const msg = err instanceof Error ? err.message : 'Unknown error';
65+
throw new Error(`Make request failed: ${msg}`);
66+
}
67+
}

0 commit comments

Comments
 (0)