Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Treeverse LakeFS CreateTag For Import

From Leeroopedia


Knowledge Sources
Domains Data_Import, REST_API
Last Updated 2026-02-08 00:00 GMT

Overview

Concrete API endpoint for creating immutable tags on import commits to mark data milestones, provided by the lakeFS REST API.

Description

The createTag endpoint creates a named, immutable reference (tag) pointing to a specific commit in a lakeFS repository. When used in the context of import workflows, this endpoint is called after a successful import to assign a descriptive, human-readable name to the import commit.

Key characteristics:

  • Immutability -- Once created, a tag always resolves to the same commit. This guarantees that any system referencing the tag will see the same data state.
  • Human-readable naming -- Tags like import-2024-01-15 or import-v1.0 are easier to reference than commit hashes.
  • Optional force overwrite -- The force flag allows overwriting an existing tag (default: false). In most import workflows, this should remain false to maintain immutability.
  • Conflict detection -- If a tag with the given name already exists and force is false, the API returns 409 Conflict.

This implementation focuses specifically on the import tagging angle of the general-purpose createTag API: tagging import commits with descriptive names for traceability and rollback.

Usage

Use this endpoint when:

  • Creating a permanent reference to an import commit after successful import completion and verification
  • Implementing automated tagging in import pipelines (e.g., Airflow DAGs that tag each daily import)
  • Marking pre-import baselines for rollback purposes
  • Publishing named data versions for downstream consumers

Code Reference

Source Location

  • Repository: lakeFS
  • File: api/swagger.yml (lines 3999-4031)
  • Schema: api/swagger.yml (lines 772-787)

Signature

/repositories/{repository}/tags:
  post:
    tags:
      - tags
    operationId: createTag
    summary: create tag
    requestBody:
      required: true
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TagCreation"
    responses:
      201:
        description: tag
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Ref"
      400:
        $ref: "#/components/responses/ValidationError"
      401:
        $ref: "#/components/responses/Unauthorized"
      403:
        $ref: "#/components/responses/Forbidden"
      404:
        $ref: "#/components/responses/NotFound"
      409:
        $ref: "#/components/responses/Conflict"

TagCreation:
  type: object
  description: Make tag ID point at this REF.
  required:
    - id
    - ref
  properties:
    id:
      type: string
      description: ID of tag to create
    ref:
      type: string
      description: the commit to tag
    force:
      type: boolean
      default: false

Import

import lakefs

client = lakefs.Client(
    host="http://localhost:8000",
    username="access_key",
    password="secret_key"
)
repo = lakefs.Repository("my-repo", client=client)

I/O Contract

Inputs

Name Type Required Description
repository string (path) Yes Repository name
id string (body) Yes Tag name to create. Descriptive names are recommended (e.g., import-v1.0, import-2024-01-15).
ref string (body) Yes The commit ID to tag. For import workflows, this is the commit ID from the ImportStatus.commit.id field returned upon import completion.
force boolean (body) No If true, overwrite an existing tag with the same name (default: false). Use with caution in import workflows.

Outputs

Name Type Description
id string The commit ID that the tag now points to

HTTP Status Codes:

Code Description
201 Tag created successfully -- returns a Ref object with the commit ID
400 Validation error -- invalid tag name or ref
401 Unauthorized -- missing or invalid credentials
403 Forbidden -- insufficient permissions
404 Not found -- repository or referenced commit does not exist
409 Conflict -- a tag with this name already exists (and force is false)
429 Too many requests -- rate limited

Usage Examples

Tag an Import Commit with curl

# After import completes, tag the resulting commit
REPO="my-repo"
COMMIT_ID="a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"

curl -X POST \
  "http://localhost:8000/api/v1/repositories/${REPO}/tags" \
  -H "Content-Type: application/json" \
  -u "access_key:secret_key" \
  -d "{
    \"id\": \"import-2024-01-15\",
    \"ref\": \"${COMMIT_ID}\"
  }"

# Response (HTTP 201):
# {
#   "id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
# }

Full Import-Then-Tag Workflow in Python

import requests
import time
from datetime import date

LAKEFS_URL = "http://localhost:8000/api/v1"
AUTH = ("access_key", "secret_key")
REPO = "my-repo"
BRANCH = "main"

# Step 1: Start import
import_resp = requests.post(
    f"{LAKEFS_URL}/repositories/{REPO}/branches/{BRANCH}/import",
    json={
        "paths": [
            {
                "type": "common_prefix",
                "path": "s3://my-bucket/production/collections/",
                "destination": "collections/"
            }
        ],
        "commit": {
            "message": "Import production collections"
        }
    },
    auth=AUTH,
)
import_resp.raise_for_status()
import_id = import_resp.json()["id"]

# Step 2: Poll for completion
while True:
    time.sleep(2)
    status_resp = requests.get(
        f"{LAKEFS_URL}/repositories/{REPO}/branches/{BRANCH}/import",
        params={"id": import_id},
        auth=AUTH,
    )
    status_resp.raise_for_status()
    status = status_resp.json()

    if status.get("error"):
        raise RuntimeError(f"Import failed: {status['error']}")
    if status["completed"]:
        commit_id = status["commit"]["id"]
        print(f"Import completed. Commit: {commit_id}")
        break

# Step 3: Tag the import commit
today = date.today().isoformat()
tag_name = f"import-{today}"

tag_resp = requests.post(
    f"{LAKEFS_URL}/repositories/{REPO}/tags",
    json={
        "id": tag_name,
        "ref": commit_id
    },
    auth=AUTH,
)
tag_resp.raise_for_status()
print(f"Tagged import commit as: {tag_name}")

Tag with Version Numbering

# Create a versioned tag for a dataset release
curl -X POST \
  "http://localhost:8000/api/v1/repositories/my-repo/tags" \
  -H "Content-Type: application/json" \
  -u "access_key:secret_key" \
  -d '{
    "id": "import-v1.0",
    "ref": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
  }'

# Later, after another import, create a new version tag
curl -X POST \
  "http://localhost:8000/api/v1/repositories/my-repo/tags" \
  -H "Content-Type: application/json" \
  -u "access_key:secret_key" \
  -d '{
    "id": "import-v1.1",
    "ref": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0a1"
  }'

Pre-Import Baseline Tag

# Before running an import, tag the current branch head as a rollback point
REPO="my-repo"
BRANCH="main"

# Get current branch head commit
HEAD_COMMIT=$(curl -s \
  "http://localhost:8000/api/v1/repositories/${REPO}/branches/${BRANCH}" \
  -u "access_key:secret_key" | jq -r '.commit_id')

# Tag it as a pre-import baseline
curl -X POST \
  "http://localhost:8000/api/v1/repositories/${REPO}/tags" \
  -H "Content-Type: application/json" \
  -u "access_key:secret_key" \
  -d "{
    \"id\": \"pre-import-2024-01-15\",
    \"ref\": \"${HEAD_COMMIT}\"
  }"

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment