Skip to content

arXiv/arxiv-base

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,573 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

arXiv Base

This project provides a base Flask application and base Docker image for arXiv-NG services.

Each component of this project must meet all the following criteria:

  1. It is likely that the component will be utilized in many or all arXiv services.
  2. Once stable, it is unlikely to change often.
  3. It is unlikely that implementing new features in specific services would require changes to the component.
  4. When a component does change, it must change in the same way for all the services that use it.

Base CSS and Templates for arXiv.org-NG

Templates are written in Jinja2 syntax. CSS framework is Bulma with arXiv-specific overrides for color and typography. While the .sass format has been used for override files, .scss files may also be imported and included.

These files set the default display styles and layout for all pages on arxiv-NG, and can be overridden as needed by submodules.

A template is included for rapid evaluation of display layer CSS within this repo, prepopulated with sample content. The styleguide.html template (route: /styleguide) shows error message samples, informational message boxes, and sample content from search.

Development server

This project includes a minimal Flask application for development verification/testing purposes. To run the dev server (assuming that you are working in the root of this repository):

poetry install
$ FLASK_APP=app.py FLASK_DEBUG=1 poetry run flask run

You should be able to view the rendered styleguide.html at http://127.0.0.1:5000/styleguide.

Installing arxiv-base

To use the base package in a Flask application add it to your dependency manager. To use a specific version, for example, you would write:

arxiv-base = "==0.11.1rc5"

Or if you want to install a specific working branch (dev only) the line might read:

arxiv-base = {git = "https://github.com/arXiv/arxiv-base.git@task/ARXIVNG-1215"}

You can use pip from the command line to install a selected unpublished branch. First uninstall existing, then reinstall using pip syntax above. Example:

pip uninstall arxiv-base
pip install git+https://github.com/arXiv/arxiv-base.git@task/ARXIVNG-1010#egg=arxiv-base

Using arxiv-base with Flask

In your application factory, instantiate the Base component. This makes templates and static files available to you. For example, in your factory.py module:

from flask import Flask
from arxiv.base import Base

def create_web_app() -> Flask:
   app = Flask('mega_tool')
   app.config.from_pyfile('config.py')

   Base(app)   # Registers the base/UI blueprint.
   @app.route("/mega_tool")
   def mega_tool():
       # TODO use something from arxiv-base 
       return "<p>Mega_tool!</p>"

   return app

You can now extend base templates, e.g.:

{%- extends "base/base.html" %}

{% block content %}
Hello world!
{% endblock %}

And use static files in your templates, e.g.:

{{ url_for('base.static', filename='images/CUL-reduced-white-SMALL.svg') }}

Static files and paths

In order to serve static assets for multiple versions of the app at the same time, arxiv-base prefixes the app name and app version to asset urls. This is to allow gracefully upgrades with no broken links to css, js or images.

The Base component will automatically set your app's static_url_path using the name of the app and the value of APP VERSION in your config to /static/[app name]/[ app version ]. It will also rewrite blueprint static_url_path to /static/[app name]/[ app version ]/[ blueprint name].

Publishing static files to GCS

arxiv/base/static is the single source of truth for the shared chrome (css/arxiv-header-footer.css, js/arxiv-header.js, the IBM Plex fonts, the arXiv logo + funder images) and the rest of base's assets. Every app consumes these instead of vendoring a copy — Flask apps via url_for('base.static', …), non-Flask apps via the absolute /static/base/<BASE_VERSION>/… URL.

Env Bucket Served at
prod gs://arxiv-web-static https://static.arxiv.org/
dev gs://arxiv-dev-web-static https://static.dev.arxiv.org/

Assets land at /static/base/<BASE_VERSION>/… — the same versioned path the base blueprint serves (arxiv/base/__init__.py), so the URL resolves 1:1 with base.static. Versioned paths are immutable: bump the package version to roll a new release.

Publish — out-of-band (not CI), once per released BASE_VERSION. Test on dev first, then prod at release:

pip install ./
gcloud auth login   # or a service account with roles/storage.objectAdmin on the bucket

python upload_static_assets.py --bucket gs://arxiv-dev-web-static   # dev  — test here first
python upload_static_assets.py --bucket gs://arxiv-web-static       # prod — at release

--dry-run previews. The script rsyncs arxiv/base/static/<bucket>/static/base/<BASE_VERSION>/ and pins font/woff2 on the IBM Plex files.

One-time bucket setup — already done for both buckets; needed only to add a new one:

gcloud storage buckets create gs://<bucket> --location=us-central1 --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding gs://<bucket> \
  --member=allUsers --role=roles/storage.objectViewer          # public read
gcloud storage buckets update gs://<bucket> --cors-file=cors.json   # cross-origin @font-face

How apps resolve it — same bytes everywhere; only the host differs per env:

  • Flask (browse, auth, search): set FLASKS3_ACTIVE=1 and FLASKS3_CDN_DOMAIN (static.arxiv.org prod / static.dev.arxiv.org dev) and keep using url_for('base.static', …). No hardcoded host.
  • Non-Flask (submit, docs, status): reference https://<static-host>/static/base/<BASE_VERSION>/…, where <static-host> is a configurable root (mkdocs !ENV, Catalyst config, …) — prod default, dev override.

Migrated 2026-06 from the legacy AWS / Flask-S3 upload (boto + the old arxiv-web-static1 bucket); the embedded AWS key went with it.

App tests

Some tests to check app configuration and pattern compliance are provided in arxiv.base.tests. See that module for usage. You can run them with the command pytest

Editing and compiling sass

The file arxivstyle.css should never be edited directly. It is compiled from arxivstyle.sass with this command from project directory root: sass arxiv/base/static/sass/arxivstyle.sass:arxiv/base/static/css/arxivstyle.css

or you can use the --watch option to autocompile on any changed file:

sass --watch arxiv/base/static/sass/arxivstyle.sass:arxiv/base/static/css/arxivstyle.css

Bulma source files are included in the static/sass directory so that variables can be overridden directly during compile. The arxivstyle.sass file has been written to do this; do not edit it.

Documentation for sass

Layout features, tips and tricks

Beta watermark

Adding class="beta" to the main content div will create a beta watermark at the top left of pages having this class.

Upload to pypi

pip install --upgrade setuptools wheel twine
python setup.py sdist bdist_wheel
twine --upload dist/*  # Enter username and password from lastpass

About

Supporting libraries for templates and arXiv services

Topics

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages