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

Allow building more complex profile_list templates #724

Merged
merged 12 commits into from
May 17, 2023

Conversation

yuvipanda
Copy link
Collaborator

@yuvipanda yuvipanda commented Apr 27, 2023

The profile_list HTML / CSS was a single string embedded into the python code,
and modifications were allowed as a single traitlet that had to be a fully complete jinja2
template.

This becomes difficult to manage very quickly, and means we lose out on all the compositional
benefits of using jinja2 templates.

This PR will:

  • Split the existing HTML / CSS string into a separate HTML & CSS file
  • Switch to FilesystemLoader, so we can split out the one big HTML / CSS file into
    multiple smaller files and compose them together
  • Add the config additional_profile_form_template_paths to allow admins to set extra paths where templates can be found. This
    allows admins to customize the profile_list form easily without having to shove everything
    into one file. This is stolen from JupyterHub's JupyterHub.template_paths.
  • Add a pre-commit hook to autoformat the default templates we ship
  • Add some docs on how admins can continue to customize the profile_list template by setting
    the string, but also recommends using the directory based approach for more complex changes.
    This allows the change to be backwards compatible.

This is HTML / CSS that was embedded in python literally.
Was getting big enough that working on it like this was no fun,
so I have moved it to its own file.
@manics
Copy link
Member

manics commented Apr 27, 2023

https://setuptools.pypa.io/en/latest/userguide/datafiles.html#accessing-data-files-at-runtime recommends using importlib.resources instead of relying on direct filesystem access.

@yuvipanda
Copy link
Collaborator Author

@manics it looks like that would only work on python 3.10+ without adding an external dependency. From https://setuptools.pypa.io/en/latest/userguide/datafiles.html#accessing-data-files-at-runtime

importlib.resources was added to Python 3.7. However, the API illustrated in this code (using files()) was added only in Python 3.9, [3] and support for accessing data files via namespace packages was added only in Python 3.10 [4] (the data subdirectory is a namespace package under the root package mypkg). Therefore, you may find this code to work only in Python 3.10 (and above). For other versions of Python, you are recommended to use the importlib-resources backport which provides the latest version of this library.

I'd say it's ok to let this be, maybe add a note to remove it once we are python 3.10+ only?

@yuvipanda
Copy link
Collaborator Author

@manics the alternative is to add the additional dependency, which we currently don't have. I just checked to see if any jupyterhub or kubespawner dependency transitively includes that - turns out the answer is no. If you strongly prefer, I will add that dependency?

@yuvipanda
Copy link
Collaborator Author

(am working through the pre-commit situation now)

@manics
Copy link
Member

manics commented Apr 27, 2023

If there's no easy fix then leave it as it is unless anyone else has thoughts

- Supports autoformatting too
- Exclude from prettier, which treats them as .html files and
  mangles everything
Otherwise, users will have to manually reformat
@yuvipanda yuvipanda requested a review from manics April 27, 2023 15:38
@yuvipanda
Copy link
Collaborator Author

hmm, not sure if the test failures are related.

@yuvipanda
Copy link
Collaborator Author

Per @consideRatio the test failures are unrelated #721 (comment)****

@consideRatio
Copy link
Member

Per @consideRatio the test failures are unrelated #721 (comment)****

@yuvipanda the failures I meant would have shown up during the action-k3s-helm step, not in pytest. It seems that the failure seen here is recurring for the py37 env with oldest dependencies.

But, they seem to be indepent of this PR as when I triggered the test workflow in the main branch, I saw the failures as well: https://github.com/jupyterhub/kubespawner/actions/runs/4824271639

@yuvipanda
Copy link
Collaborator Author

@consideRatio makes sense. Let's investigate that separately from this PR?

@consideRatio
Copy link
Member

@yuvipanda yes I agree, separate investigation.

I'm considering an conditional dependency for importlib_resources. I've seen Min do similar things in several places.

Python version constrained requirement, that is conditionally imported.

Reading this not confident on the implications or meaning, I would feel at ease knowing we do that.

It is strongly recommended that, if you are using data files, you should use importlib.resources to access them.

@yuvipanda yuvipanda changed the title Move profile_form_template default into its own file Render profile_form with jinja2 templates robustly Apr 27, 2023
@yuvipanda
Copy link
Collaborator Author

@consideRatio ok, I've expanded the scope of this PR a little bit, and in the process got rid of the manual template loading :)

@yuvipanda
Copy link
Collaborator Author

Alright, I've completely removed the usage of __file__ from here!

Copy link
Member

@consideRatio consideRatio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love seeing these as standalone files, and I'm happy to see a jinja autoformatter we can use with pre-commit!

I think the additional_profile_form_template_paths sounds reasonable, thinking about the option of simply having profile_form_template_paths and letting its @default(...) function evaluate something. Maybe not though, then its far easier to override it when you want to append to it when configuring this via YAML based config rather than Python based config. So, maybe this is the way to go as it is.

Are the .html / .css files solely extracted and autoformatted - but not changed?

kubespawner/spawner.py Outdated Show resolved Hide resolved
kubespawner/spawner.py Outdated Show resolved Hide resolved
pyproject.toml Show resolved Hide resolved
yuvipanda and others added 2 commits April 27, 2023 16:56
Co-authored-by: Erik Sundell <erik.i.sundell@gmail.com>
@yuvipanda
Copy link
Collaborator Author

@consideRatio I have not changed the contents of the templates, so there should be no visual differences. Just extracted and autoformatted.

Copy link
Member

@consideRatio consideRatio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this LGTM. @manics what do you think?


@yuvipanda can you update the PR description to mention that you add the new config option, and maybe consider if the title can highlight what is new for the jupyterhub admin reading this changelog? It sounds like a bugfix/maintenance PR in a way as it mentions "robustly".

@yuvipanda yuvipanda changed the title Render profile_form with jinja2 templates robustly Allow building more complex profile_list templates Apr 28, 2023
@yuvipanda
Copy link
Collaborator Author

@consideRatio how about now for the PR title & description?

@manics
Copy link
Member

manics commented Apr 28, 2023

I haven't reviewed the latest code but I'm happy to go with @consideRatio

Are we happy that the wheel package correctly contains these extra files (from python -mbuild .), or can we rely on pyproject.toml/the build system to just "do the right thing"?

@yuvipanda
Copy link
Collaborator Author

@manics hmm, I see it in the sdist but not wheel! Investigating.

@yuvipanda
Copy link
Collaborator Author

@manics turns out hatch doesn't read MANIFEST.in, so I've included it separately in the wheel now. Good catch!

@consideRatio
Copy link
Member

Nice work @yuvipanda !!!

@yuvipanda
Copy link
Collaborator Author

THANKS A LOT, @consideRatio!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants