# infra_virtualenv **Repository Path**: mirrors_chromium_googlesource/infra_virtualenv ## Basic Information - **Project Name**: infra_virtualenv - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-03-19 - **Last Updated**: 2025-09-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # infra_virtualenv README [TOC] This repository provides a common Python virtualenv interface that Chromium OS infrastructure code can depend on. ## Using virtualenv in another repository A repository adding virtualenv should mimic this repository, which itself uses virtualenv for running unit tests. Key files: * `bin/python_venv` starts an instance of Python that uses the virtualenv. * `bin/turtle` is an example script for running a Python module using `bin/python_venv`. * `venv/requirements.txt` lists the packages to install inside the virtualenv. * `venv` is added to `PYTHONPATH`. For example, `venv/cros_venv` can be imported inside the virtualenv using `import cros_venv`. To make sure all your requirements are pinned, run: bin/python_venv -m pip freeze Copy the output into `requirements.txt` Refer to Pip's [documentation](https://pip.pypa.io/en/stable/) for the `requirements.txt` format. ## Adding packages to be available for use Packages to be installed inside a virtualenv must first be added to `pip_packages`. To add packages, run: bin/python_venv -m pip wheel -w pip_packages foo==1.2.3 Refer to Pip's documentation for details on the arguments for `pip`. If the resultant wheel contains `linux` and not `manylinux`, then it is NOT portable. You will need to build a portable wheel; see next section. Commit the wheel and make a CL. ## Building portable wheel with C extensions You need to use the standard manylinux Docker image to build the portable wheel. Install Docker: http://go/installdocker Add the manylinux Docker image: docker pull quay.io/pypa/manylinux2014_x86_64@sha256:cffd074a33992fb7493f727fda59aebd81e54b8a0e016574ceab054691acdfd0 Get the image ID: docker image ls quay.io/pypa/manylinux2014_x86_64 Run the Docker image: docker run -i -t -v "$(pwd)/pip_packages:/pip_packages" --rm $IMAGE /bin/bash Build a portable wheel: cd /opt/python/cp27-cp27mu bin/pip wheel -w /pip_packages foo==1.2.3 auditwheel repair --plat manylinux2014_x86_64 -w /pip_packages /pip_packages/foo-1.2.3-cp27-cp27mu-linux_x86_64.whl Keep the `manylinux` wheel and remove the `linux` wheel. Since these wheels are built as root inside the container, you may need to chown the files on the host to prevent permission issues later: sudo chown $(id -un):$(id -gn) pip_packages/* ## Adding third party packages to a virtualenv Add the packages to `requirements.txt`. If the packages are not in `pip_packages` yet, add the packages to `pip_packages`. ## Adding first party modules to a virtualenv's import path "First party modules" refers to Chromium OS code (anything checked out by `repo`). NOTE: Do not use this for third party dependencies (stuff not owned by Chromium OS)! This should only be used to set up imports for stuff we own. For example, importing `python-MySQL` SHOULD NOT use this, but importing `chromite` MAY use this. There are two ways to do this: 1. Adding a relative symlink to `venv`. 2. Modifying `sys.path` in `__init__.py`. Adding a symlink to `venv` is simple and should be self-explanatory. However, keep in mind that `repo` checkouts may not always have the same structure, and certain environments such as production servers may check out repositories in completely different locations. This method is not powerful enough to account for these environments. Modifying `sys.path` is a lot more powerful. The way to do this is to add a small bit of code to the `__init__.py` of the package that needs the import. Example (do not copy and paste blindly): import os import sys # The path of the package PKGDIR = __path__[0] # Paths to check _PATH1 = os.path.join(PKGDIR, '../foo') _PATH2 = '/opt/foo' if os.path.exists(_PATH1): sys.path.append(_PATH1) elif os.path.exists(_PATH2): sys.path.append(_PATH2) else: raise ImportError('foo not found') You must also add the contents of the other project's `requirements.txt` to your project. We do not attempt to resolve dependencies recursively as that is very difficult. ## Low level API The `bin/create_venv` script prepares a virtualenv using a `requirements.txt` file. bin/create_venv requirements.txt The script will print the path to the virtualenv to stdout. Note that the output ends with a newline; Bash handles this, but Python does not. To run the virtualenv Python, call `bin/python` under the virtualenv directory. Together, this might look up: venv=$(bin/create_venv requirements.txt) ${venv}/bin/python NOTE: It is not generally safe to run the other scripts in the virtualenv's `bin` directory due to hard-coded paths. Instead of running `bin/pip` for example, use `bin/python -m pip`.