diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 432cccd1ef..fda197ed70 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,7 +4,7 @@ version: 2 updates: # Maintain dependencies for Python - - package-ecosystem: "pip" + - package-ecosystem: "uv" directory: "/" schedule: interval: "monthly" diff --git a/.github/workflows/deploytest.yml b/.github/workflows/deploytest.yml index 7248418fb3..6cc81d3501 100644 --- a/.github/workflows/deploytest.yml +++ b/.github/workflows/deploytest.yml @@ -48,24 +48,16 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - name: Set up Python 3.10 - uses: actions/setup-python@v6 + - name: Install uv + uses: astral-sh/setup-uv@v7 with: python-version: '3.10' - - name: pip cache - uses: actions/cache@v5 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pyprod-${{ hashFiles('requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pyprod- - - name: Install pip-tools and python dependencies + activate-environment: "true" + enable-cache: "true" + - name: Install python dependencies with uv run: | - # Pin pip to 25.2 to avoid incompatibility with pip-tools and 25.3 - # see https://github.com/jazzband/pip-tools/issues/2252 - python -m pip install pip==25.2 - pip install pip-tools - pip-sync requirements.txt + # Use uv to install dependencies directly from requirements files + uv pip sync requirements.txt - name: Use pnpm uses: pnpm/action-setup@v4 - name: Use Node.js diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 2f8a5bb082..4eb66cd0ec 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -32,7 +32,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - name: Install uv + uses: astral-sh/setup-uv@v7 with: python-version: '3.10' - name: Use pnpm diff --git a/.github/workflows/pythontest.yml b/.github/workflows/pythontest.yml index a7c40a4b19..e77c613e69 100644 --- a/.github/workflows/pythontest.yml +++ b/.github/workflows/pythontest.yml @@ -69,24 +69,16 @@ jobs: -e "MINIO_ROOT_PASSWORD=development" \ -e "MINIO_DEFAULT_BUCKETS=content:public" \ bitnamilegacy/minio:2024.5.28 - - name: Set up Python 3.10 - uses: actions/setup-python@v6 + - name: Install uv + uses: astral-sh/setup-uv@v7 with: python-version: '3.10' - - name: pip cache - uses: actions/cache@v5 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pytest-${{ hashFiles('requirements.txt', 'requirements-dev.txt') }} - restore-keys: | - ${{ runner.os }}-pytest- - - name: Install pip-tools and python dependencies + activate-environment: "true" + enable-cache: "true" + - name: Install python dependencies with uv run: | - # Pin pip to 25.2 to avoid incompatibility with pip-tools and 25.3 - # see https://github.com/jazzband/pip-tools/issues/2252 - python -m pip install pip==25.2 - pip install pip-tools - pip-sync requirements.txt requirements-dev.txt + # Use uv to install dependencies directly from requirements files + uv pip sync requirements.txt requirements-dev.txt - name: Test pytest run: | sh -c './contentcuration/manage.py makemigrations --check' diff --git a/.gitignore b/.gitignore index 9f9debd85c..e5ff67287f 100644 --- a/.gitignore +++ b/.gitignore @@ -129,6 +129,3 @@ storybook-static/ # i18n /contentcuration/locale/**/LC_MESSAGES/*.csv - -# pyenv -.python-version diff --git a/.python-version b/.python-version new file mode 100644 index 0000000000..c8cfe39591 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.10 diff --git a/docs/dependencies.md b/docs/dependencies.md index afa1e0f205..2c3ecbf385 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -1,11 +1,11 @@ # Adding or updating dependencies -We use `pip-tools` to ensure all our dependencies use the same versions on all deployments. +We use `uv` to manage Python dependencies and generate requirements files. To add a dependency, add it to either `requirements.in` or `requirements-dev.in`, then -run `pip-compile requirements[-dev].in` to generate the .txt file. Please make sure that +run `uv pip compile requirements[-dev].in` to generate the .txt file. Please make sure that both the `.in` and `.txt` file changes are part of the commit when updating dependencies. -To update a dependency, use `pip-compile --upgrade-package [package-name] requirements[-dev].in` +To update a dependency, use `uv pip compile --upgrade-package [package-name] requirements[-dev].in` -For more details, please see the [pip-tools docs on Github](https://github.com/jazzband/pip-tools). +For more details, please see the [uv documentation](https://docs.astral.sh/uv/). diff --git a/docs/host_services_setup.md b/docs/host_services_setup.md index 74aa267cbf..0034b140ea 100644 --- a/docs/host_services_setup.md +++ b/docs/host_services_setup.md @@ -3,7 +3,7 @@ This guide will walk through setting up Kolibri Studio for local development, where you'll run Studio's Python apps and all of Studio's services on your host machine, without the need for docker. ## Prerequisites -For detailed instructions on installing and configuring Volta, pyenv, and pyenv-virtualenv, please see the [Prerequisites](./local_dev_host.md#prerequisites) section in our Local Development with host guide. +For detailed instructions on installing and configuring Volta and uv, please see the [Prerequisites](./local_dev_host.md#prerequisites) section in our Local Development with host guide. ## Install system dependencies and services Studio requires some background services to be running: diff --git a/docs/local_dev_docker.md b/docs/local_dev_docker.md index 3d89e3a38b..e30a5ab5ea 100644 --- a/docs/local_dev_docker.md +++ b/docs/local_dev_docker.md @@ -5,10 +5,10 @@ The following guide utilizes docker and docker-compose to run select services re **Note:** If you are developing on Windows, it is recommended to use WSL (Windows Subsystem for Linux). Please follow the [WSL setup guide](./local_dev_wsl.md) for detailed instructions. ## Prerequisites -For detailed instructions on installing and configuring Volta, pyenv, and pyenv-virtualenv, please see the [Prerequisites](./local_dev_host.md#prerequisites) section in our Local Development with host guide. +For detailed instructions on installing and configuring Volta and uv, please see the [Prerequisites](./local_dev_host.md#prerequisites) section in our Local Development with host guide. ## Build your python virtual environment -For complete instructions on installing Python 3.10.13, creating and activating the virtual environment, and installing Studio’s Python dependencies, please refer to the [Build Your Python Virtual Environment](./local_dev_host.md#build-your-python-virtual-environment) section in our Local Development with host guide. +For complete instructions on creating and activating the virtual environment, and installing Studio’s Python dependencies, please refer to the [Build Your Python Virtual Environment](./local_dev_host.md#build-your-python-virtual-environment) section in our Local Development with host guide. ### A note about dependencies on Apple Silicon M1+ diff --git a/docs/local_dev_host.md b/docs/local_dev_host.md index 548aa05d91..94b571aebe 100644 --- a/docs/local_dev_host.md +++ b/docs/local_dev_host.md @@ -6,7 +6,7 @@ This guide will walk through setting up Kolibri Studio for local development, wh ## Prerequisites - [volta](https://docs.volta.sh/guide/getting-started) -- [pyenv](https://kolibri-dev.readthedocs.io/en/develop/howtos/installing_pyenv.html) and [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv#installation) +- [uv](https://docs.astral.sh/uv/) - Python package installer and virtual environment manager ## Install system dependencies and services Studio requires some background services to be running: @@ -75,29 +75,25 @@ exit # leave the postgres account ``` ## Build your python virtual environment -To determine what version of Python studio needs, you can check the `runtime.txt` file: -```bash -$ cat runtime.txt -# This is the required version of Python to run Studio currently. -# This is determined by the default Python 3 version that is installed -# inside Ubuntu Bionic, which is used to build images for Studio. -# We encode it here so that it can be picked up by Github's dependabot -# to manage automated package upgrades. -python-3.10.13 -``` -So to install python 3.10.13 through `pyenv` and set up a virtual environment: + +Studio uses [uv](https://docs.astral.sh/uv/) for Python dependency management and virtual environments. To set up your development environment: + ```bash -pyenv install 3.10.13 -pyenv virtualenv 3.10.13 studio-py3.10 -pyenv activate studio-py3.10 +# Create a virtual environment with uv (this will use the system Python or uv-managed Python) +uv venv --seed + +# Activate the virtual environment +source .venv/bin/activate ``` + Now you may install Studio's Python dependencies: ```bash -pip install -r requirements.txt -r requirements-dev.txt +uv pip sync requirements.txt requirements-dev.txt ``` + To deactivate the virtual environment, when you're finished developing on Studio for the time being: ```bash -pyenv deactivate +deactivate ``` ### A note about `psycopg2` diff --git a/docs/local_dev_wsl.md b/docs/local_dev_wsl.md index d94f308553..f5405cb01a 100644 --- a/docs/local_dev_wsl.md +++ b/docs/local_dev_wsl.md @@ -53,7 +53,7 @@ git clone https://github.com/$USERNAME/studio.git Replace `$USERNAME` with your GitHub username. ## Install Prerequisites -For detailed instructions on installing and configuring Volta, pyenv, and pyenv-virtualenv, please see the [Prerequisites](./local_dev_host.md#prerequisites) section in our Local Development with host guide. +For detailed instructions on installing and configuring Volta and uv, please see the [Prerequisites](./local_dev_host.md#prerequisites) section in our Local Development with host guide. ## Install System Dependencies and Services @@ -171,7 +171,7 @@ Now that you have your project open in VS Code, you can run the same commands yo 2. **Activate the Python Virtual Environment**: ```sh - pyenv activate studio-py3.10 + source .venv/bin/activate ``` 3. **Run the Services**: diff --git a/requirements-dev.in b/requirements-dev.in index 5690762c24..8a9224102c 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -7,5 +7,4 @@ pytest-django pytest-timeout pre-commit==4.5.1 nodeenv -pip-tools==7.5.2 drf-yasg==1.21.10 diff --git a/requirements-dev.txt b/requirements-dev.txt index 2e68164513..14d97846a2 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,21 +1,11 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile requirements-dev.in -# +# This file was autogenerated by uv via the following command: +# uv pip compile requirements-dev.in --output-file requirements-dev.txt asgiref==3.3.4 # via # -c requirements.txt # django -build==1.2.1 - # via pip-tools cfgv==3.3.1 # via pre-commit -click==8.1.3 - # via - # -c requirements.txt - # pip-tools distlib==0.3.9 # via virtualenv django==3.2.24 @@ -58,12 +48,8 @@ nodeenv==1.10.0 packaging==25.0 # via # -c requirements.txt - # build # drf-yasg # pytest - # wheel -pip-tools==7.5.2 - # via -r requirements-dev.in platformdirs==4.3.6 # via virtualenv pluggy==1.5.0 @@ -72,10 +58,6 @@ pre-commit==4.5.1 # via -r requirements-dev.in pygments==2.19.1 # via pytest -pyproject-hooks==1.1.0 - # via - # build - # pip-tools pytest==9.0.2 # via # -r requirements-dev.in @@ -110,10 +92,7 @@ sqlparse==0.4.1 tblib==1.7.0 # via django-concurrent-test-helper tomli==1.2.3 - # via - # build - # pip-tools - # pytest + # via pytest typing-extensions==4.15.0 # via # -c requirements.txt @@ -123,5 +102,3 @@ uritemplate==3.0.1 # via drf-yasg virtualenv==20.36.1 # via pre-commit -wheel==0.46.2 - # via pip-tools diff --git a/requirements.in b/requirements.in index b388f613fc..a245b120b0 100644 --- a/requirements.in +++ b/requirements.in @@ -15,12 +15,12 @@ python-postmark==0.7.0 Django==3.2.24 django-webpack-loader==0.7.0 google-cloud-error-reporting -google-cloud-storage +google-cloud-storage==2.19.0 django-s3-storage==0.15.0 requests>=2.20.0 google-cloud-core django-db-readonly==0.7.0 -google-cloud-kms==2.10.0 +google-cloud-kms==2.24.2 google-crc32c==1.8.0 backoff django-model-utils==5.0.0 diff --git a/requirements.txt b/requirements.txt index c05fafb9eb..fee81446ad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,5 @@ -# -# This file is autogenerated by pip-compile with Python 3.10 -# by the following command: -# -# pip-compile requirements.in -# +# This file was autogenerated by uv via the following command: +# uv pip compile requirements.in --output-file requirements.txt amqp==5.1.1 # via kombu annotated-types==0.7.0 @@ -26,8 +22,6 @@ botocore==1.20.75 # via # boto3 # s3transfer -cachetools==4.2.2 - # via google-auth celery==5.6.0 # via # -r requirements.in @@ -36,6 +30,8 @@ certifi==2020.12.5 # via # requests # sentry-sdk +cffi==2.0.0 + # via cryptography charset-normalizer==3.3.2 # via requests click==8.1.3 @@ -52,6 +48,8 @@ click-repl==0.2.0 # via celery confusable-homoglyphs==3.2.0 # via django-registration +cryptography==46.0.5 + # via google-auth django==3.2.24 # via # -r requirements.in @@ -97,47 +95,64 @@ djangorestframework==3.15.1 # via -r requirements.in exceptiongroup==1.3.1 # via celery -google-api-core[grpc]==1.27.0 +google-api-core==2.30.0 # via + # google-cloud-appengine-logging # google-cloud-core # google-cloud-error-reporting # google-cloud-kms # google-cloud-logging -google-auth==1.30.0 + # google-cloud-storage +google-auth==2.48.0 # via # google-api-core + # google-cloud-appengine-logging # google-cloud-core + # google-cloud-kms # google-cloud-storage -google-cloud-core==1.7.3 +google-cloud-appengine-logging==1.8.0 + # via google-cloud-logging +google-cloud-audit-log==0.4.0 + # via google-cloud-logging +google-cloud-core==2.5.0 # via # -r requirements.in # google-cloud-logging # google-cloud-storage google-cloud-error-reporting==1.4.0 # via -r requirements.in -google-cloud-kms==2.10.0 +google-cloud-kms==2.24.2 # via -r requirements.in -google-cloud-logging==2.3.1 +google-cloud-logging==2.7.1 # via google-cloud-error-reporting -google-cloud-storage==1.41.1 +google-cloud-storage==2.19.0 # via -r requirements.in google-crc32c==1.8.0 # via # -r requirements.in + # google-cloud-storage # google-resumable-media -google-resumable-media==1.3.0 +google-resumable-media==2.8.0 # via google-cloud-storage -googleapis-common-protos[grpc]==1.57.0 +googleapis-common-protos==1.57.0 # via # google-api-core + # google-cloud-audit-log # grpc-google-iam-v1 + # grpcio-status grpc-google-iam-v1==0.12.4 - # via google-cloud-kms -grpcio==1.53.2 + # via + # google-cloud-kms + # google-cloud-logging +grpcio==1.78.1 # via # google-api-core + # google-cloud-appengine-logging # googleapis-common-protos # grpc-google-iam-v1 + # grpcio-status +grpcio-status==1.62.3 + # via google-api-core gunicorn==23.0.0 # via -r requirements.in html5lib==1.1 @@ -172,9 +187,7 @@ packaging==25.0 # via # -r requirements.in # django-js-reverse - # google-api-core # google-cloud-error-reporting - # google-cloud-kms # gunicorn # kombu pillow==12.1.1 @@ -183,15 +196,21 @@ prometheus-client==0.10.1 # via django-prometheus prompt-toolkit==3.0.23 # via click-repl -proto-plus==1.18.1 +proto-plus==1.27.1 # via + # google-api-core + # google-cloud-appengine-logging # google-cloud-error-reporting # google-cloud-kms # google-cloud-logging protobuf==4.25.8 # via # google-api-core + # google-cloud-appengine-logging + # google-cloud-audit-log + # google-cloud-kms # googleapis-common-protos + # grpcio-status # proto-plus psycopg2-binary==2.9.11 # via -r requirements.in @@ -203,6 +222,8 @@ pyasn1-modules==0.2.8 # via google-auth pycountry==24.6.1 # via -r requirements.in +pycparser==3.0 + # via cffi pydantic==2.12.5 # via -r requirements.in pydantic-core==2.41.5 @@ -220,7 +241,6 @@ pytz==2022.1 # via # django # django-postmark - # google-api-core redis==7.1.0 # via # -r requirements.in @@ -247,17 +267,15 @@ sentry-sdk==2.48.0 six==1.16.0 # via # click-repl - # google-api-core - # google-auth - # google-cloud-core - # google-resumable-media # html5lib # python-dateutil sqlparse==0.4.1 # via django typing-extensions==4.15.0 # via + # cryptography # exceptiongroup + # grpcio # pydantic # pydantic-core # referencing @@ -282,6 +300,3 @@ wcwidth==0.2.5 # via prompt-toolkit webencodings==0.5.1 # via html5lib - -# The following packages are considered to be unsafe in a requirements file: -# setuptools