Skip to content

Add lockfileContents option to loadPyodide() #5764

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

Merged
merged 19 commits into from
Jul 31, 2025

Conversation

hoodmane
Copy link
Member

@hoodmane hoodmane commented Jul 14, 2025

And also packageBaseUrl option:

  1. If lockfileContents is provided and not packageBaseUrl, then in the browser attempting to load a lock entry with a relative path fails.
  2. In Node, packageBaseUrl is used in place of jsdelivr as the cdn url if passed.

See discussion in #5736.

  • Add a CHANGELOG entry
  • Add / update tests
  • Add new / update outdated documentation

@hoodmane hoodmane force-pushed the lockfile-contents branch from 02d380a to 7de7090 Compare July 14, 2025 13:42
And also `packageBaseUrl` option:
1. If `lockfileContents` is provided and not `packageBaseUrl`, then
   in the browser attempting to load a lock entry with a relative path
   fails.
2. In Node, `packageBaseUrl` is used in place of jsdelivr as the cdn
   url if passed.
@hoodmane hoodmane force-pushed the lockfile-contents branch from 9613447 to df050ea Compare July 14, 2025 13:45
@ryanking13 ryanking13 self-requested a review July 15, 2025 09:41
Copy link
Member

@ryanking13 ryanking13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Ideally, I would like to deprecate LockFileURL instead of having two different options doing the same thing. WDYT?

@hoodmane
Copy link
Member Author

Thanks for the review @ryanking13!

@hoodmane
Copy link
Member Author

I would like to deprecate LockFileURL instead of having two different options doing the same thing.

I don't think it's worth the churn to deprecate this since it causes no extra maintenance burden.

@WebReflection
Copy link
Contributor

WebReflection commented Jul 22, 2025

If lockfileContents is provided and not packageBaseUrl, then in the browser attempting to load a lock entry with a relative path fails.

does it mean that with content created via micropip.freeze() we still need to create an object URL to pass as packageBaseURL ?

I am trying to implement the dance that must work on any pyodide version and this detail seems to be very important to understand properly ... I am not sure micropip.freeze() does, or will, provide relative paths internally so it'd be great to understand if our JSON Blob artifact is needed at all with lockfileContents, thank you!

@ryanking13
Copy link
Member

@WebReflection

Here are some changes related to the lockfile.

  • Before 0.28.0: We assumed that the Pyodide runtime and packages are always served from the same place. So if the lockfile has relative URLs in it, it always loads the packages from the indexURL + filename.

  • Pyodide 0.28.0 (micropip 0.10.0): This assumption has changed and we now allow loading Pyodide runtime and packages in different places. Therefore, we changed the behavior related to lockFileURL parameter. If the lockfile has relative URLs in it, and if indexURL is provided, the pacakges are loaded from parent(lockFileURL) + filename.

  • Pyodide 0.28.1 (micropip 0.10.1) (to be)

    • The behavior of micropip.freeze() has been changed. micropip.freeze() will now output the lockfile with absolute URLs. So if you generate a lockfile using micropip.freeze() and serve it through indexedDB, it will load the packages correctly (which was an error in Pyodide 0.28).
    • If the lockfile contains relative URLs, it will still load the packages from parent(lockFileURL) + filename.
    • This PR adds lockFileContents and packageBaseURL.
      • If lockFileContents is provided without packageBaseURL and if the lockfile has no absolute URLs, we fail (we don't know where to load packages)
      • If packageBaseURL is provided, then we load from packageBaseURL + filename.

So...

does it mean that with content created via micropip.freeze() we still need to create an object URL to pass as packageBaseURL ?

In Pyodide 0.28.1, no. micropip.freeze() will output absolute URLs for all the packages in the lockfile, so packageBaseURL will not be necessary.

I am not sure micropip.freeze() does, or will, provide relative paths internally so it'd be great to understand if our JSON Blob artifact is needed at all with lockfileContents, thank you!

micropip.freeze() will generate absolute URLs by default from 0.10.1 (Pyodide 0.28.1). And you'll be able to provide it directly to lockfileContents. Otherwise, creating the Blob URL and passing it to lockfileURL will also work.

@WebReflection
Copy link
Contributor

@ryanking13 crystal clear, thank you!

@hoodmane hoodmane added this to the 0.28.1 milestone Jul 29, 2025
@hoodmane hoodmane force-pushed the lockfile-contents branch from eee6723 to f124a78 Compare July 29, 2025 10:13
Copy link
Member

@ryanking13 ryanking13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. There is a test failure, otherwise looks good to me.

Comment on lines +265 to +267
options_.cdnUrl =
options_.packageBaseUrl ??
`https://cdn.jsdelivr.net/pyodide/v${version}/full/`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it always be https://cdn.jsdelivr.net/pyodide/v${version}/full/, as we use this only for a fallback?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure. But:

  • the caching system only works if file_name is relative, otherwise we will try to download the url every time and won't do any caching
  • if the user has a custom lock file, then any additional packages definitely won't be available on jsdelivr

So if they are to have any chance of using the caching mechanism with their own lock file, they need to be able to adjust the cdnURL.

@@ -254,7 +299,7 @@ export async function loadPyodide(
config.env.PYTHONINSPECT ??= "1";
const emscriptenSettings = createSettings(config);
const API = emscriptenSettings.API;
API.lockFilePromise = loadLockFile(config.lockFileURL);
API.lockFilePromise = Promise.resolve(options_.lockFileContents);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a bit confusing to have all of config, option, and option_ here. But I guess I'll be able clean it up in #5746.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well options_ and options are identical things just with different types.

@hoodmane
Copy link
Member Author

The failing test doesn't actually pass for me on the main branch...

@hoodmane
Copy link
Member Author

Maybe my micropip is out of date...

@hoodmane hoodmane merged commit 427d2b1 into pyodide:main Jul 31, 2025
38 of 40 checks passed
@hoodmane hoodmane deleted the lockfile-contents branch July 31, 2025 10:01
hoodmane added a commit to hoodmane/pyodide that referenced this pull request Jul 31, 2025
And also `packageBaseUrl` option:
1. If `lockfileContents` is provided and not `packageBaseUrl`, then in the browser attempting to
   load a lock entry with a relative path fails.
2. In Node, `packageBaseUrl` is used in place of jsdelivr as the cdn url if passed.

See discussion in pyodide#5736.
@ryanking13
Copy link
Member

Thanks!

hoodmane added a commit to hoodmane/pyodide that referenced this pull request Jul 31, 2025
And also `packageBaseUrl` option:
1. If `lockfileContents` is provided and not `packageBaseUrl`, then in the browser attempting to
   load a lock entry with a relative path fails.
2. In Node, `packageBaseUrl` is used in place of jsdelivr as the cdn url if passed.

See discussion in pyodide#5736.
@WebReflection
Copy link
Contributor

any eta for a new release? we're going on vacation and we'd love to be able to bring in latest Pyodide before doing that, so that anyone playing around our project could benefit from its latest/greatest, thank you!

hoodmane added a commit to hoodmane/pyodide that referenced this pull request Aug 4, 2025
And also `packageBaseUrl` option:
1. If `lockfileContents` is provided and not `packageBaseUrl`, then in the browser attempting to
   load a lock entry with a relative path fails.
2. In Node, `packageBaseUrl` is used in place of jsdelivr as the cdn url if passed.

See discussion in pyodide#5736.
hoodmane added a commit to hoodmane/pyodide that referenced this pull request Aug 4, 2025
And also `packageBaseUrl` option:
1. If `lockfileContents` is provided and not `packageBaseUrl`, then in the browser attempting to
   load a lock entry with a relative path fails.
2. In Node, `packageBaseUrl` is used in place of jsdelivr as the cdn url if passed.

See discussion in pyodide#5736.
@ryanking13 ryanking13 mentioned this pull request Aug 7, 2025
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy