From c504eb76f7db8b7ec29ef4154b97b698f741c6a1 Mon Sep 17 00:00:00 2001 From: Jacob Curley Date: Mon, 27 Apr 2026 22:25:18 +0000 Subject: [PATCH 1/3] Add more detail to DevPod instructions --- README.md | 2 +- docs/devpod.md | 124 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 111 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d3b3c29..5d4df25 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ This repo includes a Dev Container descriptor file at [`.devcontainer/devcontain Read more about DevPod [here](https://devpod.sh/docs/what-is-devpod) -Docs: [`docs/devpod.md`](docs/devpod.md). +Full instructions: [`docs/devpod.md`](docs/devpod.md). ## Application Modes diff --git a/docs/devpod.md b/docs/devpod.md index 312af86..a6de39d 100644 --- a/docs/devpod.md +++ b/docs/devpod.md @@ -17,25 +17,121 @@ The workspace uses the external image referenced there, which is expected to pro ## Use -1. On your local machine, [install DevPod](https://devpod.sh/docs/getting-started/install). -2. Open DevPod and enter the URL of your project's GitHub repository, or point it to the local directory if you've already cloned the repo. -3. After the workspace starts, run the default build command, or run it manually: +### Setup - ```bash - uv sync - ``` +1. Ensure [VS Code is set up](#vs-code) +2. Prepare your machine + - [Mac](#mac) + - [Windows](#windows) +3. On your local machine, [install DevPod](https://devpod.sh/docs/getting-started/install#install-devpod). +4. Open DevPod and enter the URL of your project's GitHub repository, or point it to the local directory if you've already cloned the repo. +5. Select Docker as the "Provider" + - If on Windows, edit the advanced options to specify the "Host" as `tcp://127.0.0.1:2375` +6. Select VS Code as your IDE +7. Click Create - the dev container will be pulled down and started for you, and VS Code should open +8. After the workspace starts, open a terminal in VS Code and run + ```bash + uv sync --dev --all-extras + ``` +9. Run tests + ```bash + uv run pytest + ``` +10. Run the CLI app + ```bash + uv run ap-python-starter-kit + ``` -4. Run tests: +### Prerequisites - ```bash - uv run pytest - ``` +#### VS Code -5. Run the CLI app: +1. [Install VS Code](https://code.visualstudio.com/download) +2. Open VS Code and navigate to the Extensions tab (icon looks like four squares, where the top-right square is rotated 45 degrees) +3. In the search bar at the top, type "Dev Containers" and install the extension from Microsoft +4. (Windows-only) Do the same as step 3, searching for and installing the "WSL" extension (also by Microsoft) - ```bash - uv run ap-python-starter-kit - ``` +#### Mac + +Mac users will require Docker to be installed. While Windows users can leverage Docker Engine to avoid licensing issues, Mac users will have to leverage an open-source alternative called [Colima](https://github.com/abiosoft/colima). + +1. Install Colima using [one of the provided methods](https://github.com/abiosoft/colima/blob/main/docs/INSTALL.md) +2. Start Colima using + ```bash + colima start + ``` +3. During DevPod setup, follow the instructions for using Docker as your provider. Colima will be substituted by DevPod automatically. + +#### Windows +If your local machine is running Windows, you will need to have Windows Subsystem for Linux installed, with Docker or some other pod management system installed there. Here are the steps to accomplish this: + +1. Run the following in a terminal with administrator rights (you may be asked to restart your machine) + ```PowerShell + wsl --install + ``` + Ubuntu will be the default Linux distribution, and the remainder of this guide will target that. +2. Open the Start menu and type `wsl`. Run the WSL application. +3. You will be asked to set up a username and password in the Ubuntu instance. This has no bearing on your Windows environment. The user you set up will have administrator (sudo) permissions in the Ubuntu image. +4. Update the packages installed by running + ```bash + sudo apt update && sudo apt upgrade + ``` +5. Install needed packages for Docker + ```bash + sudo apt install ca-certificates curl gnupg lsb-release + ``` +6. Set up GPG for Docker authentication + ```bash + sudo mkdir -p /etc/apt/keyrings + ``` + ```bash + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg + ``` +7. Configure GPG authentication + ```bash + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + ``` +8. Install Docker Engine + ```bash + sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin + ``` +9. Add your user to the `docker` group (prevents needing to use `sudo` for every Docker command) + ```bash + sudo usermod -aG docker $USER + ``` +10. Start Docker + ```bash + sudo systemctl enable --now docker + ``` + ```bash + sudo systemctl enable containerd + ``` + Verify Docker is running + ```bash + sudo systemctl status docker + ``` +11. Configure Docker to be accessible to DevPod + ```bash + sudo systemctl edit --full docker.service + ``` + This should open an editor. Look for + ``` + ... + [Service] + ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock + ... + ``` + On the end of this line, add `-H tcp://127.0.0.1:2375`. The full entry should now read + ``` + ... + [Service] + ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://127.0.0.1:2375 + ... + ``` + Now run + ```bash + sudo systemctl daemon-reload && sudo systemctl restart docker.service + ``` ## Notes From fbc30f783ebaa1e8516262c246e5d7cdafa1a48b Mon Sep 17 00:00:00 2001 From: Jacob Curley Date: Tue, 28 Apr 2026 16:47:54 +0000 Subject: [PATCH 2/3] Migration guide --- README.md | 23 ++------- docs/devpod.md | 3 +- docs/migration.md | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 20 deletions(-) create mode 100644 docs/migration.md diff --git a/README.md b/README.md index 5d4df25..a239530 100644 --- a/README.md +++ b/README.md @@ -8,30 +8,15 @@ A Python-first project template with one installable application package that pr 1. **Do not** clone this repo! Instead, click "**Use this template**" at the top right of its GitHub page, then click "**Create a new repository**" and complete the form to create a new repo using this template. -2. Rename the template to make it your own project: +2. [Set up your development environment](docs/devpod.md) - ```bash - python3 scripts/rename_project.py - ``` - -3. Install dependencies: - - ```bash - uv sync - ``` - -4. Run the app in CLI mode: +3. Rename the template to make it your own project: ```bash - uv run ap-python-starter-kit + python3 scripts/rename_project.py ``` -5. Optionally install GUI support and run the integrated GUI through the main launcher: - - ```bash - uv sync --extra gui-pyqt - uv run ap-python-starter-kit --gui - ``` +4. Code away! Detailed onboarding is in [`docs/quickstart.md`](docs/quickstart.md). diff --git a/docs/devpod.md b/docs/devpod.md index a6de39d..6949e9b 100644 --- a/docs/devpod.md +++ b/docs/devpod.md @@ -19,7 +19,7 @@ The workspace uses the external image referenced there, which is expected to pro ### Setup -1. Ensure [VS Code is set up](#vs-code) +1. Ensure [VS Code is set up](#vs-code). This includes installing some necessary extensions, listed in the instructions. 2. Prepare your machine - [Mac](#mac) - [Windows](#windows) @@ -63,6 +63,7 @@ Mac users will require Docker to be installed. While Windows users can leverage 3. During DevPod setup, follow the instructions for using Docker as your provider. Colima will be substituted by DevPod automatically. #### Windows + If your local machine is running Windows, you will need to have Windows Subsystem for Linux installed, with Docker or some other pod management system installed there. Here are the steps to accomplish this: 1. Run the following in a terminal with administrator rights (you may be asked to restart your machine) diff --git a/docs/migration.md b/docs/migration.md new file mode 100644 index 0000000..6e68d4a --- /dev/null +++ b/docs/migration.md @@ -0,0 +1,118 @@ +# Migrating an existing Python project + +This guide will walk through the steps to take when pulling an existing Python project into the +AP Python ecosystem. + +### Assumptions + +This guide assumes your project uses `pip` as a package manager and `PyQt 5` as a GUI framework. +There will be sections dedicated to migrating from `pip` to `uv` and from `PyQt 5` to `PyQt 6`. +Feel free to skip these if you're already set up with `uv` and `PyQt 6`. + +Included at the end of this guide are a few extra Quality-of-Life enhancements made to the original Auto Quad Centering application when testing out the migration process. They have to do with the application itself rather than the project configuration, so they may or may not have relevance in other applications. + +## General migration steps + +1. Construct a new repository for your migrated application from this template, using the "**Create a new repository**" button. +2. Ensure your AP Python development environment is set up. Follow [the guide](docs/devpod.md) for complete instructions. +3. Use the rename script (run `python3 scripts/rename_project.py` in the DevPod for your migrated project repository) to change the project package name. +Make it match the package name you use in your source project. + + For example, for Auto Quad Centering, the project name became `auto-quad-centering` and the package name was likewise `auto_quad_centering`. +4. Replace the contents of `src/` with your existing Python code to be migrated. +5. If your source project used `pip`, follow the [`pip` to `uv` migration steps](#pip-to-uv-migration). +6. If your source project used `PyQt 5`, follow the [`PyQt 5` to `PyQt 6` migration steps](#pyqt-5-to-pyqt-6). + +## `pip` to `uv` migration + +`uv` and its dependencies are already installed in your DevPod environment. To build with `uv`, you'll simply need to let it know what Python packages your project depends on and where the entrypoint for your code is. This is configured in the `pyproject.toml` file at the root of the repository. The exact version of the dependencies used by `uv` when building your code will be recorded in the `uv.lock` file. + +Migration steps are as follows: + +1. Copy the contents of your `requirements.txt` file to your clipboard +2. Locate the `[project]` section of the `pyproject.toml`, and paste the `requirements.txt` contents into the `dependencies` array. + Modify the dependency entries so they are comma-delimited and each is surrounded by quotes. + + Example: + + `requirements.txt` + ```txt + numpy>=1.19.0 + pandas>=2.0.0 + matplotlib>=3.3.0 + ... + ``` + becomes + + `pyproject.toml` + ```toml + ... + [project] + ... + dependencies = [ + "acsys", + "acsys[settings]", + "numpy>=1.19.0", + "pandas>=2.0.0", + "matplotlib>=3.3.0", + ... + ] + ... + ``` +3. Refresh the `uv.lock` file by running `uv sync` in the command line +4. Rebuild the virtual environment by running `uv venv --clear` in the command line (this may take a minute to complete) + - Be sure to run `source .venv/bin/activate` once the virtual environment has been rebuilt + - Also run `uv run pre-commit install` to ensure the Git pre-commit hooks work correctly +5. (optional) You can delete your `requirements.txt`. All dependencies should now be handled via the `pyproject.toml` file. Use `uv add` and `uv remove` to update your dependencies from the command line, or edit the `dependencies` section of `pyproject.toml` directly. + + `uv --help` has a complete list of the commands available with `uv`. + +6. Update the project entrypoint in `pyproject.toml` + + By now, your `pyproject.toml` should have a section that looks like + ```toml + ... + [project.scripts] + = ".main:main" + ... + ``` + + Update this section so the `.main:main` portion reflects the name and main function of the entry file for your project. For example, Auto Quad Centering has this section as + ```toml + ... + [project.scripts] + auto-quad-centering = "auto_quad_centering.autocenter:main" + ... + ``` + This reflects that the main file for the project is `auto_quad_centering/autocenter.py`, and the entrypoint for that file is a function called `main()`. + +## `PyQt 5` to `PyQt 6` + +While the bulk of upgrading from PyQt 5 to PyQt 6 is simply a matter of updating your import statements (i.e., `from PyQt5 import ...` becoming `from PyQt6 import ...`), there are a couple breaking changes to be aware of. + +- PyQt 6 demands fully-qualified enums, e.g. `Qt.AlignCenter` must now be `Qt.AlignmentFlag.AlignCenter` +- Any uses of PyQt 5's `exec_()` function must now use the standard `exec()` function from Python 3 +- Various classes have moved to different modules (e.g. `QAction` and `QShortcut` are now in `QtGui` rather than `QtWidgets`) +- Some methods/APIs have changed (e.g. `QMouseEvent` now uses `.position()` instead of `.x()` and `.y()`) + +For a deeper breakdown and migration guide, see [this article](https://www.pythonguis.com/faq/pyqt5-vs-pyqt6/). + +## Auto Quad Centering addons + +The following are some enhancements made to the original Auto Quad Centering application so it plays a little nicer with the Xpra runtime. + +1. Added scrolling behavior to all tabs + + The Xpra runtime only exposes a certain amount of screen real estate. The original Auto Quad Centering app went off the screen by quite a bit, when first tested in the Xpra deployment. To resolve this, a `QScrollArea` was added to each of the tab widgets in the `ui` directory. + +2. Added a Kerberos login dialog + + Auto Quad Centering requires the user to have an active Kerberos ticket to make settings to the accelerator. The original application assumed such a ticket would already be available in the host runtime. With the move to the remote Xpra environment, this is no longer a valid assumption. + + A small username/password dialog was added to `ui/dialogs.py` that would be activated when the user selects to generate a new ticket. This allows the migrated app to leverage the preexisting code to generate a ticket in Kerberos from `auth/kerberos_manager.py`. + +3. Updated the file loading process to reflect the remote runtime + + The original application expected to be able to load files from the user's system. With the deployment to a remote Xpra instance, this is no longer a straightforward process. Users must first upload files to the Xpra runtime, and only then can the application access those files. The same is true, but in reverse, for files generated by the app. It writes the file to the Xpra runtime, and users must initiate the process in Xpra to download a file from the remote filesystem. + + To help clarify this, some modifications were made to the file upload section in `ui/setup_tab.py`. There is now descriptive text to call out the new process. \ No newline at end of file From 5f134c681725ff3a171a8d395681a5126373c296 Mon Sep 17 00:00:00 2001 From: Jacob Curley Date: Wed, 29 Apr 2026 20:34:01 +0000 Subject: [PATCH 3/3] Updates for local GUI development --- .devcontainer/devcontainer.json | 8 ++++++- docs/devpod.md | 20 +++++++++++++++++ docs/migration.md | 38 ++++----------------------------- 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f1df92f..044a698 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,12 @@ { "name": "ap-python", "image": "adregistry.fnal.gov/dev-containers/ap-python:latest", + "features": { + "ghcr.io/devcontainers/features/desktop-lite:1": { + "password": "", + "webPort": 6080 + } + }, "customizations": { "vscode": { "extensions": [ @@ -24,5 +30,5 @@ } } }, - "postCreateCommand": "uv sync --dev --all-extras && uv run pre-commit install" + "postStartCommand": "uv sync --dev --all-extras && uv run pre-commit install" } diff --git a/docs/devpod.md b/docs/devpod.md index 6949e9b..2a8d6cb 100644 --- a/docs/devpod.md +++ b/docs/devpod.md @@ -41,6 +41,12 @@ The workspace uses the external image referenced there, which is expected to pro ```bash uv run ap-python-starter-kit ``` +11. (Optional) Run the GUI + 1. [Set up access to the container's desktop](#ui-development-after-setup-is-complete) + 2. Run + ```bash + uv run ap-python-starter-kit --gui + ``` ### Prerequisites @@ -134,6 +140,20 @@ If your local machine is running Windows, you will need to have Windows Subsyste sudo systemctl daemon-reload && sudo systemctl restart docker.service ``` +### UI development (After setup is complete) + +While building your app, you'll probably want to test out changes to the UI before deploying. In the container, this requires one preliminary step. + +The development container comes with a minimal desktop overlay, in which your app will run when you kick it off. To see it, do the following: + +1. In VS Code, go to the "Ports" tab of the bottom panel (toggle the panel with the appropriate button in the very top-right if it is not already visible) +2. Click the "Forward a Port" button +3. Type `6080` and hit Enter +4. If it doesn't open automatically, go to your web browser and navigate to `localhost:6080` +5. Click "Connect" + +You're all set! Now when you run the app locally, it will come up in your web browser at `localhost:6080`. + ## Notes - The template placeholders (`ap-python-starter-kit`, `ap_python_starter_kit`, and similar values) are expected to be replaced when you generate a real project from this template. diff --git a/docs/migration.md b/docs/migration.md index 6e68d4a..bc57d83 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -29,45 +29,15 @@ Make it match the package name you use in your source project. Migration steps are as follows: -1. Copy the contents of your `requirements.txt` file to your clipboard -2. Locate the `[project]` section of the `pyproject.toml`, and paste the `requirements.txt` contents into the `dependencies` array. - Modify the dependency entries so they are comma-delimited and each is surrounded by quotes. - - Example: - - `requirements.txt` - ```txt - numpy>=1.19.0 - pandas>=2.0.0 - matplotlib>=3.3.0 - ... - ``` - becomes - - `pyproject.toml` - ```toml - ... - [project] - ... - dependencies = [ - "acsys", - "acsys[settings]", - "numpy>=1.19.0", - "pandas>=2.0.0", - "matplotlib>=3.3.0", - ... - ] - ... - ``` -3. Refresh the `uv.lock` file by running `uv sync` in the command line -4. Rebuild the virtual environment by running `uv venv --clear` in the command line (this may take a minute to complete) +1. In the command line, run `uv add -r src//requirements.txt` +2. Rebuild the virtual environment by running `uv venv --clear` in the command line (this may take a minute to complete) - Be sure to run `source .venv/bin/activate` once the virtual environment has been rebuilt - Also run `uv run pre-commit install` to ensure the Git pre-commit hooks work correctly -5. (optional) You can delete your `requirements.txt`. All dependencies should now be handled via the `pyproject.toml` file. Use `uv add` and `uv remove` to update your dependencies from the command line, or edit the `dependencies` section of `pyproject.toml` directly. +3. (optional) You can delete your `requirements.txt`. All dependencies should now be handled via the `pyproject.toml` file. Use `uv add` and `uv remove` to update your dependencies from the command line, or edit the `dependencies` section of `pyproject.toml` directly. `uv --help` has a complete list of the commands available with `uv`. -6. Update the project entrypoint in `pyproject.toml` +4. Update the project entrypoint in `pyproject.toml` By now, your `pyproject.toml` should have a section that looks like ```toml