Skip to content

Commit

Permalink
Add patch to allow URL use by default (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
coatless authored Mar 2, 2024
1 parent f83c77b commit 278e126
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 9 deletions.
21 changes: 16 additions & 5 deletions _extensions/pyodide/qpyodide-document-engine-initialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,21 @@ globalThis.qpyodideInstance = await import(

// Setup a namespace for global scoping
// await loadedPyodide.runPythonAsync("globalScope = {}");

// Update status to reflect the next stage of the procedure
qpyodideUpdateStatusHeaderSpinner("Initializing Python Packages");

// Load the `micropip` package to allow installation of packages.
await mainPyodide.loadPackage("micropip");
await mainPyodide.runPythonAsync(`import micropip`);

// Load the `pyodide_http` package to shim uses of `requests` and `urllib3`.
// This allows for `pd.read_csv(url)` to work flawlessly.
// Details: https://github.com/coatless-quarto/pyodide/issues/9
await mainPyodide.loadPackage("pyodide_http");
await mainPyodide.runPythonAsync(`
import micropip
import pyodide_http
pyodide_http.patch_all() # Patch all libraries
`);

// Load the `matplotlib` package with necessary environment hook
Expand All @@ -53,11 +63,12 @@ globalThis.qpyodideInstance = await import(
qpyodideSetInteractiveButtonState(
`<i class="fa-solid fa-play qpyodide-icon-run-code"></i> <span>Run Code</span>`,
true
);
);

if (qpyodideShowStartupMessage) {
qpyodideStartupMessage.innerText = "🟢 Ready!"
}
// Set document status to viable
qpyodideUpdateStatusHeader(
"🟢 Ready!"
);

// Assign Pyodide into the global environment
globalThis.mainPyodide = mainPyodide;
Expand Down
15 changes: 13 additions & 2 deletions _extensions/pyodide/qpyodide-document-status.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,22 @@ globalThis.qpyodideUpdateStatusMessage = function(message) {

// Function to update the status message
globalThis.qpyodideUpdateStatusHeader = function(message) {
qpyodideStartupMessage.innerHTML = `

if (!qpyodideShowStartupMessage) return;

qpyodideStartupMessage.innerHTML = message;
}

// Status header update with customized spinner message
globalThis.qpyodideUpdateStatusHeaderSpinner = function(message) {

qpyodideUpdateStatusHeader(`
<i class="fa-solid fa-spinner fa-spin qpyodide-icon-status-spinner"></i>
<span>${message}</span>`;
<span>${message}</span>
`);
}


// Function that attaches the document status message
function qpyodideDisplayStartupMessage(showStartupMessage) {
if (!showStartupMessage) {
Expand Down
29 changes: 27 additions & 2 deletions docs/qpyodide-code-cell-demo.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,22 @@ num_list = [1, 2, 3]

## Load a package

We've enabled _dynamic_ package detection to handle importing packages into the environment. The _dynamic_ part comes from detecting whether a non-core Python package is used, installing, and, then, importing it.
There are two types of Python packages that will work within an interactive cell.

- pure Python packages
- denoted by `*py3-none-any.whl` on PyPI
- Python packages compiled for Pyodide
- denoted by `*-cp310-cp310-emscripten_3_1_27_wasm32.whl` that require a specific Python and Emscripten versions

The latter option makes up part of the Pyodide "core" or "base" set of Python packages.

:::{.callout-important}
Not all functionality of a Python package may be available in the browser due to limitations or different versions being present.
:::

### Loading a Pyodide core package

For packages that are part of [Pyodide core](https://pyodide.org/en/stable/usage/packages-in-pyodide.html), we've enabled _dynamic_ package detection to handle importing packages into the environment. The _dynamic_ part comes from detecting whether a Python package is being used through an import statement and automatically taking care of the installation process behind the scenes.

:::{.callout-note}
Importing a package for the first time will require more time. Subsequent import statements will be resolve quicker.
Expand Down Expand Up @@ -173,7 +188,7 @@ from palmerpenguins import load_penguins
# Load data in the package
penguins = load_penguins()
# Display th e first 5 rows of the data using Pandas
# Display the first 5 rows of the data using Pandas
penguins.head()
```

Expand All @@ -190,3 +205,13 @@ y = [-5, 8, 9, 4]
plt.plot(x, y)
plt.show()
```

## External Data

Interactive cells also allow for a limited subset of operations when working with external data. For example, we can use Pandas' `read_csv()` function to ingest data from a URL.
```{pyodide-python}
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv")
df.head()
```
7 changes: 7 additions & 0 deletions docs/qpyodide-release-notes.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ format:

- New code cell option that set the interactive cell to be read-only. ([#4](https://github.com/coatless-quarto/pyodide/issues/4))

## Changes

- We now load the `micropip` and `pyodide_http` packages during document initialization.
- `micropip` package allows for installation of pure Python or Pyodide-compiled Python packages.
([#3](https://github.com/coatless-quarto/pyodide/issues/3))
- `pyodide_http` provides the necessary shims to ensure uses of `requests` and `urllib3` are
able to be processed instead of returning a URL error. ([#9](https://github.com/coatless-quarto/pyodide/issues/9))

# 0.0.1: What does the Python Say? (02-19-2024)

Expand Down
15 changes: 15 additions & 0 deletions tests/qpyodide-test-url.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: "Test: Accessing Data via URL"
format: html
filters:
- pyodide
---

This test is designed to check if HTTP requests are shimmed so that the operation can be performed.

```{pyodide-python}
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv")
df.head()
```

0 comments on commit 278e126

Please sign in to comment.