Skip to content

Commit

Permalink
Rename the package to shinywidgets (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpsievert authored Jul 12, 2022
1 parent d24a777 commit c3d8d61
Show file tree
Hide file tree
Showing 34 changed files with 76 additions and 88 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
* ipyshiny version:
* shinywidgets version:
* Python version:
* Operating System:

Expand Down
24 changes: 12 additions & 12 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Types of Contributions
Report Bugs
~~~~~~~~~~~

Report bugs at https://github.com/rstudio/ipyshiny/issues.
Report bugs at https://github.com/rstudio/shinywidgets/issues.

If you are reporting a bug, please include:

Expand All @@ -38,14 +38,14 @@ and "help wanted" is open to whoever wants to implement it.
Write Documentation
~~~~~~~~~~~~~~~~~~~

ipyshiny could always use more documentation, whether as part of the
official ipyshiny docs, in docstrings, or even on the web in blog posts,
shinywidgets could always use more documentation, whether as part of the
official shinywidgets docs, in docstrings, or even on the web in blog posts,
articles, and such.

Submit Feedback
~~~~~~~~~~~~~~~

The best way to send feedback is to file an issue at https://github.com/rstudio/ipyshiny/issues.
The best way to send feedback is to file an issue at https://github.com/rstudio/shinywidgets/issues.

If you are proposing a feature:

Expand All @@ -57,17 +57,17 @@ If you are proposing a feature:
Get Started!
------------

Ready to contribute? Here's how to set up `ipyshiny` for local development.
Ready to contribute? Here's how to set up `shinywidgets` for local development.

1. Fork the `ipyshiny` repo on GitHub.
1. Fork the `shinywidgets` repo on GitHub.
2. Clone your fork locally::

$ git clone [email protected]:your_name_here/ipyshiny.git
$ git clone [email protected]:your_name_here/shinywidgets.git

3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development::

$ mkvirtualenv ipyshiny
$ cd ipyshiny/
$ mkvirtualenv shinywidgets
$ cd shinywidgets/
$ python setup.py develop

4. Create a branch for local development::
Expand All @@ -79,7 +79,7 @@ Ready to contribute? Here's how to set up `ipyshiny` for local development.
5. When you're done making changes, check that your changes pass flake8 and the
tests, including testing other Python versions with tox::

$ flake8 ipyshiny tests
$ flake8 shinywidgets tests
$ python setup.py test or pytest
$ tox

Expand All @@ -103,15 +103,15 @@ Before you submit a pull request, check that it meets these guidelines:
your new functionality into a function with a docstring, and add the
feature to the list in README.rst.
3. The pull request should work for Python 3.5, 3.6, 3.7 and 3.8, and for PyPy. Check
https://travis-ci.com/rstudio/ipyshiny/pull_requests
https://travis-ci.com/rstudio/shinywidgets/pull_requests
and make sure that the tests pass for all supported Python versions.

Tips
----

To run a subset of tests::

$ pytest tests.test_ipyshiny
$ pytest tests.test_shinywidgets


Deploying
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ include LICENSE
include README.rst

recursive-include tests *
recursive-include ipyshiny/static *
recursive-include shinywidgets/static *
recursive-exclude * __pycache__
recursive-exclude * *.py[co]

Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ clean-test: ## remove test and coverage artifacts
rm -fr .pytest_cache

lint/flake8: ## check style with flake8
flake8 ipyshiny tests
flake8 shinywidgets tests
lint/black: ## check style with black
black --check ipyshiny tests
black --check shinywidgets tests

lint: lint/flake8 lint/black ## check style

Expand All @@ -61,15 +61,15 @@ test-all: ## run tests on every Python version with tox
tox

coverage: ## check code coverage quickly with the default Python
coverage run --source ipyshiny -m pytest
coverage run --source shinywidgets -m pytest
coverage report -m
coverage html
$(BROWSER) htmlcov/index.html

docs: ## generate Sphinx HTML documentation, including API docs
rm -f docs/ipyshiny.rst
rm -f docs/shinywidgets.rst
rm -f docs/modules.rst
sphinx-apidoc -o docs/ ipyshiny
sphinx-apidoc -o docs/ shinywidgets
$(MAKE) -C docs clean
$(MAKE) -C docs html
$(BROWSER) docs/_build/html/index.html
Expand Down
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ipyshiny
shinywidgets
================

Render [ipywidgets](https://ipywidgets.readthedocs.io/en/stable/) inside a
Expand All @@ -7,23 +7,23 @@ Render [ipywidgets](https://ipywidgets.readthedocs.io/en/stable/) inside a
## Installation

```sh
pip install ipyshiny --extra-index-url=https://pyshiny.netlify.app/pypi
pip install shinywidgets --extra-index-url=https://pyshiny.netlify.app/pypi
```

## Overview

Every Shiny app has two main parts: the user interface (UI) and server logic.
`{ipyshiny}` provides `output_widget()` for defining where to place a widget in the UI
`{shinywidgets}` provides `output_widget()` for defining where to place a widget in the UI
and `register_widget()` (or `@render_widget`) for supplying a widget-like object to
the `output_widget()` container. More technically, widget-like means:

* Any object that subclasses `{ipywidgets}`'s `Widget` class.
* Some other widget-like object that can be coerced into a `Widget`. Currently, we
support objects from `{altair}`, `{bokeh}`, and `{pydeck}`, but [please let us
know](https://github.com/rstudio/ipyshiny/issues/new) about other packages that we
know](https://github.com/rstudio/shinywidgets/issues/new) about other packages that we
should support.

The recommended way to incorporate `{ipyshiny}` widgets into Shiny apps is to:
The recommended way to incorporate `{shinywidgets}` widgets into Shiny apps is to:

1. Initialize and `register_widget()` _once_ for each widget.
* In most cases, initialization should happen when the user session starts (i.e.,
Expand All @@ -32,15 +32,15 @@ The recommended way to incorporate `{ipyshiny}` widgets into Shiny apps is to:
until it's needed.
2. Use Shiny's `@reactive.Effect` to reactively modify the widget whenever relevant
reactive values change.
3. Use `{ipyshiny}`'s `reactive_read()` to update other outputs whenever the widget changes.
3. Use `{shinywidgets}`'s `reactive_read()` to update other outputs whenever the widget changes.
* This way, relevant output(s) invalidate (i.e., recalculate) whenever the relevant
widget attributes change (client-side or server-side).

The following app below uses `{ipyleaflet}` to demonstrate all these concepts:

```py
from shiny import *
from ipyshiny import output_widget, register_widget, reactive_read
from shinywidgets import output_widget, register_widget, reactive_read
import ipyleaflet as L

app_ui = ui.page_fluid(
Expand Down Expand Up @@ -88,7 +88,7 @@ a fitted line on a scatterplot with lots of points:

```py
from shiny import *
from ipyshiny import output_widget, register_widget
from shinywidgets import output_widget, register_widget
import plotly.graph_objs as go
import numpy as np
from sklearn.linear_model import LinearRegression
Expand Down Expand Up @@ -152,7 +152,7 @@ be noticeable delay.

```py
from shiny import *
from ipyshiny import output_widget, render_widget
from shinywidgets import output_widget, render_widget
import ipyleaflet as L

app_ui = ui.page_fluid(
Expand Down Expand Up @@ -204,29 +204,29 @@ w.layout.display = "none"
Yes! In fact this a crucial aspect to how packages like `{ipyleaflet}` work. In
`{ipyleaflet}`'s case, each [individual marker is a widget](https://ipyleaflet.readthedocs.io/en/latest/layers/circle_marker.html) which gets attached to a `Map()` via `.add_layer()`.

### Does `{ipyshiny}` work with `shiny static`?
### Does `{shinywidgets}` work with `shiny static`?

Shiny's `shiny static` CLI command allows some Shiny apps to be statically served (i.e.,
run entirely in the browser). [py-shinylive](https://github.com/rstudio/py-shinylive)
(the Python package behind `shiny static`) does have some special support for
`{ipyshiny}` and it's dependencies, which should make most widgets work out-of-the-box.
`{shinywidgets}` and it's dependencies, which should make most widgets work out-of-the-box.

In some cases, the package(s) that you want to use may not come pre-bundled with
`{ipyshiny}`; and in that case, you can [include a `requirements.txt`
`{shinywidgets}`; and in that case, you can [include a `requirements.txt`
file](https://pyshiny.netlify.app/examples/#extra-packages) to pre-install those other
packages

## Troubleshooting

If after [installing](#installation) `{ipyshiny}`, you have trouble rendering widgets,
first try running the "hello world" ipywidgets [example](https://github.com/rstudio/ipyshiny/blob/main/examples/ipywidgets/app.py). If that doesn't work, it could be that you have an unsupported version
If after [installing](#installation) `{shinywidgets}`, you have trouble rendering widgets,
first try running the "hello world" ipywidgets [example](https://github.com/rstudio/shinywidgets/blob/main/examples/ipywidgets/app.py). If that doesn't work, it could be that you have an unsupported version
of a dependency like `{ipywidgets}` or `{shiny}`.

If you can run the "hello world" example, but "3rd party" widget(s) don't work, first
check that the extension is properly configured with `jupyter nbextension list`. Even if
the extension is properly configured, it still may not work right away, especially if
that widget requires initialization code in a notebook environment. In this case,
`{ipyshiny}` probably won't work without providing the equivalent setup information to
`{shinywidgets}` probably won't work without providing the equivalent setup information to
Shiny. Some known cases of this are:

#### bokeh
Expand All @@ -241,11 +241,11 @@ head_content(HTML(Resources(mode="inline").render()))
#### Other widgets?

Know of another widget that requires initialization code? [Please let us know about
it](https://github.com/rstudio/ipyshiny/issues/new)!
it](https://github.com/rstudio/shinywidgets/issues/new)!

## Development

If you want to do development on `{ipyshiny}`, run:
If you want to do development on `{shinywidgets}`, run:

```sh
pip install -e .
Expand Down
2 changes: 1 addition & 1 deletion examples/ipyleaflet/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from shiny import *
from ipyshiny import output_widget, register_widget, reactive_read
from shinywidgets import output_widget, register_widget, reactive_read
import ipyleaflet as L
from htmltools import css

Expand Down
4 changes: 2 additions & 2 deletions examples/ipywidgets/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from shiny import *
from ipyshiny import *
from shinywidgets import *
import ipywidgets as ipy
from ipywidgets.widgets.widget import Widget

Expand Down Expand Up @@ -28,4 +28,4 @@ def _():
return f"The value of the slider is: {reactive_read(s, 'value')}"


app = App(app_ui, server)
app = App(app_ui, server, debug=True)
11 changes: 0 additions & 11 deletions examples/ipywidgets/rsconnect-python/ipywidgets.json

This file was deleted.

2 changes: 1 addition & 1 deletion examples/outputs/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np

from shiny import *
from ipyshiny import *
from shinywidgets import *
from htmltools import head_content, HTML

# TODO: jupyter_bokeh assumes this additional JS has been loaded into the
Expand Down
2 changes: 1 addition & 1 deletion examples/outputs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
--extra-index-url https://pyshiny.netlify.app/pypi/
shiny>=0.2.0.9004
ipyshiny
shinywidgets
ipywidgets
numpy
pandas
Expand Down
2 changes: 1 addition & 1 deletion examples/plotly/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from sklearn.linear_model import LinearRegression

from shiny import *
from ipyshiny import output_widget, register_widget
from shinywidgets import output_widget, register_widget
import plotly.graph_objs as go

# Generate some data and fit a linear regression
Expand Down
2 changes: 1 addition & 1 deletion examples/plotly/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
--extra-index-url https://pyshiny.netlify.app/pypi/
shiny>=0.2.0.9004
ipyshiny
shinywidgets
ipywidgets
numpy
pandas
Expand Down
2 changes: 1 addition & 1 deletion examples/superzip/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from htmltools import head_content
from shiny import *
from shiny.types import SilentException
from ipyshiny import *
from shinywidgets import *
import ipywidgets
import ipyleaflet as leaf
from ipyleaflet import basemaps
Expand Down
2 changes: 1 addition & 1 deletion js/src/comm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class ShinyComm {
header: {}
};
const msg_txt = JSON.stringify(msg);
Shiny.setInputValue("ipyshiny_comm_send", msg_txt, {priority: "event"});
Shiny.setInputValue("shinywidgets_comm_send", msg_txt, {priority: "event"});

// When client-side changes happen to the WidgetModel, this send method
// won't get called for _every_ change (just the first one). The
Expand Down
10 changes: 5 additions & 5 deletions js/src/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class OutputManager extends HTMLManager {
const shinyRequireLoader = async function(moduleName: string, moduleVersion: string): Promise<any> {

// shiny provides require.js and also sets `define.amd=false` to prevent <script>s
// with UMD loaders from triggering anonymous define() errors. ipyshiny should
// with UMD loaders from triggering anonymous define() errors. shinywidgets should
// generally be able to avoid anonymous define errors though since there should only
// be one 'main' anonymous define() for the widget's module (located in a JS file that
// we've already require.config({paths: {...}})ed; and in that case, requirejs adds a
Expand Down Expand Up @@ -103,7 +103,7 @@ class IPyWidgetOutput extends Shiny.OutputBinding {
}
})
});
});
});
}
}

Expand All @@ -115,7 +115,7 @@ Shiny.outputBindings.register(new IPyWidgetOutput(), "shiny.IPyWidgetOutput");

// Initialize the comm and model when a new widget is created
// This is basically our version of https://github.com/jupyterlab/jupyterlab/blob/d33de15/packages/services/src/kernel/default.ts#L1144-L1176
Shiny.addCustomMessageHandler("ipyshiny_comm_open", (msg_txt) => {
Shiny.addCustomMessageHandler("shinywidgets_comm_open", (msg_txt) => {
setBaseURL();
const msg = jsonParse(msg_txt);
Shiny.renderDependencies(msg.content.html_deps);
Expand All @@ -125,7 +125,7 @@ Shiny.addCustomMessageHandler("ipyshiny_comm_open", (msg_txt) => {

// Handle any mutation of the model (e.g., add a marker to a map, without a full redraw)
// Basically out version of https://github.com/jupyterlab/jupyterlab/blob/d33de15/packages/services/src/kernel/default.ts#L1200-L1215
Shiny.addCustomMessageHandler("ipyshiny_comm_msg", (msg_txt) => {
Shiny.addCustomMessageHandler("shinywidgets_comm_msg", (msg_txt) => {
const msg = jsonParse(msg_txt);
manager.get_model(msg.content.comm_id).then(m => {
// @ts-ignore for some reason IClassicComm doesn't have this method, but we do
Expand All @@ -134,7 +134,7 @@ Shiny.addCustomMessageHandler("ipyshiny_comm_msg", (msg_txt) => {
});

// TODO: test that this actually works
Shiny.addCustomMessageHandler("ipyshiny_comm_close", (msg_txt) => {
Shiny.addCustomMessageHandler("shinywidgets_comm_close", (msg_txt) => {
const msg = jsonParse(msg_txt);
manager.get_model(msg.content.comm_id).then(m => {
// @ts-ignore for some reason IClassicComm doesn't have this method, but we do
Expand Down
2 changes: 1 addition & 1 deletion js/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const plugins = [
new FileManagerPlugin({
events: {
onEnd: {
copy: [{ source: outputPath + '/*', destination: '../ipyshiny/static' }]
copy: [{ source: outputPath + '/*', destination: '../shinywidgets/static' }]
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion scripts/static_download.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

static_dir <- file.path(getwd(), "ipyshiny", "static")
static_dir <- file.path(getwd(), "shinywidgets", "static")
if (!dir.exists(static_dir)) dir.create(static_dir)
# From https://github.com/jupyter-widgets/ipywidgets/blob/fbdbd005/python/ipywidgets/ipywidgets/embed.py#L62
# Note that we also grab libembed-amd, not embed-amd, because the Shiny bindings handle the actual rendering aspect
Expand Down
Loading

0 comments on commit c3d8d61

Please sign in to comment.