Skip to content

Commit 98b44bd

Browse files
committed
Add environment variable support
1 parent d6cf9d3 commit 98b44bd

File tree

3 files changed

+94
-8
lines changed

3 files changed

+94
-8
lines changed

docs/config/extensions/pythonExtension.mdx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,32 @@ export const myStreamingScript = task({
151151
},
152152
});
153153
```
154+
155+
## Environment variables
156+
157+
We automatically inject the environment variables in the `process.env` object when running Python scripts. You can access these environment variables in your Python scripts using the `os.environ` dictionary. For example:
158+
159+
```python
160+
import os
161+
162+
print(os.environ["MY_ENV_VAR"])
163+
```
164+
165+
You can also pass additional environment variables to the Python script using the `env` option in the `python.runScript` function. For example:
166+
167+
```ts
168+
import { task } from "@trigger.dev/sdk/v3";
169+
import { python } from "@trigger.dev/python";
170+
171+
export const myScript = task({
172+
id: "my-python-script",
173+
run: async () => {
174+
const result = await python.runScript("./python/my_script.py", ["hello", "world"], {
175+
env: {
176+
MY_ENV_VAR: "my value",
177+
},
178+
});
179+
return result.stdout;
180+
},
181+
});
182+
```

packages/python/src/index.ts

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,26 @@ import fs from "node:fs";
99
import { Result, x, Options as XOptions } from "tinyexec";
1010
import { createTempFileSync, withTempFile } from "./utils/tempFiles.js";
1111

12+
export type PythonExecOptions = Partial<XOptions> & {
13+
env?: { [key: string]: string | undefined };
14+
};
15+
1216
export const python = {
13-
async run(scriptArgs: string[] = [], options: Partial<XOptions> = {}): Promise<Result> {
17+
async run(scriptArgs: string[] = [], options: PythonExecOptions = {}): Promise<Result> {
1418
const pythonBin = process.env.PYTHON_BIN_PATH || "python";
1519

1620
return await logger.trace(
1721
"python.run()",
1822
async (span) => {
1923
const result = await x(pythonBin, scriptArgs, {
2024
...options,
25+
nodeOptions: {
26+
...(options.nodeOptions || {}),
27+
env: {
28+
...process.env,
29+
...options.env,
30+
},
31+
},
2132
throwOnError: false, // Ensure errors are handled manually
2233
});
2334

@@ -48,7 +59,7 @@ export const python = {
4859
async runScript(
4960
scriptPath: string,
5061
scriptArgs: string[] = [],
51-
options: Partial<XOptions> = {}
62+
options: PythonExecOptions = {}
5263
): Promise<Result> {
5364
assert(scriptPath, "Script path is required");
5465
assert(fs.existsSync(scriptPath), `Script does not exist: ${scriptPath}`);
@@ -63,6 +74,13 @@ export const python = {
6374
[scriptPath, ...scriptArgs],
6475
{
6576
...options,
77+
nodeOptions: {
78+
...(options.nodeOptions || {}),
79+
env: {
80+
...process.env,
81+
...options.env,
82+
},
83+
},
6684
throwOnError: false,
6785
}
6886
);
@@ -92,7 +110,7 @@ export const python = {
92110
);
93111
},
94112

95-
async runInline(scriptContent: string, options: Partial<XOptions> = {}): Promise<Result> {
113+
async runInline(scriptContent: string, options: PythonExecOptions = {}): Promise<Result> {
96114
assert(scriptContent, "Script content is required");
97115

98116
return await logger.trace(
@@ -109,6 +127,13 @@ export const python = {
109127
const pythonBin = process.env.PYTHON_BIN_PATH || "python";
110128
const result = await x(pythonBin, [tempFilePath], {
111129
...options,
130+
nodeOptions: {
131+
...(options.nodeOptions || {}),
132+
env: {
133+
...process.env,
134+
...options.env,
135+
},
136+
},
112137
throwOnError: false,
113138
});
114139

@@ -139,11 +164,18 @@ export const python = {
139164
},
140165
// Stream namespace for streaming functions
141166
stream: {
142-
run(scriptArgs: string[] = [], options: Partial<XOptions> = {}): AsyncIterableStream<string> {
167+
run(scriptArgs: string[] = [], options: PythonExecOptions = {}): AsyncIterableStream<string> {
143168
const pythonBin = process.env.PYTHON_BIN_PATH || "python";
144169

145170
const pythonProcess = x(pythonBin, scriptArgs, {
146171
...options,
172+
nodeOptions: {
173+
...(options.nodeOptions || {}),
174+
env: {
175+
...process.env,
176+
...options.env,
177+
},
178+
},
147179
throwOnError: false,
148180
});
149181

@@ -167,7 +199,7 @@ export const python = {
167199
runScript(
168200
scriptPath: string,
169201
scriptArgs: string[] = [],
170-
options: Partial<XOptions> = {}
202+
options: PythonExecOptions = {}
171203
): AsyncIterableStream<string> {
172204
assert(scriptPath, "Script path is required");
173205
assert(fs.existsSync(scriptPath), `Script does not exist: ${scriptPath}`);
@@ -176,6 +208,13 @@ export const python = {
176208

177209
const pythonProcess = x(pythonBin, [scriptPath, ...scriptArgs], {
178210
...options,
211+
nodeOptions: {
212+
...(options.nodeOptions || {}),
213+
env: {
214+
...process.env,
215+
...options.env,
216+
},
217+
},
179218
throwOnError: false,
180219
});
181220

@@ -197,7 +236,7 @@ export const python = {
197236
},
198237
});
199238
},
200-
runInline(scriptContent: string, options: Partial<XOptions> = {}): AsyncIterableStream<string> {
239+
runInline(scriptContent: string, options: PythonExecOptions = {}): AsyncIterableStream<string> {
201240
assert(scriptContent, "Script content is required");
202241

203242
const pythonBin = process.env.PYTHON_BIN_PATH || "python";
@@ -206,6 +245,13 @@ export const python = {
206245

207246
const pythonProcess = x(pythonBin, [pythonScriptPath], {
208247
...options,
248+
nodeOptions: {
249+
...(options.nodeOptions || {}),
250+
env: {
251+
...process.env,
252+
...options.env,
253+
},
254+
},
209255
throwOnError: false,
210256
});
211257

references/python-catalog/src/trigger/pythonTasks.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,24 @@ export const convertUrlToMarkdown = schemaTask({
2929
export const pythonRunInlineTask = task({
3030
id: "python-run-inline",
3131
run: async () => {
32-
const result = await python.runInline(`
32+
const result = await python.runInline(
33+
`
34+
import os
3335
import html2text as h2t
3436
3537
h = h2t.HTML2Text()
3638
3739
print(h.handle("<p>Hello, <a href='https://www.google.com/earth/'>world</a>!"))
38-
`);
40+
print(f"API Key: {os.environ['OPENAI_API_KEY']}")
41+
`,
42+
{
43+
env: {
44+
OPENAI_API_KEY: "sk-1234567890",
45+
},
46+
}
47+
);
48+
49+
console.log(result.stdout);
3950

4051
const streamingResult = python.stream.runInline(`
4152
import html2text as h2t

0 commit comments

Comments
 (0)