Sei que isso está fora do escopo da maioria das comunidades, mas somos uma comunidade científica, usando Python e muitos gráficos (Matplotlib) que compartilhamos uns com os outros no Discourse.
Seria incrível poder compartilhar um gráfico interativo em vez de um jpg/png estático
Considere este exemplo:
import matplotlib.pyplot as plt
import mpld3
import numpy as np
Fs = 4000
f = 100
sample = 200
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
fig, ax = plt.subplots(1,1)
ax.plot(x, y, marker=".")
html_str = mpld3.fig_to_html(fig)
Html_file= open("index.html","w")
Html_file.write(html_str)
Html_file.close()
Você seria capaz de abrir o arquivo index.html e ele mostrará isso (apenas que será INTERATIVO…)
O método que você descreveu seria possível através de um plugin personalizado, combinando um plugin no estilo markdown-it e possivelmente um bom armazenamento de objetos para os HTMLs. No entanto, eu teria cautela quanto à segurança disso, permitindo que código inserido pelo usuário seja executado em qualquer lugar do servidor. O Discourse já faz muito trabalho apenas para higienizar uma postagem para que HTML e JS sejam analisados com segurança no backend.
Você pode ter mais sorte tentando incorporar um interpretador Python no navegador e deixá-lo executar o código no cliente, pulando toda a criação de HTML. O JupyterLite permitiria que você executasse o JupyterLab no navegador com interface de usuário. Pela documentação, parece que você pode ter ele para executar código automaticamente na criação do iframe. Você pode fornecer o código com um plugin HighlightJS personalizado que criará um botão acionável em qualquer bloco de código Python, ou fazê-lo executar automaticamente.
Então, algo como:
O usuário vê uma postagem com um bloco de código Python.
O usuário passa o mouse sobre o bloco de código, onde um botão aparece para permitir que ele execute o código no navegador.
O usuário clica no botão, que cria um iframe para o JupyterLite abaixo do código, importando o código do bloco de código.
Como isso seria apenas um plugin HighlightJS que cria um iframe para o JupyterLite, você pode criar tudo dentro de um Componente de Tema, sem necessidade de código de servidor.
Uma coisa a notar: o JupyterLite é descrito como não sendo completo em recursos em comparação com o JupyterLab, e não tenho certeza de como ele lida com importações de pacotes, então você pode ter que hospedá-lo você mesmo. O JupyterLite usa Pyodide, que suporta qualquer roda no PyPI, então deve ser bom.
Acho que o risco de segurança não é tão grande caso o index.html seja executado no lado do cliente (no navegador do usuário, não no servidor Discourse).
Além disso, a vantagem na abordagem mpld3 é que é um arquivo único sem dependências. Se você executar Python puro, também terá que ser capaz de carregar todas as dependências, como arquivos CSV, arquivos de dados, etc., que são a origem do que você deseja plotar.
Dito isso, poder executar scripts Python puros dentro de uma postagem do Discourse seria fabuloso!
Oh! Eu entendi completamente errado como o HTML seria gerado. Se o usuário estiver pré-gerando o HTML, você poderia fazê-lo em iframe de um site externo, com o domínio na lista de permissões.
Por exemplo, codepen, que deve ser permitido por padrão:
<iframe height="300" width="800" style="width: 100%;" scrolling="no" title="mplD3 example, actually working" src="https://codepen.io/gully/embed/BawMGr?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/gully/pen/BawMGr">
mplD3 example, actually working</a> by gully (<a href="https://codepen.io/gully">@gully</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
<iframe height="300" width="800" style="width: 100%;" scrolling="no" title="mplD3 example, actually working" src="https://codepen.io/gully/embed/BawMGr?default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/gully/pen/BawMGr">
mplD3 example, actually working</a> by gully (<a href="https://codepen.io/gully">@gully</a>)
on <a href="https://codepen.io">CodePen</a>.
</iframe>
Isso é realmente incrível!
Tenho algumas perguntas:
Você acha que funcionará com o ipympl (caso contrário, as figuras não são interativas, o que invalida todo o propósito)?
Você acha que pode funcionar com uma pasta de projeto subjacente onde podemos definir a variável de ambiente PYTHONPATH antes de iniciar o Jupyter para que os usuários possam importar funções e dependências do projeto conjunto?
E sim, eu tenho um orçamento se isso for razoável e viável e puder ser contribuído como código aberto para toda a comunidade Discourse.
@Alteras Obrigado, esta solução é realmente simples e funciona se você puder encontrar uma maneira de fazer o upload do arquivo “index.heml” para o Discourse (o que é fácil de habilitar o upload de .html) e servi-lo no código do iframe. O único problema é que não está funcionando… quando tento isso, ele apenas baixa o index.html em vez de renderizá-lo no iframe. Talvez haja uma meta tag para dizer ao iframe para mostrar o arquivo em vez de baixá-lo?
Ahh, entendi. O Discourse, por padrão, define qualquer anexo que não seja imagem com o Content-Disposition como “attachment”, o que o tratará apenas como um download.
Você pode ser capaz de fazer algo semelhante às Pré-visualizações de PDF Inline, que parece lidar com o mesmo problema, mas para uploads de PDF.