-
Notifications
You must be signed in to change notification settings - Fork 51
feat: support uv-managed Python Actors in apify create #1274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ import { join } from 'node:path'; | |
| import process from 'node:process'; | ||
|
|
||
| import { gte, minVersion } from 'semver'; | ||
| import which from 'which'; | ||
|
|
||
| import { fetchManifest, manifestUrl } from '@apify/actor-templates'; | ||
|
|
||
|
|
@@ -197,6 +198,39 @@ export class CreateCommand extends ApifyCommand<typeof CreateCommand> { | |
| await cwdProjectResult.inspectAsync(async (project) => { | ||
| const minimumSupportedNodeVersion = minVersion(SUPPORTED_NODEJS_VERSION); | ||
|
|
||
| // uv-managed Python projects (recognized by a committed `uv.lock`) manage their own virtual | ||
| // environment, dependencies, and Python version. Install them with `uv sync` instead of the | ||
| // pip + requirements.txt flow. uv provides the Python pinned in `.python-version` on its own, | ||
| // so this runs even when no system Python is detected. | ||
| const isPythonProject = project.type === ProjectLanguage.Python || project.type === ProjectLanguage.Scrapy; | ||
| const hasUvLock = await stat(join(actFolderDir, 'uv.lock')) | ||
| .then(() => true) | ||
| .catch(() => false); | ||
|
Comment on lines
+206
to
+208
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: now we run it also for javascript projects, maybe we can move it to isPythonProject code block? |
||
|
|
||
| if (isPythonProject && hasUvLock) { | ||
| const uvPath = await which('uv', { nothrow: true }); | ||
|
|
||
| if (!uvPath) { | ||
| warning({ | ||
| message: | ||
| 'This Actor uses uv to manage its dependencies, but the uv executable was not found. ' + | ||
| 'Install uv (https://docs.astral.sh/uv/getting-started/installation/), then run "uv sync" in the Actor directory.', | ||
| }); | ||
| return; | ||
|
Comment on lines
+216
to
+219
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: we should check for uvPath also in getInstallCommandSuggestion otherwise we recommend pip install after this warning (or after --skip-dependency-install) something like this maybe 🔽 ? } else if (project.type === ProjectLanguage.Python || project.type === ProjectLanguage.Scrapy) {
const hasUvLock = await stat(join(actFolderDir, 'uv.lock')).then(() => true).catch(() => false);
installCommandSuggestion = hasUvLock ? 'uv sync' : 'python -m pip install -r requirements.txt';
} |
||
| } | ||
|
|
||
| info({ message: 'Installing dependencies with "uv sync"...' }); | ||
|
|
||
| await execWithLog({ | ||
| cmd: uvPath, | ||
| args: ['sync'], | ||
| opts: { cwd: actFolderDir }, | ||
| }); | ||
|
Comment on lines
+224
to
+228
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question: "pip way" now ignores skipOptionalDeps flag, is this the same for uv? does uv have something for optional deps? |
||
|
|
||
| dependenciesInstalled = true; | ||
| return; | ||
| } | ||
|
|
||
| if (!project.runtime) { | ||
| switch (project.type) { | ||
| case ProjectLanguage.JavaScript: { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: does it make sense to introduce new parameters in project level so we do not need to check for uv.lock? Or make
uvpart ofproject.packageManager?