Skip to content

Commit be76d69

Browse files
committed
move python runtime/extension to independent package
1 parent 4776637 commit be76d69

File tree

11 files changed

+203
-80
lines changed

11 files changed

+203
-80
lines changed

.changeset/little-trains-begin.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
"@trigger.dev/build": minor
2+
"@trigger.dev/python": minor
33
---
44

55
Introduced a new Python extension to enhance the build process. It now allows users to execute Python scripts with improved support and error handling.

packages/build/package.json

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
"./extensions/prisma": "./src/extensions/prisma.ts",
2929
"./extensions/audioWaveform": "./src/extensions/audioWaveform.ts",
3030
"./extensions/typescript": "./src/extensions/typescript.ts",
31-
"./extensions/python": "./src/extensions/python.ts",
3231
"./extensions/puppeteer": "./src/extensions/puppeteer.ts"
3332
},
3433
"sourceDialects": [
@@ -52,9 +51,6 @@
5251
"extensions/typescript": [
5352
"dist/commonjs/extensions/typescript.d.ts"
5453
],
55-
"extensions/python": [
56-
"dist/commonjs/extensions/python.d.ts"
57-
],
5854
"extensions/puppeteer": [
5955
"dist/commonjs/extensions/puppeteer.d.ts"
6056
]
@@ -70,9 +66,7 @@
7066
},
7167
"dependencies": {
7268
"@trigger.dev/core": "workspace:3.3.16",
73-
"@trigger.dev/sdk": "workspace:3.3.16",
7469
"pkg-types": "^1.1.3",
75-
"tinyexec": "^0.3.2",
7670
"tinyglobby": "^0.2.2",
7771
"tsconfck": "3.1.3"
7872
},
@@ -156,17 +150,6 @@
156150
"default": "./dist/commonjs/extensions/typescript.js"
157151
}
158152
},
159-
"./extensions/python": {
160-
"import": {
161-
"@triggerdotdev/source": "./src/extensions/python.ts",
162-
"types": "./dist/esm/extensions/python.d.ts",
163-
"default": "./dist/esm/extensions/python.js"
164-
},
165-
"require": {
166-
"types": "./dist/commonjs/extensions/python.d.ts",
167-
"default": "./dist/commonjs/extensions/python.js"
168-
}
169-
},
170153
"./extensions/puppeteer": {
171154
"import": {
172155
"@triggerdotdev/source": "./src/extensions/puppeteer.ts",

packages/python/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# @trigger.dev/python

packages/python/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Trigger.dev
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/python/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Official Python extension for Trigger.dev
2+
3+
View the full documentation [here](https://trigger.dev/docs)

packages/python/package.json

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"name": "@trigger.dev/python",
3+
"version": "3.3.16",
4+
"description": "Python runtime and build extension for Trigger.dev",
5+
"license": "MIT",
6+
"publishConfig": {
7+
"access": "public"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/triggerdotdev/trigger.dev",
12+
"directory": "packages/python"
13+
},
14+
"type": "module",
15+
"files": [
16+
"dist"
17+
],
18+
"tshy": {
19+
"selfLink": false,
20+
"main": true,
21+
"module": true,
22+
"project": "./tsconfig.src.json",
23+
"exports": {
24+
"./package.json": "./package.json",
25+
".": "./src/index.ts",
26+
"./extension": "./src/extension.ts"
27+
},
28+
"sourceDialects": [
29+
"@triggerdotdev/source"
30+
]
31+
},
32+
"typesVersions": {
33+
"*": {
34+
"extension": [
35+
"dist/commonjs/extension.d.ts"
36+
]
37+
}
38+
},
39+
"scripts": {
40+
"clean": "rimraf dist",
41+
"build": "tshy && pnpm run update-version",
42+
"dev": "tshy --watch",
43+
"typecheck": "tsc --noEmit -p tsconfig.src.json",
44+
"update-version": "tsx ../../scripts/updateVersion.ts",
45+
"check-exports": "attw --pack ."
46+
},
47+
"dependencies": {
48+
"@trigger.dev/build": "workspace:3.3.16",
49+
"@trigger.dev/core": "workspace:3.3.16",
50+
"@trigger.dev/sdk": "workspace:3.3.16",
51+
"tinyexec": "^0.3.2"
52+
},
53+
"devDependencies": {
54+
"@types/node": "20.14.14",
55+
"rimraf": "6.0.1",
56+
"tshy": "^3.0.2",
57+
"typescript": "^5.5.4",
58+
"tsx": "4.17.0",
59+
"esbuild": "^0.23.0",
60+
"@arethetypeswrong/cli": "^0.15.4"
61+
},
62+
"engines": {
63+
"node": ">=18.20.0"
64+
},
65+
"exports": {
66+
"./package.json": "./package.json",
67+
".": {
68+
"import": {
69+
"@triggerdotdev/source": "./src/index.ts",
70+
"types": "./dist/esm/index.d.ts",
71+
"default": "./dist/esm/index.js"
72+
},
73+
"require": {
74+
"types": "./dist/commonjs/index.d.ts",
75+
"default": "./dist/commonjs/index.js"
76+
}
77+
},
78+
"./extension": {
79+
"import": {
80+
"@triggerdotdev/source": "./src/extension.ts",
81+
"types": "./dist/esm/extension.d.ts",
82+
"default": "./dist/esm/extension.js"
83+
},
84+
"require": {
85+
"types": "./dist/commonjs/extension.d.ts",
86+
"default": "./dist/commonjs/extension.js"
87+
}
88+
}
89+
},
90+
"main": "./dist/commonjs/index.js",
91+
"types": "./dist/commonjs/index.d.ts",
92+
"module": "./dist/esm/index.js"
93+
}

packages/build/src/extensions/python.ts renamed to packages/python/src/extension.ts

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import fs from "node:fs";
22
import assert from "node:assert";
3-
import { additionalFiles } from "./core/additionalFiles.js";
3+
import { additionalFiles } from "@trigger.dev/build/extensions/core";
44
import { BuildManifest } from "@trigger.dev/core/v3";
55
import { BuildContext, BuildExtension } from "@trigger.dev/core/v3/build";
6-
import { logger } from "@trigger.dev/sdk/v3";
7-
import { x, Options as XOptions, Result } from "tinyexec";
86

97
export type PythonOptions = {
108
requirements?: string[];
@@ -118,61 +116,4 @@ class PythonExtension implements BuildExtension {
118116
}
119117
}
120118

121-
export const run = async (
122-
scriptArgs: string[] = [],
123-
options: Partial<XOptions> = {}
124-
): Promise<Result> => {
125-
const pythonBin = process.env.PYTHON_BIN_PATH || "python";
126-
127-
return await logger.trace("Python call", async (span) => {
128-
span.addEvent("Properties", {
129-
command: `${pythonBin} ${scriptArgs.join(" ")}`,
130-
});
131-
132-
const result = await x(pythonBin, scriptArgs, {
133-
...options,
134-
throwOnError: false, // Ensure errors are handled manually
135-
});
136-
137-
span.addEvent("Output", { ...result });
138-
139-
if (result.exitCode !== 0) {
140-
logger.error(result.stderr, { ...result });
141-
throw new Error(`Python command exited with non-zero code ${result.exitCode}`);
142-
}
143-
144-
return result;
145-
});
146-
};
147-
148-
export const runScript = (
149-
scriptPath: string,
150-
scriptArgs: string[] = [],
151-
options: Partial<XOptions> = {}
152-
) => {
153-
assert(scriptPath, "Script path is required");
154-
assert(fs.existsSync(scriptPath), `Script does not exist: ${scriptPath}`);
155-
156-
return run([scriptPath, ...scriptArgs], options);
157-
};
158-
159-
export const runInline = async (scriptContent: string, options: Partial<XOptions> = {}) => {
160-
assert(scriptContent, "Script content is required");
161-
162-
const tmpFile = `/tmp/script_${Date.now()}.py`;
163-
await fs.promises.writeFile(tmpFile, scriptContent, { mode: 0o600 });
164-
165-
try {
166-
return await runScript(tmpFile, [], options);
167-
} finally {
168-
try {
169-
await fs.promises.unlink(tmpFile);
170-
} catch (error) {
171-
logger.warn(`Failed to clean up temporary file ${tmpFile}:`, {
172-
error: (error as Error).stack || (error as Error).message,
173-
});
174-
}
175-
}
176-
};
177-
178-
export default { run, runScript, runInline };
119+
export default pythonExtension;

packages/python/src/index.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import fs from "node:fs";
2+
import assert from "node:assert";
3+
import { logger } from "@trigger.dev/sdk/v3";
4+
import { x, Options as XOptions, Result } from "tinyexec";
5+
6+
export const run = async (
7+
scriptArgs: string[] = [],
8+
options: Partial<XOptions> = {}
9+
): Promise<Result> => {
10+
const pythonBin = process.env.PYTHON_BIN_PATH || "python";
11+
12+
return await logger.trace("Python call", async (span) => {
13+
span.addEvent("Properties", {
14+
command: `${pythonBin} ${scriptArgs.join(" ")}`,
15+
});
16+
17+
const result = await x(pythonBin, scriptArgs, {
18+
...options,
19+
throwOnError: false, // Ensure errors are handled manually
20+
});
21+
22+
span.addEvent("Output", { ...result });
23+
24+
if (result.exitCode !== 0) {
25+
logger.error(result.stderr, { ...result });
26+
throw new Error(`Python command exited with non-zero code ${result.exitCode}`);
27+
}
28+
29+
return result;
30+
});
31+
};
32+
33+
export const runScript = (
34+
scriptPath: string,
35+
scriptArgs: string[] = [],
36+
options: Partial<XOptions> = {}
37+
) => {
38+
assert(scriptPath, "Script path is required");
39+
assert(fs.existsSync(scriptPath), `Script does not exist: ${scriptPath}`);
40+
41+
return run([scriptPath, ...scriptArgs], options);
42+
};
43+
44+
export const runInline = async (scriptContent: string, options: Partial<XOptions> = {}) => {
45+
assert(scriptContent, "Script content is required");
46+
47+
const tmpFile = `/tmp/script_${Date.now()}.py`;
48+
await fs.promises.writeFile(tmpFile, scriptContent, { mode: 0o600 });
49+
50+
try {
51+
return await runScript(tmpFile, [], options);
52+
} finally {
53+
try {
54+
await fs.promises.unlink(tmpFile);
55+
} catch (error) {
56+
logger.warn(`Failed to clean up temporary file ${tmpFile}:`, {
57+
error: (error as Error).stack || (error as Error).message,
58+
});
59+
}
60+
}
61+
};
62+
63+
export default { run, runScript, runInline };

packages/python/tsconfig.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "../../.configs/tsconfig.base.json",
3+
"references": [
4+
{
5+
"path": "./tsconfig.src.json"
6+
}
7+
]
8+
}

packages/python/tsconfig.src.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"include": ["./src/**/*.ts"],
4+
"compilerOptions": {
5+
"isolatedDeclarations": false,
6+
"composite": true,
7+
"sourceMap": true,
8+
"customConditions": ["@triggerdotdev/source"]
9+
}
10+
}

references/v3-catalog/trigger.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ffmpeg, syncEnvVars } from "@trigger.dev/build/extensions/core";
77
import { puppeteer } from "@trigger.dev/build/extensions/puppeteer";
88
import { prismaExtension } from "@trigger.dev/build/extensions/prisma";
99
import { emitDecoratorMetadata } from "@trigger.dev/build/extensions/typescript";
10-
import { pythonExtension } from "@trigger.dev/build/extensions/python";
10+
import { pythonExtension } from "@trigger.dev/python/extension";
1111
import { defineConfig } from "@trigger.dev/sdk/v3";
1212

1313
export { handleError } from "./src/handleError.js";

0 commit comments

Comments
 (0)