Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/cute-eagles-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"workers-playground": minor
"wrangler": minor
---

Python packages are now read from cf-requirements.txt instead of requirements.txt by default
6 changes: 3 additions & 3 deletions packages/workers-playground/generate-default-hashes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ const pythonWorker = async () => {
);

worker.set(
"requirements.txt",
new Blob([await readFile("./welcome/requirements.txt", "utf8")], {
"cf-requirements.txt",
new Blob([await readFile("./welcome/cf-requirements.txt", "utf8")], {
type: "text/plain",
}),
"requirements.txt"
"cf-requirements.txt"
);
return worker;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export default {
contentType:
"multipart/form-data; boundary=----formdata-88e2b909-318c-42df-af0d-9077f33c7988",
worker:
'------formdata-88e2b909-318c-42df-af0d-9077f33c7988\r\nContent-Disposition: form-data; name="metadata"\r\n\r\n{"main_module":"index.py","compatibility_date":"$REPLACE_COMPAT_DATE","compatibility_flags":["python_workers"]}\r\n------formdata-88e2b909-318c-42df-af0d-9077f33c7988\r\nContent-Disposition: form-data; name="index.py"; filename="index.py"\r\nContent-Type: text/x-python\r\n\r\nfrom js import Response\nimport numpy as np\n\ndef on_fetch(request):\n print("Hi there!")\n arr = np.array([1, 2, 3])\n return Response.new(str(arr))\n\r\n------formdata-88e2b909-318c-42df-af0d-9077f33c7988\r\nContent-Disposition: form-data; name="requirements.txt"; filename="requirements.txt"\r\nContent-Type: text/plain\r\n\r\nnumpy\r\n------formdata-88e2b909-318c-42df-af0d-9077f33c7988--',
'------formdata-88e2b909-318c-42df-af0d-9077f33c7988\r\nContent-Disposition: form-data; name="metadata"\r\n\r\n{"main_module":"index.py","compatibility_date":"$REPLACE_COMPAT_DATE","compatibility_flags":["python_workers"]}\r\n------formdata-88e2b909-318c-42df-af0d-9077f33c7988\r\nContent-Disposition: form-data; name="index.py"; filename="index.py"\r\nContent-Type: text/x-python\r\n\r\nfrom js import Response\nimport numpy as np\n\ndef on_fetch(request):\n print("Hi there!")\n arr = np.array([1, 2, 3])\n return Response.new(str(arr))\n\r\n------formdata-88e2b909-318c-42df-af0d-9077f33c7988\r\nContent-Disposition: form-data; name="cf-requirements.txt"; filename="cf-requirements.txt"\r\nContent-Type: text/plain\r\n\r\nnumpy\r\n------formdata-88e2b909-318c-42df-af0d-9077f33c7988--',
},
"/": {
contentType:
Expand Down
10 changes: 5 additions & 5 deletions packages/workers-playground/src/QuickEditor/useDraftWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ export function serialiseWorker(service: PartialWorker): FormData {
const entrypointModule = typedModules.find(
(m) => m.name === service.entrypoint
);
// Try to find a requirements.txt file
// Try to find a cf-requirements.txt file
const isPythonEntrypoint = entrypointModule?.type === "python";

if (isPythonEntrypoint) {
try {
const pythonRequirements = service.modules["requirements.txt"];
const pythonRequirements = service.modules["cf-requirements.txt"];
if (pythonRequirements) {
const textContent = decoder.decode(pythonRequirements.contents);
// This is incredibly naive. However, it supports common syntax for requirements.txt
// This is incredibly naive. However, it supports common syntax for cf-requirements.txt
for (const requirement of textContent.split("\n")) {
const packageName = requirement.match(/^[^\d\W]\w*/);
if (typeof packageName?.[0] === "string") {
Expand All @@ -98,10 +98,10 @@ export function serialiseWorker(service: PartialWorker): FormData {
}
}
}
// We don't care if a requirements.txt isn't found
// We don't care if a cf-requirements.txt isn't found
} catch (e) {
console.debug(
"Python entrypoint detected, but no requirements.txt file found."
"Python entrypoint detected, but no cf-requirements.txt file found."
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { existsSync } from "node:fs";
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
import path from "node:path";
import chalk from "chalk";
Expand Down Expand Up @@ -93,21 +94,28 @@ export async function findAdditionalModules(
name: m.name,
}));

// Try to find a requirements.txt file
// Try to find a cf-requirements.txt file
const isPythonEntrypoint =
getBundleType(entry.format, entry.file) === "python";

if (isPythonEntrypoint) {
let pythonRequirements = "";
try {
pythonRequirements = await readFile(
path.resolve(entry.projectRoot, "requirements.txt"),
path.resolve(entry.projectRoot, "cf-requirements.txt"),
"utf-8"
);
} catch (e) {
// We don't care if a requirements.txt isn't found
// We don't care if a cf-requirements.txt isn't found
logger.debug(
"Python entrypoint detected, but no requirements.txt file found."
"Python entrypoint detected, but no cf-requirements.txt file found."
);
}

// If a `requirements.txt` file is found, show a warning instructing user to use `cf-requirements.txt` instead.
if (existsSync(path.resolve(entry.projectRoot, "requirements.txt"))) {
logger.warn(
"Found a `requirements.txt` file. Python requirements should now be in a `cf-requirements.txt` file."
);
}

Expand All @@ -117,7 +125,7 @@ export async function findAdditionalModules(
}
if (!isValidPythonPackageName(requirement)) {
throw new UserError(
`Invalid Python package name "${requirement}" found in requirements.txt. Note that requirements.txt should contain package names only, not version specifiers.`
`Invalid Python package name "${requirement}" found in cf-requirements.txt. Note that cf-requirements.txt should contain package names only, not version specifiers.`
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default async function guessWorkerFormat(
`The entrypoint ${path.relative(
process.cwd(),
entryFile
)} defines a Python worker, support for Python workers is currently experimental. Python workers with a requirements.txt file can only be run locally and cannot be deployed.`
)} defines a Python worker, support for Python workers is currently experimental. Python workers with a cf-requirements.txt file can only be run locally and cannot be deployed.`
);
return { format: "modules", exports: [] };
}
Expand Down
4 changes: 2 additions & 2 deletions packages/wrangler/src/dev/use-esbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,10 @@ export function runBuild(
// trigger "builds" when any change
if (noBundle) {
const watching = [path.resolve(entry.moduleRoot)];
// Check whether we need to watch a Python requirements.txt file.
// Check whether we need to watch a Python cf-requirements.txt file.
const watchPythonRequirements =
getBundleType(entry.format, entry.file) === "python"
? path.resolve(entry.projectRoot, "requirements.txt")
? path.resolve(entry.projectRoot, "cf-requirements.txt")
: undefined;

if (watchPythonRequirements) {
Expand Down
Loading