Skip to content

Commit

Permalink
Fix cirq_web README from large Typescript development PR merge (quant…
Browse files Browse the repository at this point in the history
…umlib#4314)

Changed how widgets should be structured in Python right before merging and forgot to update the documentation. This fixes the documentation on that.
  • Loading branch information
seunomonije authored and erichulburd committed Jul 15, 2021
1 parent d956942 commit 661c7fa
Showing 1 changed file with 36 additions and 37 deletions.
73 changes: 36 additions & 37 deletions cirq-web/cirq_web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The `cirq_web` package runs separately from the rest of Cirq, and can be used on
A reference for the build structure of a module is the Bloch sphere. Reference the `bloch_sphere/` directory to see the code. Modules should:
- Abide by Cirq convention in terms of testing, styling, and initialization files.
- Contain a "root" folder labeled according to the title of the module. In the case of the Bloch sphere, this is `bloch_sphere/`.
- Contain a main class that contains the code for the visualization. All supporting files should be imported into this class. In the case of the Bloch sphere, this is `cirq_bloch_sphere.py`.
- Contain a main class that contains the code for the visualization. All supporting files should be imported into this class. In the case of the Bloch sphere, this is `bloch_sphere.py`.
- Make sure that any additional modules and files are in separate subdirectories labeled accordingly.

### Developing Python modules for visualization
Expand All @@ -21,60 +21,59 @@ The main class for all visualizations should inherit from the `Widget` class loc
class MyWidget(widget.Widget):
def __init__(self,...):
...
super().__init__('cirq_ts/dist/YOUR_BUNDLE_FILE.js')
super().__init__()
...
```
This will allow you to easily access the absolute path to your bundle file, which should always be used when referencing it, with `self.bundle_file_path`. It also allows you to call `super().get_bundle_script()` to easily
get full script content of your widget as a string. These methods should be used when generating your HTML outputs for boththe web browser and notebooks.
This ensures that your widget has the standard functionality of all Cirq visualization widgets, including:
- A unique id for each instance of your visualization.
- Magic method so that your visualization can be displayed in a Colab/Jupyter notebook.
- The ability to generate a standalone HTML file with your visualization.

The `widget.py` file also contains methods like `write_output_file()` that should be used for all visualizations, as well as some other helpful methods.
`Widget` is an abstract class with methods `get_client_code()` and `get_widget_bundle_name()` that need to be implemented in your visualization as well. Failure to implement these will lead to a `NotImplementedError` at runtime. Instructions on how to properly implement these methods are in the next section.

### Handling HTML output from Python
#### Viewing a visualization in a notebook setting
We capitalize on IPython's `_repr_html_` magic method to help display visualizations in the notebook. In the main class of your visualization, include a method like so:

In your individual visualizations class, you only need to handle two things:
1. The client code that's unique to your visualization.
2. The name of the bundle file.

```python
from cirq_web import widget

class MyWidget(widget.Widget):
...
def _repr_html_(self):
bundle_script = super().get_bundle_script()
def get_client_code(self) -> str:
return f"""
<meta charset="UTF-8">
<div id="container"></div>
{bundle_script}
<script>YOUR_BUNDLE_FUNCTION<script>
<script>
YOUR_CLIENT_CODE
</script>
"""
```
This will allow your visualization to be displayed in a notebook cell with:

def get_widget_bundle_name(self) -> str:
return 'YOUR_BUNDLE_FILE.bundle.js'
```

`Widget` will take this information and organize it so that it can be properly displayed.

#### Viewing a visualization in a notebook setting
We capitalize on IPython's `_repr_html_` magic method to help display visualizations in the notebook. This will allow your visualization to be displayed in a notebook cell with:
```python
widget = MyWidget()
display(widget)
```

#### Generating a standalone HTML file from a visualization
Generating a standalone HTML file is a bit more involved than in a notebook, but not difficult. In the main class of your visualiztion, include a method like so:
You can generate a standalone HTML file of your visualization like so:
```python
import webbrowser
from cirq_web import widget
class MyWidget(widget.Widget):
...
def generate_html_file(self, output_directory='./', file_name="YOUR_VIZ.html", open_in_browser=False):
bundle_script = super().get_bundle_script()
contents = f"""
<meta charset="UTF-8">
<div id="container"></div>
{bundle_script}
<script>YOUR_BUNDLE_FUNCTION<script>
"""
path_of_html_file = widget.write_output_file(output_directory, file_name, contents)

if open_in_browser:
webbrowser.open(str(path_of_html_file), new=2)

return path_of_html_file
```
This code above writes a file named `YOUR_VIZ.html` to the specified output directory, returning the path of the file as a `Path` object. To get the path as string, use `str()`. If the `open_in_browser` flag is used, Python will automatically open your visualization in a new tab using the default browser on your computer.
widget = MyWidget()

The important thing about generating standalone HTML files is that they can be sent and viewed anywhere, regardless of if the recipient has Cirq installed on their computer or not.
output_directory = './'
file_name = 'YOUR_VIZ.html'
open_in_browser = False

widget.generate_html_file(output_directory, file_name, open_in_browser)
```

This code above writes a file named `YOUR_VIZ.html` to the specified output directory, returning the path of the file as a string. If the `open_in_browser` flag is used, Python will automatically open your visualization in a new tab using the default browser on your computer.

The important thing about generating standalone HTML files is that they can be sent and viewed anywhere, regardless of whether the recipient has Cirq installed on their computer or not.

0 comments on commit 661c7fa

Please sign in to comment.