PyCafe for developers
Communication with users
Users of your software will most likely communicate with you through GitHub issues or other text-based communication channels. Often, code examples are shown in these communications, and more often than not, these code examples are not fully runnable. This can make it difficult to understand the problem the user is facing. By asking the user to provide a minimal, reproducible example that runs on PyCafe, you can focus on solving the problem, instead of trying to reproduce it.
GitHub issue templates
A good way to ask users to provide a minimal, reproducible example is by using GitHub issue templates. You can create a GitHub issue template file in your repository, which will be used as a template when users create a new issue. You can use this template to ask users to provide a minimal, reproducible example that runs on PyCafe.
Example 1: streamlit-aggrid
The streamlit-aggrid repository has a GitHub issue template that will ask users that open new issues to provide a minimal, reproducible example that runs on PyCafe.
...
**live code**
Please include a functional example. You may use the excellent [py.cafe](https://py.cafe/) to share your code.
...
This makes it much easier for the maintainers of the streamlit-aggrid project to understand the problem the user is facing and to help them solve it, possibly answering the question with another PyCafe example.
Example 2: Vizro
Vizro, a dashboarding solution developed at McKinsey, also uses a GitHub issue template that asks users to provide a minimal, reproducible example that runs on PyCafe.
...
description: Provide steps to reproduce this bug. You can also [use a PyCafe link](https://py.cafe/snippet/vizro/v1) to share your example.
...
Deploying and testing build artifacts
Often, during nightly runs, or when a PR is opened, one of the byproducts is a Python wheel that contains the potential new version of your library. Although tests should be run on the CI, it can be useful to deploy this wheel to PyCafe to test it in a real-world scenario, or to debug or visually inspect the changes made in the new version.
Instead of needing to check out the the branch on your local computer, or manually installing the wheel, you can easily install the wheel into a fresh PyCafe environment by entering the wheel URL into your requirements file.
Installing wheels from GitHub actions artifacts
For instance, Panel uses a nighty build to create a wheel that is uploaded to using the upload-artifact action. This wheel can be installed in a PyCafe environment by adding the following line to the requirements.txt
file:
# requirements.txt
https://py.cafe/gh/artifact/holoviz/panel/2021154790/panel-1.5.2-py3-none-any.whl
See API for more information on how to use this feature.
Installing wheels from S3
Streamlit uploads its wheels to an S3 bucket. These wheels can be installed in a PyCafe environment by adding the following line to the requirements.txt
file:
# requirements.txt
https://core-previews.s3-us-west-2.amazonaws.com/pr-9625/streamlit-1.39.0-py2.py3-none-any.whl
Generating snippet links
The PyCafe interface provides an UI to generate snippet links, under the ‘Share’ button. However, in automated workflows, it can be useful to generate these links programmatically.
See /docs/api for more information on how to generate snippet links programmatically.
Integration in CI / GitHub
Since GitHub artifacts can be very easily installed into a PyCafe environment, it can be useful to generate a link to a PyCafe snippet that will install that wheel. This link can be added as a comment to the PR, or as a status link on the PR so a reviewer can easily test the wheel by clicking on the link.
Create a Status Link
On the bottom of a pull request on GitHub you can create a status link. This link can be used to show the status of the PR, such as testing and linting, but it can also be used to put a link to a PyCafe snippet.
Note: see the link ‘PyCafe - Test out this PR on a PyCafe environment’ on the bottom of the above image, this link will bring you to a PyCafe snippet which the ipyreact wheel installed from the PR.
The easier way to create this is to use GitHub’s API using the PyGithub package, which can be installed with:
$ pip install PyGithub
Next, we can create a script that creates a status link for a PR (lets call it pycafe-create-status.py
):
import os
import sys
from urllib.parse import quote
from github import Github
# Authenticate with GitHub
access_token = os.getenv("GITHUB_TOKEN")
g = Github(access_token)
repo_name = "widgetti/ipyreact"
commit_sha = sys.argv[1] # e.g d39677a321bca34df41ecc87ff7e539b450207f2
run_id = sys.argv[2] # e.g 1324, usually obtained via ${{ github.run_id }} or ${{ github.event.workflow_run.id }} in GitHub Actions workflow files
type = "solara" # streamlit/dash/vizro/solara/panel
# your default code
code = """import ipyreact
class ConfettiWidget(ipyreact.ValueWidget):
_esm = \"""
import confetti from "canvas-confetti";
import * as React from "react";
export default function({value, setValue}) {
return <button onClick={() => confetti() && setValue(value + 1)}>
{value || 0} times confetti
</button>
};\"""
page = ConfettiWidget()
"""
artifact_name = "ipyreact-dist" # name given in the GitHub Actions workflow file for the artifact
# your default requirements, the wheel version number (0.4.2) is bumped up for each new release using bump2version
requirements = f"""solara
https://py.cafe/gh/artifact/{repo_name}/actions/runs/{run_id}/{artifact_name}/ipyreact-0.4.2-py3-none-any.whl
"""
# GitHub Python API
repo = g.get_repo(repo_name)
base_url = f"https://py.cafe/snippet/{type}/v1"
url = f"{base_url}#code={quote(code)}&requirements={quote(requirements)}"
# Define the deployment status
state = "success" # Options: 'error', 'failure', 'pending', 'success'
description = "Test out this PR on a PyCafe playground environment"
context = "PyCafe"
# Create the status on the commit
commit = repo.get_commit(commit_sha)
commit.create_status(state="success", target_url=url, description=description, context="PyCafe")
print(f"Deployment status added to commit {commit_sha}")
Now we can call this from our GitHub action:
name: PyCafe Playground Link
on:
workflow_run:
workflows: [Build]
types:
- completed
jobs:
create-status:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Create PyCafe status link
run: |
pip install PyGithub
python .github/pycafe-create-status.py ${{ github.event.workflow_run.head_sha }} ${{ github.event.workflow_run.id }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Note that we use workflow_run
instead of pull_request
to make sure the action runs with GITHUB_TOKEN
having write access (otherwise the Python script
does not have the permission to set the status). Note that workflow files used workflow_run
lives in your default branch, not in the PR branch, for security reasons,
see the GitHub documentation for details.
The above script and workflow file use the artifact make in a workflow file with the name Build'
:
name: Build
on:
push:
branches:
- master
tags:
- "v*"
pull_request:
workflow_dispatch:
jobs:
build:
....
- name: Package
run: hatch build
- name: Upload builds
uses: actions/upload-artifact@v3
with:
name: ipyreact-dist
path: |
./dist
./*.tgz
....
Example 1: ipyreact
The above use case is based on the ipyreact project. The files used can be found at:
- https://github.com/widgetti/ipyreact/blob/master/.github/pycafe-create-status.py
- https://github.com/widgetti/ipyreact/blob/master/.github/workflows/pycafe.yml
And the workflow file that creates the wheel is at:
Example 2: Vizro
The Vizro project creates a comment in the PR with several links to PyCafe snippets that install the wheel from the PR.
The relevant files are:
- https://github.com/mckinsey/vizro/blob/main/.github/workflows/pycafe-dashboards-in-CI.yml
- https://github.com/mckinsey/vizro/blob/main/tools/pycafe/create_pycafe_links.py
Example 3: Dash mantine components
The Dash mantine components project manually triggers a workflow that creates a status link on the PR, the relevant files are:
- https://github.com/snehilvj/dash-mantine-components/blob/master/.github/workflows/host-test.yml
- https://github.com/snehilvj/dash-mantine-components/blob/master/tmp_deploy.py
More examples?
If you have an interesting examples on CI / GitHub integration, please let us know so we can add them here, please contact us or join us on discord.