-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
RFC: add multimedia I/O mechanism (display, mm_write, and friends); fixes #3817 #3932
Conversation
There is also a This is useful for Pylab/Matlab-like stateful plotting modules in which the a plot is created (e.g. by |
I like the simplicity of this approach. @dcjones - IIRC, you have a |
Let me test my understanding on a concrete example. Now we have two ways of showing profiling data: as text (using Now IIUC I would register my two methods something like this:
Really the last one pops up a GUI, so "image/png" doesn't seem quite correct. How does one distinguish between popping up a Tk GUI vs. base64-encoding at a bytestream to send to IPython? That's the job of |
@timholy, The GUI is "popped up" (if at all) during For a supported MIME type, The key is that we separate multimedia export of Julia types from multimedia display of the exported data. PS. Also, you don't have to define a text/plain |
OK, I think I see now. Let's say a user loads the But let's say instead I'm working from IJulia and then load Alternatively, are you hoping ImageView will integrate more closely with this mechanism? If so, presumably it should push a |
@timholy, what I'm hoping is that ImageView will integrate with this mechanism, by defining a You are free, of course, to define additional Furthermore, the return value of Finally, if you want provide even richer display of a certain Julia type (say you provide interactive editing, not just display, of a The whole point of putting this into Julia Base is that both multimedia export and multimedia backends are basic functionalities that can be provided in lots of ways, by lots of packages — this is not something that can or should be limited to IJulia! |
OK, I think I'm slowly catching on. My current thought is that perhaps Tk and Gtk are perhaps the right places to put the parts dealing with low-level window state management. Anyway, I'm good to merge on this. We'll figure any issues out as they come up. |
Should the mm_write function get a hint about the display size? For non vector images it makes a huge difference, and I think that the display should be able to ask for a specific hight and/or width, even if the mm_write implementation might ignore the hint. Does this interface support display devices might start to show the first frames of an animation before the last framme is generated and mm_write returns? |
@ivarne, with regards to the first question, my inclination is to think of that as a more application-specific thing; e.g. the default height and width you might want for plotting output would be very different from the default height and width for emoticon output, and since the display knows nothing about the source of the data it doesn't seem like the best place to put that information. With regards to the second question, it should be perfectly possible in Julia for the display to read and display the output of |
For asynchronous I/O all that's needed is some kind of IO object that can handle the data and block the writing task when appropriate. |
Note that the IPython protocol does incorporate a metadata field that can be used to pass arbitrary data along with the MIME data, and their metadata field is used to pass image-size hints (see ipython/ipython#3190), but it is used in the opposite direction, as I understand it (the data source sends the full image but sometimes hints that it should be shown as a different size, e.g. a thumbnail). However, even though they support arbitrary metadata, these thumbnailing hints are still essentially the only thing their metadata is used for. It seemed to me that this was a problematic design, and in any case there should probably be a more global way to indicate thumbnailing preferences for large images. |
Maybe it should be called |
+1 for writemime. |
Okay, so mm_write, mm_repr, mm_string_repr, and mm_writable become (I agree that "mime" is more readable, although it may be technically incorrect. We are using MIME types (or rather, "Internet media types"), but we are not writing MIME email attachments. I don't really care if you don't, though.) |
Okay, renamed, and also renamed {push/pop}_display to {push/pop}display |
Okay to merge? |
Fine with me |
@JeffBezanson and I have both been away over the weekend and are still catching up, could you wait a bit so we can review and comment. Sorry for the delay! |
@StefanKarpinski, no problem. |
Hi, Sorry I'm not a julia expert and I have a few questions. I didn't totally got how is the richest representation decided in display. Back to The In this case (only the first) how will this apply when multiple frontend with different display capability are hooked to the same kernel ?
The metadata will mainly be use for javascript plugin to receive extra information about the mimetype they are supposed to handle. Right now the only javascript widget we have is the one that deal with image and resize, and so get only width and height metadatafield, but if the image was read from disk you could send along permission, last modified, size on disk... on my case I have some biological images I can send a scale with it. Brian did some D3js network graph animation using json representation and some 3d vtk in browser, obviously you want to send the pure data representing to the javascript, but all the unrelevant-meta-information that might be plugin specific like the speed of animation or the original orientation of the 3D model have their place in metadata. The point is that as data are stored in notebook format, they should be handler independent, hence the optional metadata field. Hope this clarify what I understood of how metadata will be used, and not only for thumbnailing. |
@Carreau, whichever frontend that is called has access to all of the available representations; it can call as many I don't understand why a separate metadata field is needed for the uses you mentioned, as opposed to embedding the metadata in the Javascript or elsewhere in the HTML DOM (with Javascript embedded via |
Ok, I'm starting to get it. I still have difficulties to separate the julia from the IJulia layer, but it makes sens.
This is because we try as much as possible to avoid making assumption that the frontend will be javascript/html. For example Emacs-IPython-Notebook speek with the server through websocket, also have a dispatch on mime-type it might interpreat the size attribute of the metadata to scale image (maybe it does, or not, I have no clues), but still it needs to be able to store it as JSON, as the Another type of "frontend" is be nbconvert. It actually read the json file, which include mimetype/data/metadata and use it to build a converted document like PDF, where there is no DOM. Metadata can be use to scale image, or assign a We could have send everything in the following form
But this would have involve significant refactor on one side, also, json does not support binary data which should allow to keep the content binary as long as possible. You could, in some ways, see metadata of as exif, but for all mime-types, even thoses that don't support it. |
I'm still confused about the justification for your metadata:
|
Ok, let's step back I think we probably miss understand each other. right now we have (form [here]):
You would like something more like
Where
Yes, in this should mostly be true in any metada. Nobody should expect metadata to be there, they might not be.
That would be creating yet another mimetype for each existing mimetype. For me, the data of the mimetype should be untouched as many library already now how to process those file. Moreover, embedding the metadata into the data themselve would require to write a extractor for those metadata for each mimetype. Consider also the fact that each embeded data could be extracted from the ipynb file. What assure you that the clever embeding you did in some mimetype will not choke another software ? Sure it might work in html or javascript as you know the comments, but what about |
No. I just want you to deprecate the If a particular application needs to embed some additional meta-information in an application-specific way, that will be read and used by an application-specific front-end, it can do that by embedding it within the existing data as I suggested.
No it wouldn't, because my suggestions (comments in Javascript source or EXIF-like tags in images) utilize existing metadata mechanisms in those formats that would simply be ignored by front-ends that don't know to look for the application-specific metadata. (Alternatively, in a binary format with predictable/detectable length but no designated metadata fields, you could just append application-specific binary metadata beyond the end of the MIME binary data, which would be ignored by readers that didn't know to look for it. But most formats these days already have ways to embed arbitrary metadata within them.) Yes, it would be hard to embed metadata in |
I like it. |
@JeffBezanson, fixed the exports & flushing. I'm actually not sure in retrospect why I bothered flushing, or why I ignored errors from the |
…th a Base64Pipe <: IO type
Not sure I understand the Travis failure; at first glance, it has nothing to do with this patch... |
I'm ready to merge this. @StefanKarpinski ? |
@stevengj We've got a couple bugs that are floating around, some of which seem to only manifest on Travis builds, others which intermittently show up on our machines as well. In general, if only one of the builds fail (e.g. I've restarted the Travis build, it should show up green if we're lucky. (How I hate intermittent failures) |
RFC: add multimedia I/O mechanism (display, mm_write, and friends); fixes #3817
This patch addresses #3817 to provide a general mechanism in Julia to display objects via rich multimedia representations, via three components:
display(x)
to request the richest available multimedia display of a Julia objectx
(with a text/plain fallback).writemime
allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types.Display
type and pushing them onto a stack of display backends viapushdisplay
.This design has gone through several iterations since the inception of #3817, and is in part inspired by the design of IPython's custom display logic. It is especially critical for the development of IJulia, where I have tested this technique and found that it works very well.
The main difference from my most recent proposal in #3817 is that I generalized the mechanism to be extensible to arbitrary MIME types without modifying
Base
, using a parametric singleton-type technique similar to @StefanKarpinski's beautifulMathConst
trick in order to allow Julia to dispatch on the MIME type. For example, if I have a typeMyImage
that I know how to write as PNG, I can simply define a newwritemime
method:and any
MyImage
object will automatically display as a PNG image in IJulia or in any other display device supporting image/png.See the changes to
doc/stdlib/base.rst
for the complete documentation.I also added and documented a
base64(x)
function to base64-encode binary data, as this is generically useful for sending MIME data to backends over string-based transport protocols (and is essential for IJulia), based on some code by @StefanKarpinski.cc: @JeffBezanson, @viralshah, @timholy, @fperez, @loladiro