Skip to content

feat: Add PyPI support#116

Merged
Pavel Zwerschke (pavelzw) merged 22 commits intoQuantco:mainfrom
e8035669:pypi_support
Apr 4, 2025
Merged

feat: Add PyPI support#116
Pavel Zwerschke (pavelzw) merged 22 commits intoQuantco:mainfrom
e8035669:pypi_support

Conversation

@e8035669
Copy link
Copy Markdown
Contributor

@e8035669 Jeff Zhang (e8035669) commented Mar 12, 2025

Motivation

closes #38

pixi-pack is a great work to deploy packages to anywhere, but I hope to support pypi packages as well. So I am trying to make support for pypi packages.

But I am not familar with how pixi or uv works. So it roughly imitates the way pixi works.

Changes

Use pixi-pack pack --experimental-pypi-support to package a project which has pypi dependencies.

It will do these things internally:

  • Collect all pypi record from pixi.lock, It accept wheel files currently. source distribution would reject
  • Create simple repository
  • Download all wheel files into simple directory
  • Create some index.html make it becomes PyPI-compatible package repository
  • Writing pip section when creating environment.yml, make it compatible to conda/micromamba

Use pixi-pack unpack to unpack. When simple directory is exist, it will continue install wheel files after conda prefix is installed.

It will do these things internally:

  • Find installed python from this prefix
  • Load python interpreter and python environment
  • Collect all .whl files
  • Unpack these wheel files
  • Install them into this python environment

If updating documentation:

@e8035669 Jeff Zhang (e8035669) changed the title Pypi support feat: Add PyPI support Mar 12, 2025
@e8035669
Copy link
Copy Markdown
Contributor Author

All right.... uv needs rustc 1.83, but current rustc in pixi is 1.81. But I am not sure about downgrading uv because pixi was using this version last week.

Can I upgrade rustc version?

@pavelzw
Copy link
Copy Markdown
Member

Can I upgrade rustc version?

yes, sure!

Copy link
Copy Markdown
Member

@pavelzw Pavel Zwerschke (pavelzw) left a comment

Choose a reason for hiding this comment

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

haven't reviewed the logic yet as i'm also not really familiar with pypi/pip/uv's inner workings, just two comments

Comment on lines +12 to +14
# torch has local version, which is percent encoded on url, it should be decode.
# torch-2.6.0%2Bcpu + torch-2.6.0+cpu
torch = { version = ">=2.2", index = "https://download.pytorch.org/whl/cpu" }
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I only know that this package has a local version, but it is big (170MB). If there is a smaller package. We can change it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

for the general unit tests, i would prefer a very small pypi package like ordered-enum which is a wheel with zero dependencies that is only 3KB large.

how about you verify the behavior with URL encoding in a unit test in pack.rs test_url_encoding where you just call download_pypi_package with the specific pytorch url?
this way pytorch will only get downloaded a single time in that test and all other integration tests just use a very small pixi environment which should make the tests quicker

key: tests
- name: Run test
run: pixi run test --color always${{ startsWith(matrix.os, 'ubuntu') && ' --no-default-features --features rustls-tls' || '' }}
run: pixi run test --color always${{ startsWith(matrix.os, 'ubuntu') && ' --no-default-features --features rustls-tls' || '' }} -- --test-threads=4
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I edited CI script to reduce parallel test, or it would make too many requests to download packages at the same time.

@tdejager
Copy link
Copy Markdown

Pavel Zwerschke (@pavelzw) asked me for a quick eyes on this. I think it is already looking pretty good , two questions.

  • Should the index.html generation maybe be optional. And AFAICS this is creating a flat index right?
  • I think it might be nicer to have a nicer error when a wheel is not found, like maybe saying only wheel files are supported or something? There can be quite some lock files with source distributions in there.

@e8035669
Copy link
Copy Markdown
Contributor Author

  • Should the index.html generation maybe be optional. And AFAICS this is creating a flat index right?

flat index is better, I didn't think of it before, I update to use flat index.

  • I think it might be nicer to have a nicer error when a wheel is not found, like maybe saying only wheel files are supported or something? There can be quite some lock files with source distributions in there.

Currently it only show the first source distribution it found, and exit program immediately, should I list all the source distribution in lock file?

@e8035669
Copy link
Copy Markdown
Contributor Author

Did I break something? Why do Windows and MacOS builds sometimes fail....

@pavelzw
Copy link
Copy Markdown
Member

stderr: "ERROR conda.core.link:_execute(938): An error occurred while installing package 'file:///private/var/folders/1z/67kzkrxn55x733bk922y4y440000gn/T/.tmpbhkkO6/channel::tk-8.6.13-h1abcd95_1'.\n\nCondaError: Cannot link a source that does not exist. /Users/runner/work/pixi-pack/pixi-pack/.pixi/envs/default/pkgs/tk-8.6.13-h1abcd95_1/include/X11/DECkeysym.h\nRunning `conda clean --packages` may resolve your problem.\n()\n\n" }

maybe this is because test_compatibility_with_pypi and test_compatibility run simultaneously and conda doesn't like that? we could try limiting the parallelism in a way that these two tests never run at the same time 🤔

@e8035669
Copy link
Copy Markdown
Contributor Author

stderr: "ERROR conda.core.link:_execute(938): An error occurred while installing package 'file:///private/var/folders/1z/67kzkrxn55x733bk922y4y440000gn/T/.tmpbhkkO6/channel::tk-8.6.13-h1abcd95_1'.\n\nCondaError: Cannot link a source that does not exist. /Users/runner/work/pixi-pack/pixi-pack/.pixi/envs/default/pkgs/tk-8.6.13-h1abcd95_1/include/X11/DECkeysym.h\nRunning `conda clean --packages` may resolve your problem.\n()\n\n" }

maybe this is because test_compatibility_with_pypi and test_compatibility run simultaneously and conda doesn't like that? we could try limiting the parallelism in a way that these two tests never run at the same time 🤔

Wow, it works!

@delsner
Copy link
Copy Markdown
Member

Thanks for your contribution Jeff Zhang (@e8035669), we'll take a look at this early next week!

Copy link
Copy Markdown
Member

@pavelzw Pavel Zwerschke (pavelzw) left a comment

Choose a reason for hiding this comment

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

looks very good already, thanks Jeff Zhang (@e8035669)! i have a couple of comments and after those are addressed, we can merge :)

Currently it only show the first source distribution it found, and exit program immediately, should I list all the source distribution in lock file?

i think it is fine as you implemented it now

Comment on lines +12 to +14
# torch has local version, which is percent encoded on url, it should be decode.
# torch-2.6.0%2Bcpu + torch-2.6.0+cpu
torch = { version = ">=2.2", index = "https://download.pytorch.org/whl/cpu" }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

for the general unit tests, i would prefer a very small pypi package like ordered-enum which is a wheel with zero dependencies that is only 3KB large.

how about you verify the behavior with URL encoding in a unit test in pack.rs test_url_encoding where you just call download_pypi_package with the specific pytorch url?
this way pytorch will only get downloaded a single time in that test and all other integration tests just use a very small pixi environment which should make the tests quicker

…d serial_test and mark conda tests are serial
Copy link
Copy Markdown
Member

@pavelzw Pavel Zwerschke (pavelzw) left a comment

Choose a reason for hiding this comment

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

thanks! some minor last comments

@e8035669
Copy link
Copy Markdown
Contributor Author

Thanks for the code review, I learned a lot

@pavelzw Pavel Zwerschke (pavelzw) added the enhancement New feature or request label Apr 4, 2025
@pavelzw Pavel Zwerschke (pavelzw) merged commit 21f8630 into Quantco:main Apr 4, 2025
13 of 17 checks passed
@e8035669 Jeff Zhang (e8035669) deleted the pypi_support branch May 21, 2025 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Question: Support for PyPi Packages planned?

4 participants