Open aculich opened 2 years ago
@aculich Thanks for raising this request. It comes at the right time as we are also working on creating branding collaterals for Datahub which includes a logo. I will scope this request for discussion during the March sprint and hope that your request is not a time-sensitive one. Let us know!
Not time-sensitive at the moment, but a nice-to-have especially if we start using it more heavily in the future.
@yuvipanda nudge to add your suggestions from the sprint planning meeting!
@aculich the homepage (pre-login) is easily customizable by forking https://github.com/berkeley-dsep-infra/datahub-homepage, which has all the HTML, CSS and images for https://datahub.berkeley.edu. If you can do that, we can then use the same image on the top left. How does that sound?
I added dlab-logo-with-url.svg to: https://github.com/berkeley-dsep-infra/datahub-homepage/tree/master/extra-assets/images
Looks like I had commit access (which I didn't realize) so I ended up uploading it directly instead of in a fork (oops, sorry if that's bad?!)
From here, how do I get the dlab deployment to use this custom image?
@aculich Did you have any luck with adding Dlab's logo in the deployment? I am also currently in the process of figuring out the steps to add the latest logo for Datahub (Check here)
@yuvipanda @ryanlovett Can you please share the detailed steps to change the logo for a particular hub deployment! It will be helpful to keep this GitHub issue as a source of truth for any such requests in the future. Thanks!
@yuvipanda @felder re: disambiguating hubs, custom logos, etc.
@balajialg looking through the info there, I have had some limited success.
On a local branch I modified https://github.com/berkeley-dsep-infra/datahub/blob/staging/deployments/datahub/config/common.yaml and added the following directive to hub: -> extraConfig: underneath the custom theme.
extraConfig:
04-custom-theme: |
c.JupyterHub.template_paths = ['/usr/local/share/jupyterhub/custom_templates/']
Change starts here:
logoConfig: |
import urllib.request
urllib.request.urlretrieve("https://www.isabellacounty.org/wp-content/uploads/2022/04/computer.jpg", "mylogo.png")
c.JupyterHub.logo_file = '/srv/jupyterhub/mylogo.png'
I then used hubploy to push that change to staging. It seems to work, is currently live on datahub staging, and will be until someone sends something else to staging. Check it out if you get a chance.
However, this is not ideal since the image is being pulled from an external source. I believe what we could do here is modify our hub image here:
https://github.com/berkeley-dsep-infra/datahub/blob/staging/images/hub/Dockerfile
To include all of the custom logo images and then modify the configs for each hub to use the appropriate custom logo as indicated in the logoConfig block above.
Ok this closed PR (I did not want to merge this) shows what needs to occur:
https://github.com/berkeley-dsep-infra/datahub/pull/3500/files
Of particular interest is this configuration that tells the hub to use the custom logo: https://github.com/berkeley-dsep-infra/datahub/blob/c3366a39ff828b24636349c2d6d67ffd4c5363b2/deployments/datahub/config/common.yaml#L84
Where the Dockerfile for the hub pod is modified to have the custom logo: https://github.com/berkeley-dsep-infra/datahub/blob/c3366a39ff828b24636349c2d6d67ffd4c5363b2/images/hub/Dockerfile#L10
The addition of the custom logo itself: https://github.com/berkeley-dsep-infra/datahub/blob/c3366a39ff828b24636349c2d6d67ffd4c5363b2/images/hub/logos/computer.jpg
The wizardry for this was asking Yuvi how to push changes to the hub pod which is done using chartpress --push
The format for the dlab custom logo (SVG) can't be displayed. We need a standard image format such as png or jpg, and we should be mindful of where the logo is being displayed (it's tiny!). Once we have a suitable image for this, I should be able to move forward with adding it.
Ryan pointed me to docs for rebuilding the hub image: https://docs.datahub.berkeley.edu/en/latest/admins/howto/rebuild-hub-image.html
Thanks, @felder for figuring out the way forward!
@aculich In order for us to execute your request, we will require the D-Lab logo as a PNG/JPG image in the dimensions 416x80 at 72 dpi. You can probably take a look at the space the current logo occupies and design the new logo with those dimensions in mind.
@yuvipanda Couple of questions for you -
Just seeing this re-assigned to me for the logo update... I'll get back to you shortly with the correct dimensions and format.
@balajialg Here's the logo at 416x80. It's a fairly sparse logo, but you can use it for now and later we'll create a version that better fits those dimensions.
Here's our original size logo at 768x512
What's the current status of getting this fully implemented? It would be great to kick off next semester with the branding in place.
Thanks @aculich! We were mostly waiting for the D-lab logo in the PNG format. I will sync with @felder and confirm with you about getting this issue closed before the start of Spring semester.
@felder Can you look into this issue when you have sometime this week?
@balajialg I will try, I have been very busy with other RTL projects this week. I'd say this week is unlikely, but not impossible.
Totally fine if you get to it next week or the following— no need to squeeze it in amongst much higher priorities!
Thanks for bringing attention to this when you're ready to tackle it.
Is this off the table for Spring 2023? Just want to check so I can set expectations. I was talking to other folks on campus about this possible feature and they were potentially interested, too @wrathofquan
We'll absolutely want to have ready to be a part of our Fall 2023 offering— though it would be nice to have by start of summer (mid-May after the semester finishes). Thanks!
@aculich Apologies for the delay at our end! We were severely constrained during the last three weeks from a dev cycles standpoint which made it difficult to prioritize this task for February. I will try to scope this task for March and if that's not feasible then keep April as the deadline month to make some progress. We will be able to circle back on this in the next few day's time. Tagging @felder @shaneknapp!
Noting that in some contexts (e.g., jupyterlab interface) the upper-left logo is not a simple single image element, but rather a set of objects "drawn" in the browser; this may have implications for rebranding all page contexts of a given hub.
The screenshot below illustrates this drawn-in-browser nature via edits of the loaded-in-browser source as a demonstration:
Jonathan has an example from summer of 2022 that shows one of the methods for including a custom logo for a hub.
Note that this strategy has a couple of pieces. The first is a directive in the hub-building Dockerfile that says "copy this here logos directory into the container file system" --
COPY logos /srv/logos
This means that the custom logo for given hub will need to go into a logos/
directory that's "local" to the Dockerfile run context; with this Docker magic, a customlogo.png
in the appropriate logos/
directory in the hub source will get copied into the container as /srv/logos/customlogo.png
.
The complementary configuration change to support a hub's custom logo is to include this configuration directive in the hub's deployments/<hubname>/config/common.yaml
to tell JupyterHub to replace the default logo file path parameter with this custom file that's been copied to the container's /srv/logos/
by the Dockerfile
:
extraConfig:
logoConfig: |
c.JupyterHub.logo_file = '/srv/logos/customlogo.png'
Note that in the dataub universe, there are two places for Dockerfile
(with associated inheritance):
images/hub/Dockerfile
anddeployments/<hubname>/image/Dockerfile
It's my understanding that if COPY logos /srv/logos
is used in the service-wide images/hub/Dockerfile
, then all custom hub logos would need to go into a directory that's in the service-wide context of images/hub/logos
. This is the strategy described in this example.
However, to keep the custom image data and directives within the context/scope of the specific hub that's getting a custom image, the modified Dockerfile
would be the one local to the hub -- i.e., deployments/<hubname>/image/Dockerfile
-- and that hub's custom logo would be placed into a logos directory right next to that Dockerfile
, i.e., deployments/<hubname>/image/logos/customlogo.png
.
I was able to partially test this with repo2docker
running on my local machine. Regrettably, repo2docker
cannot be used to test modifications to deployments/<hubname>/config/common.yaml
, as this file is not used by repo2docker
-- it is, relative to repo2docker
's run context of deployments/<hubname>/image/
, in the neighboring folder ../config/
, which is completely outside of the scope of the Dockerfile
used for a local instance of a hub fired up with repo2docker
.
I did test the Dockerfile
COPY
directive, and was pleased to see that my logos
directory, and its contents, were appropriately included in my container in /srv/
:
Of course, since common.yaml
is not used by repo2docker
, the image itself is not rendered in the browser in this local test context.
We should probably follow through with testing by making custom logo changes to the new logodev
hub, and push it to staging to confirm that this works as expected. (A similar solution worked fine for a local tljh
installation, so I am optimistic.)
@gmerritt thanks for advancing the discussion.
@balajialg for us(@pssachdeva) here at D-Lab this is now a much higher priority as we test RTC for use over the summer, we'd like to make sure our summer workshop participants can clearly differentiate which datahub they're using.
@aculich @gmerritt One issue to consider is that RTC uses jupyterlab which doesn't feature the /hub/logo as much as classic jupyter notebook does. Classic notebook has the large logo at the top left:
While JupyterLab has the smaller icon in the corner:
JupyterLab specifies the top-left icon here, here, and here.
RStudio doesn't use the logo at all.
The logo would still be seen at /hub/home however, though most regular users don't visit that page that often.
So jupyter notebook would require customizing the logo at /hub/logo which involves putting the image in the hub container and customizing the c.JupyterHub.logo_file traitlet as @felder found and which @gmerritt summarized above.
Customizing the top-left logo in lab may require replacing the logo in the singleuser image. I'm not sure where else that svg may appear. Given that the name of the file is jupyter.svg
, it may appear in non-logo contexts.
Lastly, there may be other opportunities for branding besides the logo. For example there could be a jupyterlab extension which loads a new top-level menu with an icon for the menu name and "About {deployment}" as one of the menu items.
Indeed, thanks @ryanlovett -- I dissected that .svg here, above.
My initial thought is to do the jupyter notebooks (non-lab, "classic") first, get that checked off, and then visit other contexts as follow-on tasks?
I will note that for hubs that currently do not use a custom Dockerfile
(a discouraged practice to use custom Dockerfile
s!), simply adding a custom logo means that a non-trivial Dockerfile (to which one will add the COPY
directive) must be created, as here: https://mybinder.readthedocs.io/en/latest/tutorials/dockerfile.html.
This seems to be kind of a bummer -- more moving parts, and extra things to "get wrong" for a hub that may not otherwise be using this discouraged method of customization.
Do we have a "starter" Dockerfile
to use with a hub? I.e., a Dockerfile
with "nothing special" that will otherwise build a hub with defaults?
Given the link above, and some quick local testing, a blank local Dockerfile (one to which we'd hope to simply add the COPY
command for the logos
directory, and nothing else, in the interest of simplicity) does not seem to be supported.
Thanks a lot, @gmerritt and @ryanlovett for your detailed inputs! To your question Greg, based on my initial exploration, most of D-Lab Python-based workshops use JupyterLab as the default interface (eg: Try clicking the "launch datahub" button present in the https://github.com/dlab-berkeley/Python-Fundamentals-Pilot). @aculich - Please clarify if I am incorrect here. From this perspective, pursuing JupyterLab-related changes would make sense over changes to classic notebook interface for this particular issue.
Having said that, I assumed earlier that changing the logo on the tree page would be a helpful way to differentiate hubs in addition to the logo change in the interface. However, As @rylo highlighted most students would skip the interface by using nbgitpuller links to launch the classic notebook or lab (in this context) or RStudio directly. Whether a proposal to change the logo in the JupyterLab interface alone will solve your need here? @aculich. Please clarify!
I am personally in favor of the JupyterLab extension with the menu name and icon as suggested by @rylo. However, not sure how complex such an implementation will be and whether an equivalent implementation for R Studio is possible. I have seen 2i2c folks differentiate the 50+ hubs by modifying the logo in the home page - https://ciroh.awi.2i2c.cloud/hub/login?next=%2Fhub%2F. Not sure whether it is relevant here.
Yes, modifying the logo for the home page before logging in is also desirable, however I think once logged in we would want a quick visual indicator to let us know which one we are connected to.
@aculich Just an FYI, Modifying the JupyterLab logo in the D Lab hub will show up like this - https://innovationoutside.github.io/jupyterlab_ou_brand_extension/lab/index.html (small logo at the left hand top corner)
Oh yeah, that's tiny, but that'll do just fine for starters. Here's the screenshot of that link for the record:
Our logo is distinctive enough as a badge for our folks to recognize it.
@aculich, we've merged to staging the code changes that support custom logos for the "classic" notebook interface for hubs.
An example is currently deployed on this temporary development hub.
The short story for adding a custom logo for the "classic" notebook interface for D-Lab would be the following two additions:
extraConfig:
block under hub:
in D-Lab's common.yaml file, like so, in which the filename matches the filename of the logo file included in 1. above (note the different path!):hub: ... extraConfig: 20-logoConfig: | c.JupyterHub.logo_file = '/srv/logos/dlab-logo-notebook.png'
Aaron, we would like very much to also provide customization options for additional contexts (e.g., /lab
); these changes are to follow.
@aculich Just an FYI, Modifying the JupyterLab logo in the D Lab hub will show up like this - https://innovationoutside.github.io/jupyterlab_ou_brand_extension/lab/index.html (small logo at the left hand top corner)
Here's the top-level link to the source:
https://github.com/innovationOUtside/jupyterlab_ou_brand_extension
In our datahub repo, it looks like jupyterlab comes in only via reference in requirements.txt (jupyterlab==3.4.5
)...I'll have to dig into this to understand how this is used, and how/whether it could be integrated into, and configured for, our hubs.
More documentation related to above-linked repo is here:
Use custom jupyterlab theme extensions to allow customization of the visual user experience, indlucing at least the opportunity to replace the default upper left jupyter logo on a hub's /lab
view.
Custom themes are jupyterlab extensions.
The jupyterlab community has made available a cookiecutter
template for creating custom jupyterlab extensions; this includes a custom theme option:
Generally speaking, an extensions is installed via the methods described at the bototm of this page: https://github.com/jupyterlab/extension-examples/tree/main/server-extension
If available via pypi.org: pip install <extension-name>
If installing locally: pip install -e ./
(in the extension's root directory)
The page linked above also describes running...
jupyter labextension develop . --overwrite
jupyter server extension enable jlab_ext_example
jlpm run build
...but this may not be required for our build context.
I have not encountered examples of, nor have I yet tried, installing via a public github repo: pip install git+git://github.com…/user/repo.git
[EDIT] -- Yes! This works for a public github repo using git+https...
but we do not want to deal with separate repos.
Hub-specific custom configuration code should go into the berkeley-dsep-infra/datahub
repo, not outside of it.
Candidate locations for hub-specific custom configuration code include:
datahub/images/hub/
(Where we've put the logos
directory for custom classic-jupyter [not jupyterlab] custom logos)datahub/deployments/<hubname>/image/
(Where we put custom Dockerfile
and associated files for hub-specific images)repo2docker
and jupyterlab theme extensions in our repo context:Adding a custom local jupyterlab extension seems to require, in our context, adding the image
directory (with appropriate files within) to datahub/deployments/<hubname>/
, as noted in our new hub documentation, at the very bottom of the page:
I've created a custom jupyterlab extension using the cookiecutter
template linked above, and have added it to our datahub/deployments/<hubname>/image/
directory.
I've added the following to the Dockerfile
in datahub/deployments/<hubname>/image/
:
COPY logodevtheme /tmp/logodevtheme
Our practice includes these lines that incorporate and build the environment.yml
file in the datahub/deployments/<hubname>/image/
directory:
COPY environment.yml /tmp/environment.yml
RUN mamba env update -p ${CONDA_DIR} -f /tmp/environment.yml && mamba clean -afy
The build happens via a line added to environment.yml
that adds the following directive:
- -e /tmp/logodevtheme
(in the dependencies: - pip:
block)Dependecies and errors are vexing, and slow to debug with the repo2docker
long build times. For the sample image
directory I used, this sample theme extension required updates to...
jupyterlab
(jupyterlab==3.4.7
) in the infra-requirements.txt
file [which is also COPY
'd by Dockerfile
] andnodejs
(- nodejs==15.*
) in the environment.yml
file.I am currently getting the following error when I build with repo2docker
in the image
directory; perhaps a dependency issue?:
AttributeError: module 'hatchling.build' has no attribute 'prepare_metadata_for_build_editable'
ERROR: No matching distribution found for logodevtheme (from -r /tmp/environment.yml (line 6))``Note that I have successfully built theme-darcula
non-locally, via dependencies: - theme-darcula
in environment.yml
; this works great, and shows up in the /lab
view as a theme option. I have not yet tried to build theme-darcula
locally, but I suspect it would work.
When I copy the theme-darcula
repo locally to image/
and try to use the Dockerfile
/ environment.yml
approach, I get this error:
error: could not create 'theme_darcula.egg-info': Permission denied
If I only COPY
the theme-dracula
repo into /tmp
via the Dockerfile, and then try to build with terminal in jupyterlab, I also get the Permission denied
error However, if I copy /tmp/theme-darcula
to ~/
in my jupyterlab terminal, then pip install ./
works successfully.
cookiecutter
-created sample theme extension with the pip install git+git://github.com…/user/repo.git
method, but this breaks our model of integrating custom code into our berkeley-dsep-infra/datahub
repo. This is likely not a supportable solution for us.image
directory, but who wants a custom, locally-built theme, will have to get into the business of managing an image
directory with its Dockerfile
and associated files, directories, and complications.Also: very not-yet-done is figuring out how to modify the custom theme extension to render a custom logo! This has been assumed possible & straightforward, and my expectation has been that the custom theme extension integration & build would be the tricky bits!
Node.js needs to be just the right version for the cookiecutter theme & its dependencies; the latest of version 16 seems to work, so environment.yml
can set...
dependencies:
- nodejs==16.*
Due to subtle peculiarities of the build process, in order to build your custom theme into the image using the cookiecutter
official jupyterlab theme extension approach one must use a custom image with Dockerfile
(putting your custom theme extension folder in deployments/Dockerfile
) and adding these lines to Dockerfile
just after RUN mamba; this will result in getting your theme added to your /lab url’s theme menu:
COPY logodevtheme /tmp/logodevtheme
RUN cd /tmp/logodevtheme; tar -czvf /tmp/logodevtheme.tar.gz *
RUN pip install --user /tmp/logodevtheme.tar.gz
Dockerfile
will also need additional lines to even create the default image for your hub; we do not have any current example aside from those that are more-highly-customized for hubs that use them for special requirements, so this is a big "to-do," i.e. creating a starter Dockerfile
-based custom image file tree that accurately defines the default hub and that is ready to accommodate a custom theme extension build.
Notes to follow regarding understandings of how to customize the theme with your desired logo in the upper left corner of /lab
view.
To modify the custom cookiecutter-created official theme extension as referenced previously, I found the following to be necessary:
Create a folder deployments/<hubname>/image/style/
and include your custom .svg logo in that folder. (I've tried with one .png that did not seem to work well? More testing needed.)
Add a base.css
file to deployments/<hubname>/image/style/
with the following contents, including the reference to your custom .svg file:
#jp-MainLogo > svg {
visibility: hidden;
}
#jp-MainLogo {
background-image: url(./images/logodevtheme_logo.svg);
background-repeat: no-repeat;
}
In deployments/<hubname>/image/style/index.css
add the line @import './base.css';
.
I'm now working on understanding how to change the default theme to the custom theme. https://github.com/jupyterlab/jupyterlab/issues/9988 provides some inspiration via the overrides.json
approach; see:
https://github.com/berkeley-dsep-infra/datahub/blob/staging/deployments/stat159/image/overrides.json & https://github.com/berkeley-dsep-infra/datahub/blob/staging/deployments/stat159/image/postBuild .
Neither this build-time postBuild
file approach nor the run-time start
file approach worked for me (yet!) in local testing.
@aculich My understanding of where things stand now based on the comprehensive exploration done by @gmerritt - You can customize the logo for Jupyter Notebooks but to customize the theme/logo for lab requires more dev bandwidth which Greg currently doesn't have. If anyone in your team has the necessary skills + some dev bandwidth to continue this exploration for JupyterLab, I think Greg would be more than happy to give a knowledge transfer (most of which is documented in this issue clearly). Please let us know!
@shaneknapp @gmerritt Please feel free to add and also correct if I have missed or misrepresented the next steps.
Thank you very much for this summary, @balajialg. Yes, while using a custom theme for a lab is quite technically possible, it all-too-quickly becomes a "rabbit hole" of committing to defining and maintaining a custom image for that hub. This includes navigating version conflicts of many of the dependencies, and one may quickly find oneself supporting an intricate set of subtly interacting version requirements that may also be very different versions from our standard hub installation.
@aculich, if you would like to start along this path of a more self-supported hub image, I would be more than happy to meet to review what I've learned.
@balajialg @gmerritt thanks to both of you keeping this moving forward.
Yes, @gmerritt would love to set up a time to meet along with my colleague @pssachdeva about a more self-supported hub image.
Summary
A branding mechanism would help to more easily & quickly distinguish at a glance between multiple datahubs.
User Stories
Acceptance criteria
Important information
Tasks to complete