Skip to content

Commit 4ff33a1

Browse files
committed
fix: Handle null citation fields in Pydantic models and update API key prefix validation.
1 parent ec74ae3 commit 4ff33a1

4 files changed

Lines changed: 33 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.1.5] - 2025-12-12
9+
10+
### Fixed
11+
12+
- Fixed Pydantic validation errors when `citations.pages` or `citations.metadata` are returned as `null` from the API
13+
14+
## [0.1.4] - 2025-12-12
15+
16+
### Changed
17+
18+
- Updated API key prefix validation from `sk_live_` to `brainus_` to match backend changes
19+
820
## [0.1.3] - 2025-12-12
921

1022
### Changed
@@ -37,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3749
- Full type hints with Pydantic models
3850
- Async/await support
3951

52+
[0.1.4]: https://github.com/BrainUsLK/brainus-ai-python/compare/v0.1.3...v0.1.4
4053
[0.1.3]: https://github.com/BrainUsLK/brainus-ai-python/compare/v0.1.2...v0.1.3
4154
[0.1.2]: https://github.com/BrainUsLK/brainus-ai-python/compare/v0.1.1...v0.1.2
4255
[0.1.1]: https://github.com/BrainUsLK/brainus-ai-python/compare/v0.1.0...v0.1.1

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "brainus-ai"
7-
version = "0.1.3"
7+
version = "0.1.5"
88
description = "Official Python SDK for Brainus AI - RAG-powered educational content API"
99
readme = "README.md"
1010
license = {text = "MIT"}

src/brainus_ai/client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class BrainusAI:
2020
2121
Example:
2222
>>> from brainus_ai import BrainusAI
23-
>>> client = BrainusAI(api_key="sk_live_...")
23+
>>> client = BrainusAI(api_key="brainus_...")
2424
>>> response = await client.query(
2525
... query="What is Python?",
2626
... store_id="abc123" # Optional - uses default if not provided
@@ -39,13 +39,13 @@ def __init__(
3939
Initialize the Brainus AI client.
4040
4141
Args:
42-
api_key: Your Brainus AI API key (sk_live_...)
42+
api_key: Your Brainus AI API key (brainus_...)
4343
base_url: Base URL for the API (default: production gateway)
4444
timeout: Request timeout in seconds
4545
max_retries: Maximum number of retry attempts for failed requests
4646
"""
47-
if not api_key or not api_key.startswith("sk_live_"):
48-
raise ValueError("Invalid API key format. Expected format: sk_live_...")
47+
if not api_key or not api_key.startswith("brainus_"):
48+
raise ValueError("Invalid API key format. Expected format: brainus_...")
4949

5050
self.api_key = api_key
5151
self.base_url = base_url.rstrip("/")

src/brainus_ai/models.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Data models for the Brainus AI SDK."""
22

33
from typing import Any, Optional
4-
from pydantic import BaseModel, Field
4+
from pydantic import BaseModel, Field, field_validator
55

66

77
class Citation(BaseModel):
@@ -13,6 +13,20 @@ class Citation(BaseModel):
1313
metadata: dict[str, Any] = Field(default_factory=dict, description="Document metadata")
1414
chunk_text: Optional[str] = Field(None, description="Relevant text chunk")
1515

16+
@field_validator("pages", mode="before")
17+
@classmethod
18+
def validate_pages(cls, v: Any) -> Any:
19+
if v is None:
20+
return []
21+
return v
22+
23+
@field_validator("metadata", mode="before")
24+
@classmethod
25+
def validate_metadata(cls, v: Any) -> Any:
26+
if v is None:
27+
return {}
28+
return v
29+
1630

1731
class QueryFilters(BaseModel):
1832
"""Metadata filters for query."""

0 commit comments

Comments
 (0)