1
- import asyncio
2
- import importlib
3
- from pathlib import Path
1
+ from micropip import package_index
4
2
5
- from packaging .markers import default_environment
6
-
7
- from .. import package_index
8
- from .._compat import loadPackage , to_js
9
- from ..constants import FAQ_URLS
10
- from ..logging import setup_logging
11
- from ..transaction import Transaction
3
+ from ..install import install as _install
12
4
13
5
14
6
async def install (
@@ -21,165 +13,9 @@ async def install(
21
13
* ,
22
14
verbose : bool | int = False ,
23
15
) -> None :
24
- """Install the given package and all of its dependencies.
25
-
26
- If a package is not found in the Pyodide repository it will be loaded from
27
- PyPI. Micropip can only load pure Python wheels or wasm32/emscripten wheels
28
- built by Pyodide.
29
-
30
- When used in web browsers, downloads from PyPI will be cached. When run in
31
- Node.js, packages are currently not cached, and will be re-downloaded each
32
- time ``micropip.install`` is run.
33
-
34
- Parameters
35
- ----------
36
- requirements :
37
-
38
- A requirement or list of requirements to install. Each requirement is a
39
- string, which should be either a package name or a wheel URI:
40
-
41
- - If the requirement does not end in ``.whl``, it will be interpreted as
42
- a package name. A package with this name must either be present
43
- in the Pyodide lock file or on PyPI.
44
-
45
- - If the requirement ends in ``.whl``, it is a wheel URI. The part of
46
- the requirement after the last ``/`` must be a valid wheel name in
47
- compliance with the `PEP 427 naming convention
48
- <https://www.python.org/dev/peps/pep-0427/#file-format>`_.
49
-
50
- - If a wheel URI starts with ``emfs:``, it will be interpreted as a path
51
- in the Emscripten file system (Pyodide's file system). E.g.,
52
- ``emfs:../relative/path/wheel.whl`` or ``emfs:/absolute/path/wheel.whl``.
53
- In this case, only .whl files are supported.
54
-
55
- - If a wheel URI requirement starts with ``http:`` or ``https:`` it will
56
- be interpreted as a URL.
57
-
58
- - In node, you can access the native file system using a URI that starts
59
- with ``file:``. In the browser this will not work.
60
-
61
- keep_going :
62
-
63
- This parameter decides the behavior of the micropip when it encounters a
64
- Python package without a pure Python wheel while doing dependency
65
- resolution:
66
-
67
- - If ``False``, an error will be raised on first package with a missing
68
- wheel.
69
-
70
- - If ``True``, the micropip will keep going after the first error, and
71
- report a list of errors at the end.
72
-
73
- deps :
74
-
75
- If ``True``, install dependencies specified in METADATA file for each
76
- package. Otherwise do not install dependencies.
77
-
78
- credentials :
79
-
80
- This parameter specifies the value of ``credentials`` when calling the
81
- `fetch() <https://developer.mozilla.org/en-US/docs/Web/API/fetch>`__
82
- function which is used to download the package.
83
-
84
- When not specified, ``fetch()`` is called without ``credentials``.
85
-
86
- pre :
87
-
88
- If ``True``, include pre-release and development versions. By default,
89
- micropip only finds stable versions.
90
-
91
- index_urls :
92
-
93
- A list of URLs or a single URL to use as the package index when looking
94
- up packages. If None, *https://pypi.org/pypi/{package_name}/json* is used.
95
-
96
- - The index URL should support the
97
- `JSON API <https://warehouse.pypa.io/api-reference/json/>`__ .
98
-
99
- - The index URL may contain the placeholder {package_name} which will be
100
- replaced with the package name when looking up a package. If it does not
101
- contain the placeholder, the package name will be appended to the URL.
102
-
103
- - If a list of URLs is provided, micropip will try each URL in order until
104
- it finds a package. If no package is found, an error will be raised.
105
-
106
- verbose :
107
- Print more information about the process.
108
- By default, micropip is silent. Setting ``verbose=True`` will print
109
- similar information as pip.
110
- """
111
- logger = setup_logging (verbose )
112
-
113
- ctx = default_environment ()
114
- if isinstance (requirements , str ):
115
- requirements = [requirements ]
116
-
117
- fetch_kwargs = dict ()
118
-
119
- if credentials :
120
- fetch_kwargs ["credentials" ] = credentials
121
-
122
- # Note: getsitepackages is not available in a virtual environment...
123
- # See https://github.com/pypa/virtualenv/issues/228 (issue is closed but
124
- # problem is not fixed)
125
- from site import getsitepackages
126
-
127
- wheel_base = Path (getsitepackages ()[0 ])
128
-
129
16
if index_urls is None :
130
17
index_urls = package_index .INDEX_URLS [:]
131
18
132
- transaction = Transaction (
133
- ctx = ctx , # type: ignore[arg-type]
134
- ctx_extras = [],
135
- keep_going = keep_going ,
136
- deps = deps ,
137
- pre = pre ,
138
- fetch_kwargs = fetch_kwargs ,
139
- verbose = verbose ,
140
- index_urls = index_urls ,
19
+ return await _install (
20
+ requirements , keep_going , deps , credentials , pre , index_urls , verbose = verbose
141
21
)
142
- await transaction .gather_requirements (requirements )
143
-
144
- if transaction .failed :
145
- failed_requirements = ", " .join ([f"'{ req } '" for req in transaction .failed ])
146
- raise ValueError (
147
- f"Can't find a pure Python 3 wheel for: { failed_requirements } \n "
148
- f"See: { FAQ_URLS ['cant_find_wheel' ]} \n "
149
- )
150
-
151
- package_names = [pkg .name for pkg in transaction .pyodide_packages ] + [
152
- pkg .name for pkg in transaction .wheels
153
- ]
154
-
155
- if package_names :
156
- logger .info ("Installing collected packages: " + ", " .join (package_names ))
157
-
158
- wheel_promises = []
159
- # Install built-in packages
160
- pyodide_packages = transaction .pyodide_packages
161
- if len (pyodide_packages ):
162
- # Note: branch never happens in out-of-browser testing because in
163
- # that case REPODATA_PACKAGES is empty.
164
- wheel_promises .append (
165
- asyncio .ensure_future (
166
- loadPackage (to_js ([name for [name , _ , _ ] in pyodide_packages ]))
167
- )
168
- )
169
-
170
- # Now install PyPI packages
171
- for wheel in transaction .wheels :
172
- # detect whether the wheel metadata is from PyPI or from custom location
173
- # wheel metadata from PyPI has SHA256 checksum digest.
174
- wheel_promises .append (wheel .install (wheel_base ))
175
-
176
- await asyncio .gather (* wheel_promises )
177
-
178
- packages = [f"{ pkg .name } -{ pkg .version } " for pkg in transaction .pyodide_packages ] + [
179
- f"{ pkg .name } -{ pkg .version } " for pkg in transaction .wheels
180
- ]
181
-
182
- if packages :
183
- logger .info ("Successfully installed " + ", " .join (packages ))
184
-
185
- importlib .invalidate_caches ()
0 commit comments