This service generates short URLs for neuroglancer views, which are encoded in very long URLs. This functionality was originally housed in a repository on Neuroglancer Hub and was split off from it. This repository generates a container that can be used with Google's "Cloud Run" service to run the link shortener.
The website and API share these input parameters:
link(textfor the API): This field must contain theneuroglancerlink in one of three forms:- the full
neuroglancerlink, copied from theneuroglancerapplication - the JSON state, either copied from
neuroglanceror created programmatically - a previously shortened link, which will be re-saved under the new filename
- the full
title(optional): If provided, this title will appear in the browser tab or browser title bar. It will replace whatever title was specified in the input link.filename: (optional): This is the name under which the link will be saved, and it will appear in the shortened URL. If omitted, the generated filename will be based on the date and time of the request.password(optional): Optional password to allow editing (re-saving) the link with thisfilenameindefinitely. See Security below.
The filename, title, and text (link) fields of the web form can be prepopulated through query parameters on the URL (eg, shortener.html?filename=my-shortened-link).
Code for accessing the API via Python looks like this:
import requests
data = {
"text": "http://neuroglancer-url/long-json-here.json",
"filename": "my-optional-filename",
"title": "optional title for browser",
"password": "myOptionalPassw0rd!",
}
r = requests.post("http://link.shortener.URL/shortng", json=data)
print(f"link: {r.json()['link']}")Links can be edited, meaning they can be re-saved with the same filename but a new link and/or title.
To prevent accidental or malicious editing, two mechanisms are in place:
- If an optional
passwordis provided, later attempts to save the link with the samefilenamemust also provide thepasswordor they will fail. - If a
passwordwas not provided, editing is only allowed for one week after the last successful edit. The time length is configurable when building the container by editing theEDIT_EXPIRATIONvariable inshortng.py.
To build and upload the container with Google Cloudbuild registry:
gcloud builds submit --tag gcr.io/flyem-private/flyem-shortenerTo build FASTER using the most recent container as the cache:
gcloud builds submit --config cloudbuild.yamlAlteratively, just use docker to build locally.
docker build . -t gcr.io/flyem-private/flyem-shortenerThen to push to the Google Artifact Registry, you need to authenticate with Google cloud and configure Docker use those credentials:
gcloud auth login
gcloud auth configure-docker # first time onlyThen:
docker push gcr.io/flyem-private/flyem-shortenerNOTE: None of the above commands will actually DEPLOY the container. The easiest way to do that is via the google cloud console.
To run the (minimal, incomplete) tests:
pip install pytest
cd flyem-shortener
pytest testThis must be done in an environment with the project's Python dependencies, and the Google Cloud credentials should be in GOOGLE_APPLICATION_CREDENTIALS.
To just run the server locally (assuming you have the dependencies installed), try this:
export GOOGLE_APPLICATION_CREDENTIALS_CONTENTS=$(cat $GOOGLE_APPLICATION_CREDENTIALS)
gunicorn --bind 0.0.0.0:8080 --workers 4 --threads 2 shortener.app:app...and then navigate to http://localhost:8080 in a browser.
To test locally using the Docker container:
export GOOGLE_APPLICATION_CREDENTIALS_CONTENTS=$(cat $GOOGLE_APPLICATION_CREDENTIALS)
docker build --platform linux/amd64 . -t gcr.io/flyem-private/flyem-shortener
docker run -p 8080:8080 -e GOOGLE_APPLICATION_CREDENTIALS_CONTENTS flyem-shortener-testWe list our high-level dependencies in requirements.in, and then we use pip-compile to generate requirements.txt, which serves as a fine-grained lock file.
To use the container's own copy of pip to update the requirements, try this:
cd flyem-shortener
# Build/run the container locally, with the current directory mounted inside.
docker build -t flyem-shortener-test .
docker run -p 8080:8080 -e GOOGLE_APPLICATION_CREDENTIALS_CONTENTS -v $(pwd):/flyem-shortener -it flyem-shortener-test /bin/bash
# Inside the container...
cd /flyem-shortener
pip install pip-tools
# This will update requirements.txt, which you'll see from outside the container.
pip-compile requirements.in
pip install -r requirements.txt
exit(Now commit requirements.txt and requirements.in to git.)