Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
72b7233
Refactor Python installation tasks in main.yml
WojciechKozak98 Oct 19, 2026
2698712
Refactor Python installation tasks in main.yml
WojciechKozak98 Oct 19, 2026
a83e26a
Update pip install commands with extra_args
WojciechKozak98 Oct 19, 2026
e47f704
Update install-jupyter.yml
WojciechKozak98 Oct 19, 2026
4deec81
Fix typo in system_dependencies key
WojciechKozak98 Oct 19, 2026
6fba485
Update _rocky-8.yml
WojciechKozak98 Oct 19, 2026
909ef8d
Update .ansible-lint
WojciechKozak98 Oct 19, 2026
6fc1938
Change uv installation method to use a script
WojciechKozak98 Oct 19, 2026
2377f7f
Download uv install script before installation
WojciechKozak98 Oct 19, 2026
ca147b0
Update _ubuntu.yml
WojciechKozak98 Oct 19, 2026
019bae7
Add curl to system dependencies in _redhat-9.yml
WojciechKozak98 Oct 19, 2026
b250c66
Add curl to system dependencies in rocky-8.yml
WojciechKozak98 Oct 19, 2026
7db857d
Refactor pip installation to use environment variables
WojciechKozak98 Oct 19, 2026
777b1b5
Refactor Jupyter package installation in Ansible playbook
WojciechKozak98 Oct 19, 2026
d8a8fac
Refactor Jupyter package installation task
WojciechKozak98 Oct 19, 2026
6e6390e
Refactor Jupyter package installation task
WojciechKozak98 Oct 19, 2026
e2aad60
Add 'allowerasing' option to dnf task
WojciechKozak98 Oct 19, 2026
21f4f7f
Add uv_version to main.yml
WojciechKozak98 Oct 21, 2026
33428fe
Add Ansible tasks for installing Python using uv
WojciechKozak98 Oct 21, 2026
d666009
Refactor Python installation tasks in main.yml
WojciechKozak98 Oct 21, 2026
d940c28
Refactor Python installation tasks in main.yml
WojciechKozak98 Oct 21, 2026
ea152c9
Fix formatting in install-jupyter.yml
WojciechKozak98 Oct 21, 2026
1f44cda
Remove Python installation task inclusion
WojciechKozak98 Oct 21, 2026
61701ed
Remove Python installation task inclusion
WojciechKozak98 Oct 21, 2026
0260373
Add shared installation tasks for Python
WojciechKozak98 Oct 21, 2026
d77fc58
Update description for Python installation role
WojciechKozak98 Oct 22, 2026
bfa4491
Update installation method and add uv version info
WojciechKozak98 Oct 22, 2026
3361818
Add changelog for Python installation updates
WojciechKozak98 Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .ansible-lint
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ exclude_paths:
- molecule/jupyter-system
offline: false
use_default_rules: true
parseable: true
verbosity: 1
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Changed
- Python installation now uses [`uv`](https://docs.astral.sh/uv/) instead of Posit's prebuilt binaries, which are no longer being built by Posit for new Python versions.
- `uv` itself is installed by downloading a pinned release archive from GitHub releases, rather than running the upstream install script.
- The symlink from `/opt/python/{{ version }}` to the actual `uv`-managed install directory is now created with the `ansible.builtin.file` module instead of a raw shell command.
- Installation tasks shared between Debian and RedHat families were extracted into a common `tasks/install-python.yml`, included by both `tasks/debian/main.yml` and `tasks/redhat/main.yml`.
- `pip` calls that install directly into the `uv`-managed Python now set `PIP_BREAK_SYSTEM_PACKAGES`/`PIP_ROOT_USER_ACTION` as environment variables (needed for PEP 668 "externally managed environment" enforcement on newer Python/pip versions).

### Added
- New `uv_version` variable controlling which `uv` release gets installed.
- `curl` added to the system dependencies list (needed by the `uv` install process).

### Removed
- `python_download_url` variable (no longer used now that Python isn't downloaded as a distro-specific package).
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Ansible Python Install

Install Python (with Jupyter) on Ubuntu and RedHat based systems with Posit's pre-compiled binaries ([docs](https://docs.posit.co/resources/install-python/))
Install Python (with Jupyter) on Ubuntu and RedHat based systems via `uv` ([docs](https://docs.posit.co/resources/install-python-uv.html))

[![CI](https://github.com/Appsilon/ansible-python-install/workflows/CI/badge.svg)](https://github.com/Appsilon/ansible-python-install/actions/workflows/ci.yml)
[![Ansible Galaxy](https://img.shields.io/badge/ansible--galaxy-appsilon.python_install-blue.svg)](https://galaxy.ansible.com/appsilon/python_install)
Expand All @@ -19,6 +19,7 @@ If you want to install Workbench's plugins, then the Python used for Jupyter ins
| python_jupyter_install_method | virtualenv | String: virtualenv, system | Method of Jupyter installation |
| python_jupyter_python_version | `"{{ python_versions[0] }}"` | One of the versions passed in python_versions | Used only for virtualenv method |
| python_jupyter_workbench | true | Boolean: true, false | Whether to install Workbench's plugins for Jupyter |
| uv_version | "0.13.4" | String | Version of `uv` to install from GitHub releases |

## Dependencies

Expand Down
1 change: 1 addition & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ python_jupyter_workbench: true
python_jupyter_workbench_packages:
- rsp_jupyter
- workbench_jupyterlab==1.1.315
uv_version: "0.13.4"
2 changes: 1 addition & 1 deletion meta/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ galaxy_info:
role_name: python_install
author: appsilon
company: Appsilon
description: Install Python with Posit's pre-compiled binaries
description: Install Python via uv (Posit-recommended python-build-standalone distributions)
license: MIT
min_ansible_version: 2.11.1
platforms:
Expand Down
28 changes: 1 addition & 27 deletions tasks/debian/main.yml
Comment thread
koralowiec marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,4 @@
update_cache: true
cache_valid_time: "{{ apt_update_cache_valid_time | default(3600) }}"
tags:
- python-install-system-dependecies

- name: Install Python | Set release version
ansible.builtin.set_fact:
ubuntu_release: "{{ ansible_facts['distribution_version'] | replace('.', '') }}"
when: ansible_facts['distribution'] == "Ubuntu"
tags:
- python-install-set-facts
- python-install-setup-versions

- name: Install Python | Download deb package
ansible.builtin.get_url:
url: "https://cdn.rstudio.com/python/ubuntu-{{ ubuntu_release }}/pkgs/python-{{ item }}_1_amd64.deb"
dest: "/tmp/Python-{{ item }}.deb"
mode: "0644"
loop: "{{ python_versions }}"
tags:
- python-install-download-archives
- python-install-setup-versions

- name: Install Python | Install deb package
ansible.builtin.apt:
deb: "/tmp/Python-{{ item }}.deb"
loop: "{{ python_versions }}"
tags:
- python-install-install-archives
- python-install-setup-versions
- python-install-system-dependencies
3 changes: 3 additions & 0 deletions tasks/install-jupyter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
ansible.builtin.pip:
name: "{{ python_jupyter_packages }}"
executable: pip3
environment:
PIP_BREAK_SYSTEM_PACKAGES: "1"
PIP_ROOT_USER_ACTION: ignore
when: python_jupyter_install_method == "system"

- name: Install Python | Set path to jupyter-nbextension
Expand Down
45 changes: 45 additions & 0 deletions tasks/install-python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
- name: Install Python | Download uv release archive
ansible.builtin.get_url:
url: "https://github.com/astral-sh/uv/releases/download/{{ uv_version }}/uv-x86_64-unknown-linux-gnu.tar.gz"
dest: /tmp/uv.tar.gz
mode: "0644"

- name: Install Python | Extract uv binary
ansible.builtin.unarchive:
src: /tmp/uv.tar.gz
dest: /usr/local/bin
remote_src: true
extra_opts:
- --strip-components=1
- --wildcards
- "*/uv"
creates: /usr/local/bin/uv

- name: Install Python | Install Python versions via uv
ansible.builtin.command: /usr/local/bin/uv python install {{ item }} --install-dir=/opt/python
loop: "{{ python_versions }}"
register: command_result
changed_when: "'Installed' in command_result.stdout"
tags:
- python-install-install-archives
- python-install-setup-versions

- name: Install Python | Find installed build directory
ansible.builtin.find:
paths: /opt/python
patterns: "cpython-{{ item }}-*"
file_type: directory
loop: "{{ python_versions }}"
register: python_build_dirs
tags:
- python-install-setup-versions

- name: Install Python | Symlink versioned path
ansible.builtin.file:
src: "{{ (item.files | first).path }}"
dest: "/opt/python/{{ item.item }}"
state: link
loop: "{{ python_build_dirs.results }}"
tags:
- python-install-setup-versions
9 changes: 9 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@
- name: Install Python | Include installation tasks
ansible.builtin.include_tasks: '{{ ansible_os_family | lower }}/main.yml'

- name: Install Python | Include shared installation tasks
ansible.builtin.include_tasks: install-python.yml

- name: Install Python | Upgrade tools
ansible.builtin.command: >
/opt/python/{{ item }}/bin/pip install --upgrade \
pip setuptools wheel
environment:
PIP_BREAK_SYSTEM_PACKAGES: "1"
PIP_ROOT_USER_ACTION: ignore
loop: "{{ python_versions }}"
register: command_result
changed_when: "'Successfully installed' in command_result.stdout"
Expand All @@ -41,6 +47,9 @@
ansible.builtin.pip:
executable: "/opt/python/{{ item }}/bin/pip"
name: ipykernel
environment:
PIP_BREAK_SYSTEM_PACKAGES: "1"
PIP_ROOT_USER_ACTION: ignore
loop: "{{ python_versions }}"

- name: Install Python | Check if kernel.json exists
Expand Down
24 changes: 2 additions & 22 deletions tasks/redhat/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,5 @@
ansible.builtin.dnf:
name: "{{ system_dependecies }}"
state: present
when: system_dependecies is defined


- name: Install Python | Download rpm package
ansible.builtin.get_url:
url: "{{ python_download_url }}/python-{{ item }}-1-1.x86_64.rpm"
dest: "{{ downloads_path }}/python-{{ item }}-1-1.x86_64.rpm"
mode: "0644"
loop: "{{ python_versions }}"
tags:
- python-install-download-archives
- python-install-setup-versions

- name: Install Python | Install rpm package
ansible.builtin.dnf:
name: "{{ downloads_path }}/python-{{ item }}-1-1.x86_64.rpm"
disable_gpg_check: true
state: present
loop: "{{ python_versions }}"
tags:
- python-install-install-archives
- python-install-setup-versions
allowerasing: true
when: system_dependecies is defined
2 changes: 1 addition & 1 deletion vars/_redhat-9.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# vars file
---
system_dependecies:
- curl
- libev-devel
python_download_url: "https://cdn.rstudio.com/python/rhel-9/pkgs"
2 changes: 1 addition & 1 deletion vars/_rocky-8.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# vars file
---
system_dependecies:
- curl
- libev-devel
python_download_url: "https://cdn.rstudio.com/python/centos-8/pkgs"
1 change: 1 addition & 0 deletions vars/_ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
---
python_system_dependecies:
- build-essential
- curl
- libffi-dev
- libgdbm-dev
- libsqlite3-dev
Expand Down
Loading