Skip to content

feat(templates): template list pagination via GET /v2/templates#1479

Open
huv1k wants to merge 22 commits into
mainfrom
templates-list-pagination-for-cli-en-603
Open

feat(templates): template list pagination via GET /v2/templates#1479
huv1k wants to merge 22 commits into
mainfrom
templates-list-pagination-for-cli-en-603

Conversation

@huv1k

@huv1k huv1k commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

Adds support for listing templates with pagination via the new GET /v2/templates endpoint (added to spec/openapi.yml; clients regenerated). The JS and Python SDKs gain a Template.list() paginator that yields TemplateInfo and is built on the shared paginator base from #1491 (Paginator in JS, PaginatorBase in Python), mirroring Sandbox.list(). The CLI's e2b template list pages through results behind a -l, --limit option (default 1000, 100 per page, 0 for no limit) with a "Showing first N…" hint — aligned with e2b sandbox list. Pagination uses the limit/nextToken query params and the X-Next-Token response header. The API key is team-scoped, so listing takes no team identifier.

What's included

  • Spec/codegen: GET /v2/templates (limit + nextToken, Template[]), regenerated JS + Python clients.
  • JS SDK (e2b): Template.list()TemplatePaginator (hasNext / nextItems()) returning TemplateInfo. Lives in src/template/templateApi.ts and depends only on shared infra (Paginator, ConnectionOpts).
  • Python SDK (@e2b/python-sdk): Template.list() / AsyncTemplate.list()TemplatePaginator / AsyncTemplatePaginator returning TemplateInfo, living in the template package (e2b/template/template_api.py, e2b/template_{sync,async}/paginator.py) and built on the shared PaginatorBase.
  • CLI (@e2b/cli): e2b template list pagination matching sandbox list; the delete/publish --select flows consume the same helper.
  • Tests: integration tests (no mocks) for JS, CLI, and Python sync + async — they build a template and assert it shows up via Template.list() against the live API.
  • Changeset: minor bump for e2b, @e2b/python-sdk, @e2b/cli.

Usage

CLI:

e2b template list                 # up to 1000 templates (100 per page)
e2b template list --limit 20      # cap at 20; prints "Showing first 20… Use --limit to change."
e2b template list --limit 0 -f json   # no cap, JSON output

JS SDK:

import { Template } from 'e2b'

const paginator = Template.list({ limit: 100 })
while (paginator.hasNext) {
  const templates = await paginator.nextItems()
  console.log(templates)
}

Python SDK:

from e2b import Template  # or AsyncTemplate

paginator = Template.list(limit=100)
while paginator.has_next:
    for template in paginator.next_items():
        print(template.template_id)

Notes

  • TemplatePaginator.nextItems() returns [] when exhausted (the sandbox/snapshot paginators still throw — to be unified separately).
  • Resolves EN-603.

Add a paginated `GET /v2/templates` endpoint to the spec and expose it
across all packages:

- JS SDK: `Template.list()` -> `TemplatePaginator` returning `TemplateInfo`,
  matching `Sandbox.list()`.
- Python SDK: `Template.list()` / `AsyncTemplate.list()` ->
  `TemplatePaginator` / `AsyncTemplatePaginator` (sync + async).
- CLI: `e2b template list` pages through templates via the SDK paginator
  and adds a `-l, --limit` option (default 1000, 0 for no limit).

Pagination uses `limit`/`nextToken` query params and the `X-Next-Token`
response header, consistent with `sandbox list`.
@linear-code

linear-code Bot commented Jun 24, 2026

Copy link
Copy Markdown

EN-603

@cla-bot cla-bot Bot added the cla-signed label Jun 24, 2026
@changeset-bot

changeset-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d6c9939

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@e2b/python-sdk Minor
e2b Minor
@e2b/cli Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Package Artifacts

Built from 1cb1172. Download artifacts from this workflow run.

JS SDK (e2b@2.31.1-templates-list-pagination-for-cli-en-603.0):

npm install ./e2b-2.31.1-templates-list-pagination-for-cli-en-603.0.tgz

CLI (@e2b/cli@2.13.1-templates-list-pagination-for-cli-en-603.0):

npm install ./e2b-cli-2.13.1-templates-list-pagination-for-cli-en-603.0.tgz

Python SDK (e2b==2.30.0+templates-list-pagination-for-cli-en-603):

pip install ./e2b-2.30.0+templates.list.pagination.for.cli.en.603-py3-none-any.whl

@huv1k huv1k marked this pull request as ready for review June 24, 2026 13:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 760d988327

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/cli/src/commands/template/list.ts Outdated
Template.list builds its own ConnectionConfig, so passing only teamId/limit
left config-file logins (e2b auth login) unauthenticated. Resolve the API key
via ensureAPIKey() and pass it to the paginator, mirroring sandbox list. This
also fixes the delete/publish --select flows.
Comment thread packages/cli/src/commands/template/list.ts Outdated

@mishushakov mishushakov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

move template method to template and shared classes to utils

Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
Comment thread packages/python-sdk/e2b/sandbox_async/paginator.py Outdated
Comment thread packages/python-sdk/e2b/sandbox_sync/paginator.py
Comment thread packages/python-sdk/e2b/template_async/main.py Outdated
Comment thread packages/python-sdk/e2b/__init__.py Outdated
Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
@mishushakov

Copy link
Copy Markdown
Member

also, no tests for the Python SDKs?

@mishushakov mishushakov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

more CLI feedback

Comment thread packages/cli/src/commands/template/list.ts Outdated
Comment thread packages/js-sdk/tests/template/list.test.ts
Comment thread packages/cli/tests/commands/template/list.test.ts
Comment thread packages/cli/src/commands/template/list.ts Outdated
Comment thread packages/cli/src/commands/template/list.ts Outdated
Comment thread packages/cli/src/commands/template/list.ts Outdated
@huv1k huv1k marked this pull request as draft June 26, 2026 13:24
huv1k added 13 commits June 26, 2026 16:07
…tion-for-cli-en-603

# Conflicts:
#	packages/js-sdk/src/sandbox/sandboxApi.ts
#	packages/python-sdk/e2b/sandbox/sandbox_api.py
The API key is team-scoped, so listing templates never needs a team
identifier. Remove teamId/team_id from Template.list (JS + Python sync/async),
the TemplatePaginator(Base), and the /v2/templates query, and drop the now-dead
--team option from `template list/delete/publish`.
…ator is exhausted

Per review: template paginator nextItems/next_items now returns [] when there
are no more items, rather than raising. Sandbox/snapshot paginators still throw;
noted in comments that they'll be aligned to this behaviour.
Per review: remove the "Showing first N templates" hint. listSandboxTemplates
now returns the template array directly instead of { templates, hasMore }; the
delete/publish select flows and tests are updated accordingly.
…tests

Per review (no mocks): the JS SDK test now builds a real template and asserts it
appears via Template.list() against the live /v2/templates endpoint (and cleans
it up); the CLI test runs the built CLI's `template list -f json` against the
real API and validates the returned templates.
templateApi no longer imports SandboxApiOpts from the sandbox module. It uses
the shared ConnectionOpts (already used by Template.build/exists/getTags), so
the template SDK only depends on shared infra (Paginator, ConnectionOpts), not
sandbox internals.
…mplateInfo

Per review: destructure only the fields that need renaming (templateID/buildID)
or date conversion (createdAt/updatedAt/lastSpawnedAt) and spread the rest,
instead of copying every field by hand.
Align Python with the TypeScript layout: template code no longer lives in the
sandbox modules.

- TemplateInfo -> e2b/template/template_api.py (mirrors templateApi.ts)
- TemplatePaginator -> e2b/template_sync/paginator.py
- AsyncTemplatePaginator -> e2b/template_async/paginator.py
- both extend the shared PaginatorBase directly (drop the redundant
  TemplatePaginatorBase), return [] when exhausted, and raise TemplateException
- template_sync/async main + e2b/__init__ import from the template modules; no
  sandbox imports remain in the template SDK
Per review: the CLI now fetches the whole list (auto-paginating every page),
since output is commonly piped into other tools and there's no good way to
paginate from the CLI yet. Removes the --limit option and the page/limit
bookkeeping.
Per review: build a real template and assert it appears via Template.list() /
AsyncTemplate.list() against the live /v2/templates endpoint, verify the
TemplateInfo shape and that an exhausted paginator returns [], then clean up.
Mirror `sandbox list` for now: re-add the -l, --limit option (default 1000,
100 per page, 0 = no limit), cap the auto-pagination at the limit, and print
the "Showing first N templates. Use --limit to change." hint when more exist.
The SDK paginator still returns [] when exhausted.
huv1k added 2 commits June 30, 2026 17:19
GET /v2/templates returns buildID as a zero UUID right after building (it's the
last *successful* build id, distinct from the just-triggered build), so the
integration tests now just assert buildId is a string. Fixes the failing JS and
Python SDK integration tests.
@huv1k huv1k requested a review from mishushakov July 1, 2026 09:49
@huv1k huv1k marked this pull request as ready for review July 1, 2026 09:49
Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
Comment thread packages/python-sdk/e2b/template/template_api.py Outdated
huv1k added 2 commits July 1, 2026 12:26
The paginators fell back to the default Sandbox error on HTTP failure. Pass
TemplateError (JS) / TemplateException (Python) to handleApiError /
handle_api_exception, matching the other template ops and the paginator's own
parsed-body error branch. Also mark TemplateInfo.aliases deprecated in the
Python SDK (use names), mirroring the JS SDK and the OpenAPI spec.
…tion-for-cli-en-603

# Conflicts:
#	packages/js-sdk/src/template/index.ts
Comment thread packages/python-sdk/e2b/template/template_api.py Outdated
Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
Comment thread packages/js-sdk/src/template/templateApi.ts Outdated
Comment thread packages/cli/src/commands/template/list.ts
Comment thread packages/cli/src/commands/template/list.ts Outdated
Comment thread packages/cli/src/commands/template/list.ts Outdated
huv1k added 2 commits July 2, 2026 15:56
…dules

Address latest review:
- JS: move TemplateInfo/TemplateListOpts into template/types.ts and
  TemplatePaginator into template/paginator.ts; delete templateApi.ts.
- Python: move TemplateInfo into template/types.py; delete template_api.py.
- CLI: simplify toTemplateSchema (spread, convert only date fields) and drop
  the 'Showing first N' hint (keep --limit).
Change the -l, --limit default from 1000 to 0 (no limit) so `e2b template list`
returns the whole list by default; pass --limit N to cap.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants