wheel python setup.py pypi

wheel - python pip install



¿Cómo puedes agrupar todo tu código de Python en un solo archivo zip? (6)

Bueno, es posible crear sus propios "paquetes / huevos" en su {app-home-dir / packages} (copiando los huevos allí, por ejemplo) y configurar archivos adicionales en setup.py (setuptools) para empaquetarlo todo como una única distribución. ( ¿Qué es setup.py? ). Tenga en cuenta que antes de iniciar la función principal de su aplicación, debe informar a Python dónde están exactamente sus "paquetes / huevos" externos, agregando {app-home-dir / packages} a sys.path. Esa es la forma fácil de crear un paquete independiente. Sin embargo, con los peligros que conlleva las dependencias y sus versiones, los módulos Python se mezclan con el código Ansi C, etc.

Sería conveniente cuando distribuyas aplicaciones para combinar todos los huevos en un solo archivo zip, de modo que todo lo que necesitas distribuir es un solo archivo zip y un ejecutable (algunos binarios personalizados que simplemente se inician, cargan la función principal del archivo zip y activan Python). apagado o similar).

He visto algunos comentarios sobre cómo hacer esto en línea, pero no hay ejemplos de cómo hacerlo realmente.

Soy consciente de que usted puede (si es seguro para zip) convertir los huevos en archivos zip.

De lo que no estoy seguro es de:

¿Puedes de alguna manera combinar todos tus huevos en un solo archivo zip? ¿Si es así, cómo?

¿Cómo cargaría y ejecutaría el código de un huevo específico?

¿Cómo se aseguraría de que el código en ese huevo pudiera acceder a todas las dependencias (es decir, otros huevos en el archivo zip)?

La gente pregunta mucho este tipo de cosas y obtiene respuestas como; utilizar py2exe. Sí, lo entiendo, esa es una solución. No es la pregunta que estoy haciendo aquí, aunque ...


Podría usar un archivo zip autoextraíble , configurado para iniciar un intérprete de Python después de descomprimir los huevos desde el mismo archivo .exe que los contiene.


Puede automatizar la mayor parte del trabajo con las herramientas regulares de Python. Vamos a empezar con limpia virtualenv.

[zart@feena ~]$ mkdir ziplib-demo [zart@feena ~]$ cd ziplib-demo [zart@feena ziplib-demo]$ virtualenv . New python executable in ./bin/python Installing setuptools.............done. Installing pip...............done.

Ahora instalemos un conjunto de paquetes que irán a la biblioteca comprimida. El truco es forzar su instalación en un directorio específico.

(Nota: no use la opción --egg en la línea de comandos o en pip.conf / pip.ini porque interrumpirá el diseño del archivo por lo que no se puede importar en zip)

[zart@feena ziplib-demo]$ bin/pip install --install-option --install-lib=$PWD/unpacked waitress Downloading/unpacking waitress Downloading waitress-0.8.5.tar.gz (112kB): 112kB downloaded Running setup.py egg_info for package waitress Requirement already satisfied (use --upgrade to upgrade): setuptools in ./lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg (from waitress) Installing collected packages: waitress Running setup.py install for waitress Installing waitress-serve script to /home/zart/ziplib-demo/bin Successfully installed waitress Cleaning up...

Actualización : pip ahora tiene el interruptor -t <path> , que hace lo mismo que --install-option --install-lib= .

Ahora empacemos todos en una cremallera

[zart@feena ziplib-demo]$ cd unpacked [zart@feena unpacked]$ ls waitress waitress-0.8.5-py2.7.egg-info [zart@feena unpacked]$ zip -r9 ../library.zip * adding: waitress/ (stored 0%) adding: waitress/receiver.py (deflated 71%) adding: waitress/server.pyc (deflated 64%) adding: waitress/utilities.py (deflated 62%) adding: waitress/trigger.pyc (deflated 63%) adding: waitress/trigger.py (deflated 61%) adding: waitress/receiver.pyc (deflated 60%) adding: waitress/adjustments.pyc (deflated 51%) adding: waitress/compat.pyc (deflated 56%) adding: waitress/adjustments.py (deflated 60%) adding: waitress/server.py (deflated 68%) adding: waitress/channel.py (deflated 72%) adding: waitress/task.pyc (deflated 57%) adding: waitress/tests/ (stored 0%) adding: waitress/tests/test_regression.py (deflated 63%) adding: waitress/tests/test_functional.py (deflated 88%) adding: waitress/tests/test_parser.pyc (deflated 76%) adding: waitress/tests/test_trigger.pyc (deflated 73%) adding: waitress/tests/test_init.py (deflated 72%) adding: waitress/tests/test_utilities.pyc (deflated 78%) adding: waitress/tests/test_buffers.pyc (deflated 79%) adding: waitress/tests/test_trigger.py (deflated 82%) adding: waitress/tests/test_buffers.py (deflated 86%) adding: waitress/tests/test_runner.py (deflated 75%) adding: waitress/tests/test_init.pyc (deflated 69%) adding: waitress/tests/__init__.pyc (deflated 21%) adding: waitress/tests/support.pyc (deflated 48%) adding: waitress/tests/test_utilities.py (deflated 73%) adding: waitress/tests/test_channel.py (deflated 87%) adding: waitress/tests/test_task.py (deflated 87%) adding: waitress/tests/test_functional.pyc (deflated 82%) adding: waitress/tests/__init__.py (deflated 5%) adding: waitress/tests/test_compat.pyc (deflated 53%) adding: waitress/tests/test_receiver.pyc (deflated 79%) adding: waitress/tests/test_adjustments.py (deflated 78%) adding: waitress/tests/test_adjustments.pyc (deflated 74%) adding: waitress/tests/test_server.pyc (deflated 73%) adding: waitress/tests/fixtureapps/ (stored 0%) adding: waitress/tests/fixtureapps/filewrapper.pyc (deflated 59%) adding: waitress/tests/fixtureapps/getline.py (deflated 37%) adding: waitress/tests/fixtureapps/nocl.py (deflated 47%) adding: waitress/tests/fixtureapps/sleepy.pyc (deflated 44%) adding: waitress/tests/fixtureapps/echo.py (deflated 40%) adding: waitress/tests/fixtureapps/error.py (deflated 52%) adding: waitress/tests/fixtureapps/nocl.pyc (deflated 48%) adding: waitress/tests/fixtureapps/getline.pyc (deflated 32%) adding: waitress/tests/fixtureapps/writecb.pyc (deflated 42%) adding: waitress/tests/fixtureapps/toolarge.py (deflated 37%) adding: waitress/tests/fixtureapps/__init__.pyc (deflated 20%) adding: waitress/tests/fixtureapps/writecb.py (deflated 50%) adding: waitress/tests/fixtureapps/badcl.pyc (deflated 44%) adding: waitress/tests/fixtureapps/runner.pyc (deflated 58%) adding: waitress/tests/fixtureapps/__init__.py (stored 0%) adding: waitress/tests/fixtureapps/filewrapper.py (deflated 74%) adding: waitress/tests/fixtureapps/runner.py (deflated 41%) adding: waitress/tests/fixtureapps/echo.pyc (deflated 42%) adding: waitress/tests/fixtureapps/groundhog1.jpg (deflated 24%) adding: waitress/tests/fixtureapps/error.pyc (deflated 48%) adding: waitress/tests/fixtureapps/sleepy.py (deflated 42%) adding: waitress/tests/fixtureapps/toolarge.pyc (deflated 43%) adding: waitress/tests/fixtureapps/badcl.py (deflated 45%) adding: waitress/tests/support.py (deflated 52%) adding: waitress/tests/test_task.pyc (deflated 78%) adding: waitress/tests/test_channel.pyc (deflated 78%) adding: waitress/tests/test_regression.pyc (deflated 68%) adding: waitress/tests/test_parser.py (deflated 80%) adding: waitress/tests/test_server.py (deflated 78%) adding: waitress/tests/test_receiver.py (deflated 87%) adding: waitress/tests/test_compat.py (deflated 51%) adding: waitress/tests/test_runner.pyc (deflated 72%) adding: waitress/__init__.pyc (deflated 50%) adding: waitress/channel.pyc (deflated 58%) adding: waitress/runner.pyc (deflated 54%) adding: waitress/buffers.py (deflated 74%) adding: waitress/__init__.py (deflated 61%) adding: waitress/runner.py (deflated 58%) adding: waitress/parser.py (deflated 69%) adding: waitress/compat.py (deflated 69%) adding: waitress/buffers.pyc (deflated 69%) adding: waitress/utilities.pyc (deflated 60%) adding: waitress/parser.pyc (deflated 53%) adding: waitress/task.py (deflated 72%) adding: waitress-0.8.5-py2.7.egg-info/ (stored 0%) adding: waitress-0.8.5-py2.7.egg-info/dependency_links.txt (stored 0%) adding: waitress-0.8.5-py2.7.egg-info/installed-files.txt (deflated 83%) adding: waitress-0.8.5-py2.7.egg-info/top_level.txt (stored 0%) adding: waitress-0.8.5-py2.7.egg-info/PKG-INFO (deflated 65%) adding: waitress-0.8.5-py2.7.egg-info/not-zip-safe (stored 0%) adding: waitress-0.8.5-py2.7.egg-info/SOURCES.txt (deflated 71%) adding: waitress-0.8.5-py2.7.egg-info/entry_points.txt (deflated 33%) adding: waitress-0.8.5-py2.7.egg-info/requires.txt (deflated 5%) [zart@feena unpacked]$ cd ..

Tenga en cuenta que esos archivos deben estar en la parte superior del archivo zip, no puede simplemente zip -r9 library.zip unpacked

Comprobando el resultado:

[zart@feena ziplib-demo]$ PYTHONPATH=library.zip python Python 2.7.1 (r271:86832, Apr 12 2011, 16:15:16) [GCC 4.6.0 20110331 (Red Hat 4.6.0-2)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import waitress >>> waitress <module ''waitress'' from ''/home/zart/ziplib-demo/library.zip/waitress/__init__.pyc''> >>> >>> from wsgiref.simple_server import demo_app >>> waitress.serve(demo_app) serving on http://0.0.0.0:8080 ^C>>>

Actualización: desde Python 3.5 también hay un módulo zipapp que puede ayudar a agrupar todo el paquete en un archivo .pyz. Para necesidades más complejas, pyinstaller , py2exe o py2app podrían ajustarse mejor a la cuenta.


Python ejecutará los archivos zip como si fueran secuencias de comandos individuales si contienen un archivo __main __. Py [c] dentro del nivel superior. Las importaciones de paquetes también verifican dentro del zip que __main__ está ejecutando desde dentro.

Así que crear su setup.py ( py_modules = [''__main__''] es importante aquí junto con la especificación de todos sus paquetes y otros módulos).

Luego ejecute python setup.py bdist --format zip para crear el archivo zip. Ahora si quieres que sea ejecutable puedes hacer lo siguiente. En este punto, puede ejecutar el archivo zip resultante como cualquier otra secuencia de comandos de Python.

Un paso más para los usuarios de Linux / Mac que leen esto para mejorar la conveniencia (aunque probablemente no sea su escenario al mencionar py2exe)

echo ''#!/usr/bin/env python'' > my_executable_zip cat output_of_setup_py_bdist.zip >> my_executable_zip chmod +x my_executable_zip

¡Esto solo hace un #! línea al archivo zip para que cuando se ejecuta desde el shell no necesite especificar el intérprete. En este punto, puede ejecutarlo como cualquier otro binario en el sistema, aunque secretamente es un archivo zip lleno de python. Normalmente creo un makefile para ejecutar setup.py y luego hago esta conversión.


Sí, un archivo zip / egg puede proporcionar múltiples módulos, por lo que puede combinarlos en un solo archivo. Sin embargo, soy muy escéptico a que sea una buena idea. Aún necesita instalar ese archivo zip, y aún puede chocar con otras versiones ya instaladas, etc.

Así que la primera pregunta es cuál es el objetivo. ¿Por qué quieres solo un archivo? ¿Es por la facilidad de instalación, o la facilidad de distribución, o qué?

Tener un solo archivo no facilitará la instalación, hay otras formas mejores. Puede dejar que la instalación descargue e instale las dependencias automáticamente, eso es fácil de hacer.

Y tenerlos en un archivo zip aún significa que necesitas expandir ese archivo zip y ejecutar setup.py, que no es muy fácil de usar.

Por lo tanto, tener un solo archivo no resuelve muchos problemas, por lo que la pregunta es qué problema está tratando de resolver.


¿Puedes de alguna manera combinar todos tus huevos en un solo archivo zip? ¿Si es así, cómo?

Sí tu puedes. Python se cargará desde el archivo zip que se agrega en sys.path (ver PEP 273 ). Si coloca todas las bibliotecas de Python dentro de un archivo, el archivo se trata como un directorio. Esto es lo que algunas de las herramientas py2exe, bbfreeze, etc. pueden hacer para aislar las bibliotecas.

En cuanto a cómo, realmente depende de cómo se instalan los huevos: pip, easy_install, etc. La lógica sería inspeccionar todos los huevos dependientes y reunir su ruta de instalación y luego comprimir los huevos dentro de un archivo.

¿Cómo cargaría y ejecutaría el código de un huevo específico?

Necesitas definir cargar y ejecutar. Si está hablando de importar módulos y paquetes, no tiene que hacer nada especial. Aquí hay una publicación de blog interesante sobre el tema que incluye algunos programas de empaquetado de Python de advertencia como archivos ZIP ejecutables

¿Cómo se aseguraría de que el código en ese huevo pudiera acceder a todas las dependencias (es decir, otros huevos en el archivo zip)?

Esto está incorporado siempre y cuando los huevos no sean extensiones (es decir, zip zip). Ver también zipimport