Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support more IPython.display output (like JSON) #10938

Open
multimeric opened this issue Oct 1, 2024 · 14 comments
Open

Support more IPython.display output (like JSON) #10938

multimeric opened this issue Oct 1, 2024 · 14 comments
Labels
enhancement New feature or request jupyter
Milestone

Comments

@multimeric
Copy link

Bug description

No response

Steps to reproduce

---
engine: jupyter
---

```{python}
from IPython.display import Markdown, display, JSON

display(JSON({
  "first_name": "John",
  "last_name": "Smith",
  "is_alive": True,
  "age": 27,
  "address": {
    "street_address": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postal_code": "10021-3100"
  },
  "phone_numbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
  ],
  "children": [
    "Catherine",
    "Thomas",
    "Trevor"
  ],
  "spouse": None
}, expanded = False))
```

Expected behavior

JSON() should result in an interactive JSON widget

Actual behavior

Prints:

<IPython.core.display.JSON object>

Your environment

No response

Quarto check output

Quarto 1.4.554
[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.1.11: OK
      Dart Sass version 1.69.5: OK
      Deno version 1.37.2: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
      Version: 1.4.554
      Path: /Users/milton.m/Applications/quarto/bin

[✓] Checking tools....................OK
      TinyTeX: v2023.09
      Chromium: (not installed)

[✓] Checking LaTeX....................OK
      Using: TinyTex
      Path: /Users/milton.m/Library/TinyTeX/bin/universal-darwin
      Version: 2023

[✓] Checking basic markdown render....OK

[✓] Checking Python 3 installation....OK
      Version: 3.9.16 (Conda)
      Path: /opt/anaconda3/bin/python
      Jupyter: 4.11.1
      Kernels: bash, python3

[✓] Checking Jupyter engine render....OK

[✓] Checking R installation...........OK
      Version: 4.4.1
      Path: /opt/homebrew/Cellar/r/4.4.1/lib/R
      LibPaths:
        - /opt/homebrew/lib/R/4.4/site-library
        - /opt/homebrew/Cellar/r/4.4.1/lib/R/library
      knitr: 1.48
      rmarkdown: 2.28

[✓] Checking Knitr engine render......OK
@multimeric multimeric added the bug Something isn't working label Oct 1, 2024
@mcanouil
Copy link
Collaborator

mcanouil commented Oct 1, 2024

Could you upgrade to the latest stable version of Quarto (or possibly the latest pre-release)?
And more generally, ensure your libraries are up to date.

@multimeric
Copy link
Author

Sure. I updated everything and the issue remains:

Quarto 1.5.57
[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.2.0: OK
      Dart Sass version 1.70.0: OK
      Deno version 1.41.0: OK
      Typst version 0.11.0: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
      Version: 1.5.57
      Path: /Users/milton.m/Applications/quarto/bin

[✓] Checking tools....................OK
      TinyTeX: v2023.09
      Chromium: (not installed)

[✓] Checking LaTeX....................OK
      Using: TinyTex
      Path: /Users/milton.m/Library/TinyTeX/bin/universal-darwin
      Version: 2023

[✓] Checking basic markdown render....OK

[✓] Checking Python 3 installation....OK
      Version: 3.12.5
      Path: /private/var/folders/q5/fvpyppm924525yl9m3xpgjm400031g/T/tmp.5ztZLMyyQn/venv/bin/python3
      Jupyter: 5.7.2
      Kernels: python3, bash

[✓] Checking Jupyter engine render....OK

[✓] Checking R installation...........OK
      Version: 4.4.1
      Path: /opt/homebrew/Cellar/r/4.4.1/lib/R
      LibPaths:
        - /opt/homebrew/lib/R/4.4/site-library
        - /opt/homebrew/Cellar/r/4.4.1/lib/R/library
      knitr: 1.48
      rmarkdown: 2.28

[✓] Checking Knitr engine render......OK

@cderv
Copy link
Collaborator

cderv commented Oct 1, 2024

Thanks for the report.

JSON() should result in an interactive JSON widget

To illustrate this, this is what we can see in Jupyter Lab
Arc_aRgqtIzSbS

And in Jupyter notebook, it seems we get the same
image

despite an issue on this reported upstream

Inside VSCODE, with Jupyter support, it does not seem to be supported either but at least it is seen as a JSON string
image

Rendering this .ipynb file with computed results gets us
image

So Quarto, through nbconvert, does not know yet how to handle this IPython.display.JSON. We would need to come up with a specific support.

This is a feature request IMO that we need to investigate to decide what could be done. We could at least print as a JSON string (minify or prettify)

@cderv cderv added enhancement New feature or request jupyter and removed bug Something isn't working labels Oct 1, 2024
@cderv cderv added this to the Future milestone Oct 1, 2024
@cderv
Copy link
Collaborator

cderv commented Oct 1, 2024

I believe the rendering is done through the JSON extension made available in Jupyter Lab
This extension:

Maybe this can be leveraged in quarto 🤔

@multimeric
Copy link
Author

I just realised this extends more generally to all IPython.display objects. I tried returning Markdown and Code, but both just got converted to a plain string without formatting, and printed inside the usual result block. The only escape hatch for advanced formatting seems to be building the markdown yourself, and then printing it with output: asis, as explained here.

@cderv
Copy link
Collaborator

cderv commented Oct 22, 2024

I tried returning Markdown and Code

Can you provide example ? We should support at last Markdown display - this is a way to output Raw content as shown in the page you linked.

---
title: Test
format: html
---

```{python}
#| echo: false
radius = 10
from IPython.display import Markdown
Markdown(f"The _radius_ of the circle is **{radius}**.")
```

It correctly outputs a Markdown string as raw markdown, to be parsed and formatted correctly with italic and bold.
Image

For other display, we probably need to see what we can do to better handling them without 'asis'

@multimeric
Copy link
Author

Sorry, you're completely right. Markdown does work and I must have been doing something wrong yesterday when I tested it.

Here's an example of Code:

---
title: Test
format: html
---

```{python}
#| echo: false
from IPython.display import Code
Code("""
x = 3
y = 'bar'
""", language="python")
```

Which results in this unhighlighted code block:
Image

@mcanouil
Copy link
Collaborator

mcanouil commented Oct 23, 2024

Why would you assume the output would be highlighted?
No language is specified, no no highlighting can be done by Pandoc/Skylighting.

@multimeric
Copy link
Author

I'm using language="python".

@mcanouil
Copy link
Collaborator

Use keep-md: true to see what is produced.
It might not be what you expect or what Quarto/Pandoc expects or another Quarto bug.

FYI:

@multimeric
Copy link
Author

This is the intermediate markdown. Not really sure what to make of it. It seems to be lexing correctly?

---
title: Test
format: html
keep-md: true
---


::: {#24a05b57 .cell execution_count=1}

::: {.cell-output .cell-output-display execution_count=1}

```{=html}
<style>pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.output_html .hll { background-color: #ffffcc }
.output_html { background: #f8f8f8; }
.output_html .c { color: #3D7B7B; font-style: italic } /* Comment */
.output_html .err { border: 1px solid #FF0000 } /* Error */
.output_html .k { color: #008000; font-weight: bold } /* Keyword */
.output_html .o { color: #666666 } /* Operator */
.output_html .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.output_html .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.output_html .cp { color: #9C6500 } /* Comment.Preproc */
.output_html .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.output_html .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.output_html .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.output_html .gd { color: #A00000 } /* Generic.Deleted */
.output_html .ge { font-style: italic } /* Generic.Emph */
.output_html .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.output_html .gr { color: #E40000 } /* Generic.Error */
.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.output_html .gi { color: #008400 } /* Generic.Inserted */
.output_html .go { color: #717171 } /* Generic.Output */
.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.output_html .gs { font-weight: bold } /* Generic.Strong */
.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.output_html .gt { color: #0044DD } /* Generic.Traceback */
.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.output_html .kp { color: #008000 } /* Keyword.Pseudo */
.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.output_html .kt { color: #B00040 } /* Keyword.Type */
.output_html .m { color: #666666 } /* Literal.Number */
.output_html .s { color: #BA2121 } /* Literal.String */
.output_html .na { color: #687822 } /* Name.Attribute */
.output_html .nb { color: #008000 } /* Name.Builtin */
.output_html .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.output_html .no { color: #880000 } /* Name.Constant */
.output_html .nd { color: #AA22FF } /* Name.Decorator */
.output_html .ni { color: #717171; font-weight: bold } /* Name.Entity */
.output_html .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.output_html .nf { color: #0000FF } /* Name.Function */
.output_html .nl { color: #767600 } /* Name.Label */
.output_html .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */
.output_html .nv { color: #19177C } /* Name.Variable */
.output_html .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.output_html .w { color: #bbbbbb } /* Text.Whitespace */
.output_html .mb { color: #666666 } /* Literal.Number.Bin */
.output_html .mf { color: #666666 } /* Literal.Number.Float */
.output_html .mh { color: #666666 } /* Literal.Number.Hex */
.output_html .mi { color: #666666 } /* Literal.Number.Integer */
.output_html .mo { color: #666666 } /* Literal.Number.Oct */
.output_html .sa { color: #BA2121 } /* Literal.String.Affix */
.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */
.output_html .sc { color: #BA2121 } /* Literal.String.Char */
.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */
.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.output_html .s2 { color: #BA2121 } /* Literal.String.Double */
.output_html .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */
.output_html .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.output_html .sx { color: #008000 } /* Literal.String.Other */
.output_html .sr { color: #A45A77 } /* Literal.String.Regex */
.output_html .s1 { color: #BA2121 } /* Literal.String.Single */
.output_html .ss { color: #19177C } /* Literal.String.Symbol */
.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */
.output_html .fm { color: #0000FF } /* Name.Function.Magic */
.output_html .vc { color: #19177C } /* Name.Variable.Class */
.output_html .vg { color: #19177C } /* Name.Variable.Global */
.output_html .vi { color: #19177C } /* Name.Variable.Instance */
.output_html .vm { color: #19177C } /* Name.Variable.Magic */
.output_html .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">y</span> <span class="o">=</span> <span class="s1">&#39;bar&#39;</span>
</pre></div>
```

:::
:::

@cderv
Copy link
Collaborator

cderv commented Oct 23, 2024

Here's an example of Code

As I said, we don't have specific support for Code output from Jupyter. After computation steps, all content will be processed by Quarto through Pandoc, with all the different feature we support.

Highlighting of code source output goes through a specific Markdown syntax, that will be converted to the right output syntax based on to format.

Right now, Code will produce as output some raw HTML with inline style. But this HTML is not the same as the other code block that are produced through Quarto rendering. They don't have the right highlighting classes, and won't benefit from the global styling. I see it does get inline style produced, though there is a high chance that this conflicts with the global styling for HTML format. Although from what I see, the inline style assume .output_html class, but it is not set on the <pre>. So I think it won't apply.

As the docs for Ipython.Display for Code() says (https://ipython.readthedocs.io/en/8.16.0/api/generated/IPython.display.html#IPython.display.Code), it uses Pygments for syntax Highlighting, and Quarto does not use that.

So you can either opt-out all Quarto highlighting and theme, and try to make a custom format using Pygments. Or you need to adapt your output to how quarto works. If you want to produce highlighted source from Jupyter cells for Quarto, just write some raw Markdown.

---
title: Test
format: html
keep-md: true
---

```{python}
#| echo: false
from IPython.display import Markdown
Markdown(r"""
```{.python}
x = 3
y = 'bar'
```""")
```

Image

I hope this clarifies.

@multimeric
Copy link
Author

Yes I understand that this isn't implemented, I guess I would like this to be treated as a feature request to implement some of these display classes? Happy to move it to a discussion if that is preferable.

It's helpful to know that both JSON and Code can be hacked around using Markdown and then adding the appropriate language tag.

@cderv
Copy link
Collaborator

cderv commented Oct 24, 2024

I guess I would like this to be treated as a feature request to implement some of these display classes

Yes I think it makes sense to support better some of the display class. However, I don't think we could support all - Code for example won't be possible to support unless Pygments highlighter can be made compatible somehow with what Quarto uses. I think this is not the case, and specific extensions could probably be made for this.

Or maybe this is just a matter of adaptation in the style to be sure that all inline styling set by Pygments works - anyhow, this is a specific issue.

I'll rename this issue to encompass more display support

@cderv cderv changed the title IPython.display.JSON doesn't render Support more IPython.display output (like JSON) Oct 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request jupyter
Projects
None yet
Development

No branches or pull requests

3 participants