Sé que esto está fuera del alcance de la mayoría de las comunidades, pero somos una comunidad científica, usamos Python y muchos gráficos (Matplotlib) que compartimos entre nosotros a través de Discourse.
Sería increíble poder compartir un gráfico interactivo en lugar de un jpg/png estático.
Considere este ejemplo:
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()
Podrías abrir el archivo index.html y mostrará eso (solo que será INTERACTIVO…)
El método que describiste sería posible a través de un plugin personalizado, combinando un plugin estilo markdown-it y posiblemente un buen almacenamiento de objetos para los HTML. Sin embargo, sería cauteloso con la seguridad de permitir que el código ingresado por el usuario se ejecute en cualquier lugar del servidor. Discourse ya hace mucho trabajo solo para sanitizar una publicación para que el HTML y el JS se analicen de forma segura en el backend.
Podrías tener más suerte intentando incrustar un intérprete de Python en el navegador y dejar que ejecute el código en el cliente, omitiendo toda la creación de HTML. JupyterLite te permitiría ejecutar JupyterLab en el navegador con interfaz de usuario. De la documentación, parece que puedes hacer que ejecute código automáticamente al crear el iframe. Puedes alimentar el código con un plugin personalizado de HighlightJS que creará un botón accionable en cualquier bloque de código Python, o hacer que se ejecute automáticamente.
Así que algo como:
El usuario ve una publicación con un bloque de código Python.
El usuario pasa el cursor sobre el bloque de código, donde aparece un botón para ejecutar el código en el navegador.
El usuario hace clic en el botón, lo que crea un iframe a JupyterLite debajo del código, importando el código del bloque de código.
Dado que esto sería solo un plugin de HighlightJS que crea un iframe a JupyterLite, puedes crearlo todo dentro de un Componente de Tema, sin necesidad de código de servidor.
Una cosa a tener en cuenta: JupyterLite se describe como no completo en características respecto a JupyterLab, y no estoy seguro de cómo maneja las importaciones de paquetes, por lo que podrías tener que alojarlo tú mismo. JupyterLite utiliza Pyodide, que admite cualquier wheel en PyPI, por lo que debería estar bien.
Creo que el riesgo de seguridad no es tan grande si index.html se ejecuta en el lado del cliente (en el navegador del usuario, no en el servidor de Discourse).
Además, la ventaja del enfoque mpld3 es que es un archivo único sin dependencias. Si ejecutas Python puro, también tienes que poder cargar todas las dependencias como archivos CSV, archivos de datos, etc., que son la fuente de lo que quieres graficar.
Dicho esto, ¡poder ejecutar scripts de Python puros dentro de una publicación de Discourse sería fabuloso!
¡Oh! Entendí completamente mal cómo se generaría el HTML. Si el usuario está pregenerando el HTML, podrías hacer que lo incluyan desde un sitio externo, con el dominio en la lista blanca.
Por ejemplo, codepen, que debería permitirse por defecto:
<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>
¡Eso es realmente genial!
Tengo un par de preguntas:
¿Crees que funcionará con ipympl (de lo contrario, las figuras no son interactivas, lo que invalida todo el propósito)?
¿Crees que puede funcionar con una carpeta de proyecto subyacente donde podamos establecer la variable de entorno PYTHONPATH antes de iniciar Jupyter para que los usuarios puedan importar funciones y dependencias del proyecto conjunto?
Y sí, tengo presupuesto si esto es razonable y factible y puede contribuir como código abierto para toda la comunidad de Discourse.
@Alteras Gracias, esta solución es realmente sencilla y funciona si puedes encontrar una manera de subir el archivo “index.heml” a Discourse (que es fácil de habilitar para la carga de .html) y servirlo en el código iframe. El único problema es que en realidad no funciona… cuando lo intento, simplemente descarga el index.html en lugar de renderizarlo en el iframe. ¿Quizás hay una etiqueta meta para decirle al iframe que muestre el archivo en lugar de descargarlo?
Ahh, ya veo. Discourse, por defecto, establece cualquier archivo adjunto que no sea una imagen con Content-Disposition como “attachment”, lo que lo tratará solo como una descarga.
Es posible que puedas hacer algo similar a las previsualizaciones de PDF en línea, que parece manejar este mismo problema, pero para las cargas de PDF.