Skip to content
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

Add customizable datahub branding for hub admins #3248

Open
aculich opened this issue Feb 8, 2022 · 38 comments
Open

Add customizable datahub branding for hub admins #3248

aculich opened this issue Feb 8, 2022 · 38 comments
Assignees
Labels
enhancement Issues around improving existing functionality jira Issue tracked in JIRA priority: medium Medium priority tasks

Comments

@aculich
Copy link

aculich commented Feb 8, 2022

Summary

A branding mechanism would help to more easily & quickly distinguish at a glance between multiple datahubs.

User Stories

  • As a workshop participant or instructor I want a visual indicator to more easily distinguish between different datahub (e.g. the general campus-wide datahub at https://datahub.berkeley.edu/ versus the D-Lab specific datahub at https://dlab.datahub.berkeley.edu/ so that I can avoid confusion and more quickly and easily verify at a glance that I am using the correct resource. Relying on just the URL makes it harder to see the distinction.

Acceptance criteria

  • Given a change in appearance of the datahub when logged in, when a user looks at the page, then it clearly indicates what hub they are logged into.

Important information

  • The simplest implementation of this would be to allow hub-admins to change the upper-left icon, e.g. for the D-Lab datahub use the D-Lab logo instead of the Jupyter Notebook logo.

    image

Tasks to complete

@balajialg
Copy link
Contributor

balajialg commented Feb 9, 2022

@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!

@balajialg balajialg added the enhancement Issues around improving existing functionality label Feb 9, 2022
@aculich
Copy link
Author

aculich commented Feb 11, 2022

Not time-sensitive at the moment, but a nice-to-have especially if we start using it more heavily in the future.

@balajialg balajialg assigned yuvipanda and unassigned balajialg Mar 4, 2022
@balajialg
Copy link
Contributor

@yuvipanda nudge to add your suggestions from the sprint planning meeting!

@yuvipanda
Copy link
Contributor

@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?

@aculich
Copy link
Author

aculich commented Mar 23, 2022

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?

@balajialg
Copy link
Contributor

balajialg commented Apr 15, 2022

@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!

@ryanlovett
Copy link
Collaborator

@yuvipanda @felder re: disambiguating hubs, custom logos, etc.

@balajialg
Copy link
Contributor

balajialg commented Jul 7, 2022

  • @felder to investigate whether the solution highlighted here is relevant to solving this Github issue!

@felder
Copy link
Contributor

felder commented Jul 8, 2022

@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.

@felder
Copy link
Contributor

felder commented Jul 8, 2022

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:

Where the Dockerfile for the hub pod is modified to have the custom logo:

COPY logos /srv/logos

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

@balajialg
Copy link
Contributor

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 -

  • The only place the logo appears in the UI is at the top left corner right? This will help us validate whether the dimensions shared with @aculich are accurate.
  • Will the logo resize based on the rendering screen size? I assume it should be a yes but just wanted to confirm.

@aculich
Copy link
Author

aculich commented Mar 1, 2023

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!

@balajialg
Copy link
Contributor

@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!

@gmerritt
Copy link
Contributor

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:

screenshot_572

@balajialg balajialg added the priority: medium Medium priority tasks label Apr 3, 2023
@gmerritt
Copy link
Contributor

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):

  1. images/hub/Dockerfile and
  2. deployments/<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/:

screenshot_786

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.)

@aculich
Copy link
Author

aculich commented Apr 17, 2023

@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.

@ryanlovett
Copy link
Collaborator

@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:
Screenshot 2023-04-17 at 1 43 15 PM

While JupyterLab has the smaller icon in the corner:
Screenshot 2023-04-17 at 1 43 31 PM

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.

@gmerritt
Copy link
Contributor

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?

@gmerritt
Copy link
Contributor

I will note that for hubs that currently do not use a custom Dockerfile (a discouraged practice to use custom Dockerfiles!), 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.

@balajialg
Copy link
Contributor

balajialg commented Apr 17, 2023

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.

@aculich
Copy link
Author

aculich commented Apr 17, 2023

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.

@balajialg
Copy link
Contributor

balajialg commented Apr 18, 2023

@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)

@aculich
Copy link
Author

aculich commented Apr 18, 2023

Oh yeah, that's tiny, but that'll do just fine for starters. Here's the screenshot of that link for the record:
image

Our logo is distinctive enough as a badge for our folks to recognize it.

@gmerritt
Copy link
Contributor

@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:

  1. Add a suitable logo image file, such as a .png, to this hubwide directory: images/hub/logos/.
  2. Add an 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.

@gmerritt
Copy link
Contributor

@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:

https://blog.ouseful.info/2022/04/29/custom-branded-logos-for-jupyterlab-and-retrolab-jupyter-notebook-v-7/

@gmerritt
Copy link
Contributor

gmerritt commented May 4, 2023

Investigating custom jupyterlab theme extensions

Proposed:

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.

Jupyterhub archictecture notes:

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.

Our practice for hub-specific customization:

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)

What I've tried and learned so far with 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] and
  • nodejs (- 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.

What to consider next? (In addition to continued debugging of current build error)

  • It may be worth trying to build the 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.
  • A hub owner that does not currently use an 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.
  • As seen with my trial runs, custom theme extensions may introduce dependency version conflicts that are difficult to debug and resolve.

@gmerritt
Copy link
Contributor

gmerritt commented May 4, 2023

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!

@gmerritt
Copy link
Contributor

gmerritt commented May 8, 2023

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//image/ alongside the 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.

@gmerritt
Copy link
Contributor

gmerritt commented May 8, 2023

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. jupyterlab/jupyterlab#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.

@balajialg balajialg added the jira Issue tracked in JIRA label May 12, 2023
@balajialg
Copy link
Contributor

balajialg commented May 31, 2023

@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.

@gmerritt
Copy link
Contributor

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.

@aculich
Copy link
Author

aculich commented May 31, 2023

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Issues around improving existing functionality jira Issue tracked in JIRA priority: medium Medium priority tasks
Projects
None yet
Development

No branches or pull requests

7 participants