{"id":31908785,"url":"https://github.com/allenai/beaker-gantry","last_synced_at":"2026-03-07T02:19:13.174Z","repository":{"id":37214696,"uuid":"491230199","full_name":"allenai/beaker-gantry","owner":"allenai","description":"Gantry is a CLI that streamlines running experiments in Beaker","archived":false,"fork":false,"pushed_at":"2026-03-02T22:32:55.000Z","size":575,"stargazers_count":32,"open_issues_count":6,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-03-03T00:46:23.778Z","etag":null,"topics":["beaker","cli","containers","docker","python"],"latest_commit_sha":null,"homepage":"https://beaker-py-docs.allen.ai/gantry","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/allenai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-05-11T18:32:07.000Z","updated_at":"2026-03-02T22:32:57.000Z","dependencies_parsed_at":"2024-02-19T22:53:09.249Z","dependency_job_id":"60e4f624-3842-42f6-97de-f7e9ab61802c","html_url":"https://github.com/allenai/beaker-gantry","commit_stats":null,"previous_names":[],"tags_count":118,"template":false,"template_full_name":"allenai/python-package-template","purl":"pkg:github/allenai/beaker-gantry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenai%2Fbeaker-gantry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenai%2Fbeaker-gantry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenai%2Fbeaker-gantry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenai%2Fbeaker-gantry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allenai","download_url":"https://codeload.github.com/allenai/beaker-gantry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allenai%2Fbeaker-gantry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30205921,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"online","status_checked_at":"2026-03-07T02:00:06.765Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beaker","cli","containers","docker","python"],"created_at":"2025-10-13T15:56:20.748Z","updated_at":"2026-03-07T02:19:13.151Z","avatar_url":"https://github.com/allenai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003cbr\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/allenai/beaker-py/main/docs/source/_static/beaker-500px-transparent.png\" width=\"200\"/\u003e\n\u003cbr\u003e\n\u003ch1\u003eBeaker Gantry\u003c/h1\u003e\n\u003cp\u003eGantry is a CLI that streamlines running experiments in \u003ca href=\"https://beaker.org\"\u003eBeaker\u003c/a\u003e.\u003c/p\u003e\n\u003chr/\u003e\n\u003c!-- TODO: Add badges once this is open source --\u003e\n\u003ca href=\"https://github.com/allenai/beaker-gantry/actions\"\u003e\n    \u003cimg alt=\"CI\" src=\"https://github.com/allenai/beaker-gantry/actions/workflows/main.yml/badge.svg\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/beaker-gantry/\"\u003e\n    \u003cimg alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/beaker-gantry\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/allenai/beaker-gantry/blob/main/LICENSE\"\u003e\n    \u003cimg alt=\"License\" src=\"https://img.shields.io/github/license/allenai/beaker-gantry.svg?color=blue\u0026cachedrop\"\u003e\n\u003c/a\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003c/div\u003e\n\n\u003c!-- begin intro --\u003e\n![2025-07-18 12 49 12](https://github.com/user-attachments/assets/82fa93ae-f512-4e76-ab95-95a535515e5b)\n\n\n⚡️*Easy to use*\n\n- **No Docker required!** 🚫 🐳\n- No writing Beaker YAML experiment specs.\n- Easy setup.\n- Simple CLI.\n\n🏎  *Fast*\n\n- Fire off Beaker experiments from your laptop instantly!\n- No local image build or upload.\n\n🪶 *Lightweight*\n\n- Pure Python (built on top of [beaker](https://github.com/allenai/beaker)'s Python client).\n- Minimal dependencies.\n\n### Who is this for?\n\nGantry is for both new and seasoned Beaker users who need to run batch jobs (as opposed to interactive sessions) from a rapidly changing repository, especially Python-based jobs.\n\n*Without* Gantry, this workflow usually looks like this:\n\n1. Add a Dockerfile to your repository.\n2. Build the Docker image locally.\n3. Push the Docker image to Beaker.\n4. Write a YAML Beaker experiment spec that points to the image you just uploaded.\n5. Submit the experiment spec.\n6. Make changes and repeat from step 2.\n\nThis requires experience with Docker, experience writing Beaker experiment specs, and a fast and reliable internet connection.\n\n*With* Gantry, on the other hand, that same workflow simplifies down to this:\n\n1. (Optional) Write a `pyproject.toml`/`setup.py` file, a PIP `requirements.txt` file, a or conda `environment.yml` file to specify your Python environment.\n2. Commit and push your changes.\n3. Submit and track a Beaker experiment with the `gantry run` command.\n4. Make changes and repeat from step 2.\n\u003c!-- end intro --\u003e\n\n## In this README\n\n- 💾 **[Installing](#installing)**\n- 🚀 **[Quick start](#quick-start)**\n- ❓ **[FAQ](#faq)**\n\n### Additional info\n\n#### 👋 *Examples*\n\n- [Savings results / metrics from an experiment](./examples/metrics)\n\n#### 💻 *For developers*\n\n- [CHANGELOG](https://github.com/allenai/beaker-gantry/blob/main/CHANGELOG.md)\n- [CONTRIBUTING](https://github.com/allenai/beaker-gantry/blob/main/CONTRIBUTING.md)\n\n\u003c!-- begin install --\u003e\n## Installing\n\n### Installing with `pip`\n\nGantry is available [on PyPI](https://pypi.org/project/gantry/). Just run\n\n```bash\npip install beaker-gantry\n```\n\n### Installing globally with `uv`\n\nGantry can be installed and made available on the PATH using [uv](https://docs.astral.sh/uv/):\n\n```bash\nuv tool install beaker-gantry\n```\n\nWith this command, beaker-gantry is automatically installed to an isolated virtual environment.\n\n### Installing from source\n\nTo install Gantry from source, first clone [the repository](https://github.com/allenai/beaker-gantry):\n\n```bash\ngit clone https://github.com/allenai/beaker-gantry.git\ncd beaker-gantry\n```\n\nThen run\n\n```bash\npip install -e .\n```\n\u003c!-- end install --\u003e\n\u003c!-- begin quickstart --\u003e\n## Quick start\n\n### One-time setup\n\n1. **Create and clone your repository.**\n\n    If you haven't already done so, create a GitHub repository for your project and clone it locally.\n    **Every `gantry` command you run must be invoked from the root directory of your repository.**\n\n2. **Configure Gantry.**\n\n    If you've already configured the [Beaker command-line client](https://github.com/allenai/beaker/), Gantry will\n    find and use the existing configuration file (usually located at `$HOME/.beaker/config.yml`).\n    Otherwise just set the environment variable `BEAKER_TOKEN` to your Beaker [user token](https://beaker.org/user).\n\n    Some gantry settings can also be specified in a `pyproject.toml` file under the section `[tool.gantry]`. For now those settings are:\n\n    1. `workspace` - The default Beaker workspace to use.\n    2. `gh_token_secret` - The name of the Beaker secret with your GitHub API token.\n    3. `budget` - The default Beaker budget to use.\n    4. `log_level` - The (local) Python log level. Defaults to \"warning\".\n    5. `quiet` - A boolean. If true the gantry logo won't be displayed on the command line.\n\n    For example:\n\n    ```toml\n    # pyproject.toml\n    [tool.gantry]\n    workspace = \"ai2/my-default-workspace\"\n    gh_token_secret = \"GITHUB_TOKEN\"\n    budget = \"ai2/my-teams-budget\"\n    log_level = \"warning\"\n    quiet = false\n    ```\n\n    The first time you call `gantry run ...` you'll also be prompted to provide a [GitHub personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) with the `repo` scope if your repository is private. This allows Gantry to clone your private repository when it runs in Beaker. You don't have to do this just yet (Gantry will prompt you for it), but if you need to update this token later you can use the `gantry config set-gh-token` command.\n\n3. (Optional) **Specify your Python environment.**\n\n    Typically you'll have to create one of several different files to specify your Python environment. There are three widely used options:\n\n    1. A [`pyproject.toml`](https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/) or [`setup.py`](https://docs.python.org/3/distutils/introduction.html#a-simple-example) file.\n    2. A PIP [`requirements.txt`](https://pip.pypa.io/en/stable/user_guide/#requirements-files) file.\n    3. A conda [`environment.yml`](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#create-env-file-manually) file.\n\n    Gantry will automatically find and use these files to reconstruct your Python environment at runtime.\n    Alternatively you can provide a custom Python install command with the `--install` option to `gantry run`, or skip the Python setup completely with `--no-python`.\n\n### Submit your first experiment with Gantry\n\nLet's spin up a Beaker experiment that just prints \"Hello, World!\" from Python.\n\nFirst make sure you've committed *and* pushed all changes so far in your repository.\nThen (from the root of your repository) run:\n\n```bash\ngantry run --show-logs -- python -c 'print(\"Hello, World!\")'\n```\n\n*❗Note: Everything after the `--` is the command + arguments you want to run on Beaker. It's necessary to include the `--` if any of your arguments look like options themselves (like `-c` in this example) so gantry can differentiate them from its own options.*\n\nIn this case we didn't request any GPUs nor a specific cluster, so this could run on any Beaker cluster.\nWe can use the `--gpu-type` and `--gpus` options to get GPUs. For example:\n\n```bash\ngantry run --show-logs --gpu-type=h100 --gpus=1 -- python -c 'print(\"Hello, World!\")'\n```\n\nOr we can use the `--cluster` option to request clusters by their name or aliases. For example:\n\n```bash\ngantry run --show-logs --cluster=ai2/jupiter --gpus=1 -- python -c 'print(\"Hello, World!\")'\n```\n\nTry `gantry run --help` to see all of the available options.\n\u003c!-- end quickstart --\u003e\n\u003c!-- begin faq --\u003e\n## FAQ\n\n### Can I use my own Docker/Beaker image?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nYou sure can! Just set the `--beaker-image TEXT` or `--docker-image TEXT` option.\nGantry can use any image that has bash, curl, and git installed.\n\nIf your image comes with a Python environment that you want gantry to use, add the flag `--system-python`.\nFor example:\n\n```bash\ngantry run --show-logs --docker-image='python:3.10' --system-python -- python --version\n```\n\n\u003c/details\u003e\n\n### Will Gantry work for GPU experiments?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nAbsolutely! This was the main use-case Gantry was developed for. Just set the `--gpus INT` option for `gantry run` to the number of GPUs you need, and optionally `--gpu-type TEXT` (e.g. `--gpu-type=h100`).\n\u003c/details\u003e\n\n### How can I save results or metrics from an experiment?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nBy default Gantry uses the `/results` directory on the image as the location of the results dataset, which will also be set as the environment variable `RESULTS_DIR`.\nThat means that everything your experiment writes to this directory will be persisted as a Beaker dataset when the experiment finalizes.\nAnd you can also attach metrics in Beaker for your experiment by writing a JSON file called `metrics.json` to the results directory, or by calling the function `gantry.api.write_metrics()` from within your experiment.\n\u003c/details\u003e\n\n### How can I see the Beaker experiment spec that Gantry uses?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nYou can use the `--dry-run` option with `gantry run` to see what Gantry will submit without actually submitting an experiment.\nYou can also use `--save-spec PATH` in combination with `--dry-run` to save the actual experiment spec to a YAML file.\n\u003c/details\u003e\n\n### How can I update Gantry's GitHub token?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nUse the command `gantry config set-gh-token`.\n\u003c/details\u003e\n\n### How can I attach Beaker datasets to an experiment?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nUse the `--dataset` option for `gantry run`. For example:\n\n```bash\ngantry run --show-logs --dataset='petew/squad-train:/input-data' -- ls /input-data\n```\n\u003c/details\u003e\n\n### How can I attach a WEKA bucket to an experiment?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nUse the `--weka` option for `gantry run`. For example:\n\n```bash\ngantry run --show-logs --weka='oe-training-default:/mount/weka' -- ls -l /mount/weka\n```\n\u003c/details\u003e\n\n### How can I run distributed multi-node batch jobs with Gantry?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nIf you're using `torchrun` you can simply set the option `--replicas INT` along with the flag `--torchrun`.\nGantry will automatically configure your experiment and `torchrun` to run your command with all GPUs across all replicas.\n\nFor example:\n\n```bash\ngantry run \\\n  --show-logs \\\n  --gpus=8 \\\n  --gpu-type='h100' \\\n  --replicas=2 \\\n  --torchrun \\\n  --install 'uv pip install . torch numpy --torch-backend=cu129' \\\n  -- python -m gantry.all_reduce_bench\n```\n\nIn general, the three options `--replicas INT`, `--leader-selection`, `--host-networking` used together give you the ability to run distributed batch jobs. See the [Beaker docs](https://beaker-docs.apps.allenai.org/experiments/distributed-training.html#batch-jobs) for more information.\nConsider also setting `--propagate-failure`, `--propagate-preemption`, and `--synchronized-start-timeout TEXT` depending on your workload.\n\nHere's a complete example using `torchrun` manually (without the `--torchrun` flag):\n\n```bash\ngantry run \\\n  --show-logs \\\n  --gpus=8 \\\n  --gpu-type='h100' \\\n  --replicas=2 \\\n  --leader-selection \\\n  --host-networking \\\n  --propagate-failure \\\n  --propagate-preemption \\\n  --synchronized-start-timeout='5m' \\\n  --install 'uv pip install . torch numpy --torch-backend=cu129' \\\n  --exec-method=bash \\\n  -- torchrun \\\n    '--nnodes=\"$BEAKER_REPLICA_COUNT:$BEAKER_REPLICA_COUNT\"' \\\n    '--nproc-per-node=\"$BEAKER_ASSIGNED_GPU_COUNT\"' \\\n    '--rdzv-id=12347' \\\n    '--rdzv-backend=static' \\\n    '--rdzv-endpoint=\"$BEAKER_LEADER_REPLICA_HOSTNAME:29400\"' \\\n    '--node-rank=\"$BEAKER_REPLICA_RANK\"' \\\n    '--rdzv-conf=\"read_timeout=420\"' \\\n    -m gantry.all_reduce_bench\n```\n\nNote that we have environment variables like `BEAKER_REPLICA_COUNT` in the arguments to our `torchrun` command that we want to have expanded *at runtime*.\nTo accomplish this we do two things:\n1. We wrap those arguments in single quotes to avoid expanding them locally.\n2. We set `--exec-method=bash` to tell gantry to run our command and arguments with `bash -c`, which will do variable expansion.\n\nAlternatively you could put your whole `torchrun` command into a script, let's call it `launch-torchrun.sh`, without single quotes around the arguments.\nThen change your `gantry run` command like this:\n\n```diff\n gantry run \\\n   --show-logs \\\n   --gpus=8 \\\n   --gpu-type='h100' \\\n   --replicas=2 \\\n   --leader-selection \\\n   --host-networking \\\n   --propagate-failure \\\n   --propagate-preemption \\\n   --synchronized-start-timeout='5m' \\\n   --install 'uv pip install . torch numpy --torch-backend=cu129' \\\n-  --exec-method='bash' \\\n-  -- torchrun \\\n-    '--nnodes=\"$BEAKER_REPLICA_COUNT:$BEAKER_REPLICA_COUNT\"' \\\n-    '--nproc-per-node=\"$BEAKER_ASSIGNED_GPU_COUNT\"' \\\n-    '--rdzv-id=12347' \\\n-    '--rdzv-backend=static' \\\n-    '--rdzv-endpoint=\"$BEAKER_LEADER_REPLICA_HOSTNAME:29400\"' \\\n-    '--node-rank=\"$BEAKER_REPLICA_RANK\"' \\\n-    '--rdzv-conf=\"read_timeout=420\"' \\\n-    -m gantry.all_reduce_bench\n+  -- ./launch-torchrun.sh\n```\n\u003c/details\u003e\n\n### How can I customize the Python setup steps?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nIf gantry's default Python setup steps don't work for you, you can override them through the `--install TEXT` option with a custom command or shell script.\nFor example:\n\n```bash\ngantry run --show-logs --install='pip install -r custom_requirements.txt' -- echo \"Hello, World!\"\n```\n\u003c/details\u003e\n\n### Can I use conda like with older versions of gantry?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nYes, you can still use conda if you wish by committing a conda `environment.yml` file to your repo or by simply specifying `--python-manager=conda`.\nFor example:\n\n```bash\ngantry run --show-logs --python-manager=conda -- which python\n```\n\u003c/details\u003e\n\n### Can I use gantry with non-Python workloads?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nAbsolutely, just add the flag `--no-python` and optionally set `--install` or `--post-setup` to a custom command or shell script if you need custom setup steps.\n\u003c/details\u003e\n\n### Can I use gantry to launch Beaker jobs from GitHub Actions?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nYes, in fact this is a great way to utilize otherwise idle on-premise hardware, especially with short-running, preemptible jobs such as those you might launch to run unit tests that require accelerators.\nTo do this you should set up a Beaker API token as a GitHub Actions Secret, named `BEAKER_TOKEN`, in your repository.\nThen copy and modify this workflow for your needs:\n\n```yaml\nname: Beaker\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\non:\n  pull_request:\n    branches:\n      - main\n  push:\n    branches:\n      - main\n\njobs:\n  gpu_tests:\n    name: GPU Tests\n    runs-on: ubuntu-latest\n    timeout-minutes: 15\n    env:\n      BEAKER_TOKEN: ${{ secrets.BEAKER_TOKEN }}\n      GANTRY_GITHUB_TESTING: 'true'  # force better logging for CI\n      BEAKER_WORKSPACE: 'ai2/your-workspace'  # TODO: change this to your Beaker workspace\n    steps:\n      - uses: actions/checkout@v5\n        with:\n          ref: ${{ github.event.pull_request.head.sha }}  # check out PR head commit instead of merge commit\n\n      - uses: astral-sh/setup-uv@v6\n        with:\n          python-version: '3.12'\n\n      - name: install gantry\n        run:\n          uv tool install 'beaker-gantry\u003e=3.1,\u003c4.0'\n\n      - name: Determine current commit SHA (pull request)\n        if: github.event_name == 'pull_request'\n        run: |\n          echo \"COMMIT_SHA=${{ github.event.pull_request.head.sha }}\" \u003e\u003e $GITHUB_ENV\n          echo \"BRANCH_NAME=${{ github.head_ref }}\" \u003e\u003e $GITHUB_ENV\n\n      - name: Determine current commit SHA (push)\n        if: github.event_name != 'pull_request'\n        run: |\n          echo \"COMMIT_SHA=$GITHUB_SHA\" \u003e\u003e $GITHUB_ENV\n          echo \"BRANCH_NAME=${{ github.ref_name }}\" \u003e\u003e $GITHUB_ENV\n\n      - name: launch job\n        run: |\n          exec gantry run \\\n            --show-logs \\\n            --yes \\\n            --workspace ${{ env.BEAKER_WORKSPACE }} \\\n            --description 'GitHub Actions GPU tests' \\\n            --ref ${{ env.COMMIT_SHA }} \\\n            --branch ${{ env.BRANCH_NAME }} \\\n            --priority normal \\\n            --preemptible \\\n            --gpus 1 \\\n            --gpu-type h100 \\\n            --gpu-type a100 \\\n            -- pytest -v tests/cuda_tests/  # TODO: change to your own command\n```\n\nNote that we use `exec gantry run ...` instead of just `gantry run`. This ensures that if GitHub Actions cancels the job, the SIGINT and SIGTERM signals will propagate to `gantry`, allowing it to clean up gracefully and cancel the running job on Beaker.\n\u003c/details\u003e\n\n### Can I use gantry outside of a git repository?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nYes, you'll just need to provide the `--remote` option along with `--ref` and/or `--branch`.\nFor example: `gantry run --show-logs --yes --dry-run --remote allenai/beaker-gantry --branch main -- echo 'hello, world!'`\n\u003c/details\u003e\n\n### Why \"Gantry\"?\n\u003cdetails\u003e\n\u003csummary\u003eClick to expand 💬\u003c/summary\u003e\n\nA gantry is a structure that's used, among other things, to lift containers off of ships. Analogously Beaker Gantry's purpose is to lift Docker containers (or at least the *management* of Docker containers) away from users.\n\u003c/details\u003e\n\u003c!-- end faq --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallenai%2Fbeaker-gantry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallenai%2Fbeaker-gantry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallenai%2Fbeaker-gantry/lists"}