Implementation:Treeverse LakeFS CreateTag For Import
| 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-15orimport-v1.0are easier to reference than commit hashes. - Optional force overwrite -- The
forceflag 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
forceis 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}\"
}"