Pyramid views for serving collections of compiled static assets (eg. bundles of JavaScript and CSS).
Compared to Pyramid's builtin static asset functionality , this provides a convenient way to serve assets based on certain assumptions about how assets are generated and opinions about how they should be served:
build
directory in
the root of the repository.Additionally h-assets provides a way to define collections (bundles) of
assets and methods to generate cache-busted URLs for all assets in the bundle.
This is useful for example to render all the <script>
or <style>
tags that
are needed by a certain part of a site.
Using h-assets in a Pyramid project involves three steps:
Environment
to handle asset URL generation and register a view to serve assets from that
environmentEnvironment
to your
templating system so that templates can generate asset URLsSet up a process to compile or copy assets from source files into an
output directory. Conventionally Hypothesis projects use a folder called
build
in the repository root.
In the output directory generate a JSON manifest file (eg. manifest.json
)
that maps asset paths to URLs with cache-busting query strings. Example content:
{
"scripts/app.bundle.js": "scripts/app.bundle.js?abcdef",
"scripts/vendor.bundle.js": "scripts/vendor.bundle.js?xyz123"
}
Any format is allowed for the cache-buster. Hypothesis projects typically use the first few characters of a hash (eg. SHA-1) of the file's contents.
Create an INI file (eg. assets.ini
) that defines collections ("bundles")
of assets that are used together. Example content:
[bundles]
frontend_apps_js =
scripts/browser_check.bundle.js
scripts/frontend_apps.bundle.js
frontend_apps_css =
styles/frontend_apps.css
To serve assets using h-assets, a Pyramid view needs to be created using the
assets_view
function.
In the Pyramid app configuration, define a route where the URL is a base URL
followed by a *subpath
:
def includeme(config):
config.add_route("assets", "/assets/*subpath")
To register the view associated with this route, first create an Environment
to handle generation of asset URLs. Then use assets_view
to create the view
callable for use with config.add_view
:
import os.path
from h_assets import Environment, assets_view
def includeme(config):
# This assumes the following repository structure:
# build/ - Compiled frontend assets
# manifest.json
# projectname/
# assets.py - This module
# routes.py - Route definitions
# assets.ini
root_dir = os.path.dirname(__file__)
assets_env = Environment(
assets_base_url="/assets",
bundle_config_path="{root_dir}/assets.ini",
manifest_path=f"{root_dir}/../build/manifest.json",
)
# Store asset environment in registry for use in registering `asset_urls`
# Jinja2 helper in `app.py`.
config.registry["assets_env"] = assets_env
config.add_view(route_name="assets", view=assets_view(assets_env))
To get a list of asset URLs for assets in a bundle, use the urls
method of the
asset Environment
. A common pattern is to expose these methods as global helpers
in the templating environment being used to generate HTML responses. For example,
in a project using pyramid_jinja2
:
jinja2_env = config.get_jinja2_environment()
jinja2_env.globals["asset_url"] = config.registry["assets_env"].url
jinja2_env.globals["asset_urls"] = config.registry["assets_env"].urls
Then a template can generate URLs using:
{% for url in asset_urls("frontend_apps_js") %}
<script async defer src="https://github.com/hypothesis/h-assets/raw/main/{{ url }}"></script>
{% endfor %}
First you'll need to install:
sudo apt install git
, on macOS: brew install git
.make --version
to check.Then to set up your development environment:
git clone https://github.com/hypothesis/h-assets.git
cd h-assets
make help
First, to get PyPI publishing working you need to go to:
https://github.com/organizations/hypothesis/settings/secrets/actions/PYPI_TOKEN
and add h-assets to the PYPI_TOKEN
secret's selected
repositories.
Now that the h-assets project has access to the PYPI_TOKEN
secret
you can release a new version by just creating a new GitHub release.
Publishing a new GitHub release will automatically trigger
a GitHub Actions workflow
that will build the new version of your Python package and upload it to
https://pypi.org/project/h-assets.
To change what versions of Python the project uses:
Change the Python versions in the cookiecutter.json file. For example:
"python_versions": "3.10.4, 3.9.12",
Re-run the cookiecutter template:
make template
Commit everything to git and send a pull request
To change the production dependencies in the setup.cfg
file:
Change the dependencies in the .cookiecutter/includes/setuptools/install_requires
file.
If this file doesn't exist yet create it and add some dependencies to it.
For example:
pyramid
sqlalchemy
celery
Re-run the cookiecutter template:
make template
Commit everything to git and send a pull request
To change the project's formatting, linting and test dependencies:
Change the dependencies in the .cookiecutter/includes/tox/deps
file.
If this file doesn't exist yet create it and add some dependencies to it.
Use tox's factor-conditional settings
to limit which environment(s) each dependency is used in.
For example:
lint: flake8,
format: autopep8,
lint,tests: pytest-faker,
Re-run the cookiecutter template:
make template
Commit everything to git and send a pull request