Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions decart/tokens/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class TokensClient:
```python
client = DecartClient(api_key=os.getenv("DECART_API_KEY"))
token = await client.tokens.create()
# Returns: CreateTokenResponse(api_key="ek_...", expires_at="...")
# Returns: CreateTokenResponse(api_key="ek_...", token="eyJhbGciOiJFZERTQS...", expires_at="...")

# With metadata:
token = await client.tokens.create(metadata={"role": "viewer"})
Expand Down Expand Up @@ -71,7 +71,7 @@ async def create(
Example:
```python
token = await client.tokens.create()
# Returns: CreateTokenResponse(api_key="ek_...", expires_at="...")
# Returns: CreateTokenResponse(api_key="ek_...", token="eyJhbGciOiJFZERTQS...", expires_at="...")

# With all options:
token = await client.tokens.create(
Expand Down Expand Up @@ -120,6 +120,7 @@ async def create(
data = await response.json()
return CreateTokenResponse(
api_key=data["apiKey"],
token=data.get("token"),
expires_at=data["expiresAt"],
permissions=data.get("permissions"),
constraints=data.get("constraints"),
Expand Down
2 changes: 2 additions & 0 deletions decart/tokens/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class CreateTokenResponse(BaseModel):
"""Response from creating a client token."""

api_key: str
token: str | None = None
"""Signed JWT mirroring ``api_key``, verifiable offline via the public JWKS."""
expires_at: str
permissions: TokenPermissions | None = None
constraints: TokenConstraints | None = None
1 change: 1 addition & 0 deletions examples/create_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ async def main() -> None:

print("Token created successfully:")
print(f" API Key: {token.api_key[:10]}...")
print(f" JWT: {f'{token.token[:16]}...' if token.token else '(not issued)'}")
print(f" Expires At: {token.expires_at}")
origins = (token.permissions or {}).get("origins")
print(f" Allowed Origins: {', '.join(origins) if origins else '(any)'}")
Expand Down
3 changes: 3 additions & 0 deletions tests/test_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ async def test_create_token() -> None:
result = await client.tokens.create()

assert result.api_key == "ek_test123"
assert result.token is None
assert result.expires_at == "2024-12-15T12:10:00Z"
assert result.permissions is None
assert result.constraints is None
Expand Down Expand Up @@ -225,6 +226,7 @@ async def test_create_token_with_all_v2_fields() -> None:
mock_response.json = AsyncMock(
return_value={
"apiKey": "ek_test123",
"token": "eyJhbGciOiJFZERTQS123",
"expiresAt": "2024-12-15T12:10:00Z",
"permissions": {
"models": ["lucy-2.1"],
Expand All @@ -249,6 +251,7 @@ async def test_create_token_with_all_v2_fields() -> None:
)

assert result.api_key == "ek_test123"
assert result.token == "eyJhbGciOiJFZERTQS123"
assert result.expires_at == "2024-12-15T12:10:00Z"
assert result.permissions == {
"models": ["lucy-2.1"],
Expand Down
Loading