-
Notifications
You must be signed in to change notification settings - Fork 12
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
Fully embracing Jupyter Widgets / Jupyter comm #144
Comments
@pkerpedjiev what would it take to tell higlass fronted to use a different |
In short, for "local" tilesets, rather than starting a background thread and temporary web-server, we reuse the Jupyter comm for displaying the widget to also send/receive requests for tiles. No more HTTP requests, just custom messages. |
Ideally we could just extend import hglib from "https://esm.sh/[email protected]?deps=react@17,react-dom@17,pixi.js@6";
window.higlassDataFetchersByType = window.higlassDataFetchersByType || {};
/**
* Detects server: 'jupyter', and creates a custom data entry for it.
* @example { server: "jupyter", tilesetUid: "aa" } -> { tilesetUid: "aa", data: { type: "jupyter-<id>", tilesetUid: "aa" } }
*/
function resolveJupyterServer(viewConfig, dataFetcherId) {
let copy = JSON.parse(JSON.stringify(viewConfig));
for (let view of copy.views) {
for (let track of Object.values(view.tracks).flat()) {
if (track?.server === "jupyter") {
delete track.server;
track.data = track.data || {};
track.data.type = dataFetcherId;
track.data.tilesetUid = track.tilesetUid;
}
}
}
return copy;
}
class JupyterDataFetcher {
#model;
constructor(model, dataConfig) {
this.#model = model;
this.dataConfig = dataConfig;
}
async tilesetInfo(cb) {
// get tilesetInfo with this.#model
}
async fetchTilesDebounced(cb, tileIds) {
// get tileData with this.#model
}
}
export default () => {
let id = globalThis.crypto.randomUUID().split("-")[0];
let dataFetcherId = `jupyter-${id}`;
return {
async initialize({ model }) {
window.higlassDataFetchersByType[dataFetcherId] = {
name: dataFetcherId,
dataFetcher: class extends JupyterDataFetcher {
constructor(dataConfig) {
super(model, dataConfig);
}
},
};
},
async render({ model, el }) {
let viewconf = resolveJupyterServer(model.get("_viewconf"), dataFetcherId);
let options = model.get("_options") ?? {};
let api = await hglib.viewer(el, viewconf, options);
},
};
}; then to use on the Python side: hg.track(type="heatmap", server="jupyter", tilesetUid="aaa") We can can just have a global weakmap of created tilesets that the HiGlassWidget can call out to to respond to the font end. |
This seems like it would be quite useful! I like the idea not having to do all of the servir stuff.
If I understand what you're asking, I think you can register a new plugin datafetcher and use |
Yup, exactly! |
There are a lot of issues caused by trying to configure the
servir
component of higlass-python, in particular for remote environments. This stems from diverse requirements for the remote web-server, leading to litany of issues for end users (bad). We are running into the case where special config needs to happen to support this kind of dynamic data fetching, and it's really challenging to support these environments. #142 #140But, Jupyter Widgets exist.
In theory, we could bypass all of this garbage by implementing a client-side data fetcher based on Jupyter comms (i.e., anywidget) in
_widget.js
. This would be able to re-use the Jupyter connection for sending tile data, rather configuring and running a background thread to host data.Comms will be consistent across all notebooks environments, and require no extra configuration by end users. As long as they are able to load the widget, data loading should just work. This also comes at the benefit of being able to drop
servir
as required dependency (andjupyter-server-proxy
). We can also get rid of all the custom server stuff.The text was updated successfully, but these errors were encountered: