Skip to content

Commit 3c2aa68

Browse files
authored
feat: add fields to topic list, version, timestamp, certificate (#4)
1 parent 81aeca9 commit 3c2aa68

File tree

2 files changed

+323
-8
lines changed

2 files changed

+323
-8
lines changed

openproficiency/TopicList.py

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""TopicList module for OpenProficiency library."""
22

33
import json
4+
import re
5+
from datetime import datetime, timezone
46
from typing import Dict, Any, Union, List, cast
57
from .Topic import Topic
68

@@ -14,7 +16,10 @@ def __init__(
1416
owner: str,
1517
name: str,
1618
# Optional
17-
description: str = "",
19+
description: Union[str, None] = None,
20+
version: Union[str, None] = None,
21+
timestamp: Union[str, None] = None,
22+
certificate: Union[str, None] = None,
1823
):
1924
# Required
2025
self.owner = owner
@@ -25,6 +30,18 @@ def __init__(
2530
self.topics: Dict[str, Topic] = {}
2631
self.dependencies: Dict[str, "TopicList"] = {}
2732

33+
# Set version with validation
34+
self.version = version
35+
36+
# Set timestamp (convert string to datetime, default to current UTC if not provided)
37+
if timestamp is None:
38+
self._timestamp = datetime.now(timezone.utc)
39+
else:
40+
self._timestamp = datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
41+
42+
# Set certificate
43+
self.certificate = certificate
44+
2845
# Methods
2946
def add_topic(self, topic: Union[str, Topic]) -> Topic:
3047
"""
@@ -44,6 +61,33 @@ def get_topic(self, topic_id: str) -> Union[Topic, None]:
4461
return self.topics.get(topic_id, None)
4562

4663
# Properties
64+
@property
65+
def version(self) -> Union[str, None]:
66+
"""Get the semantic version of the TopicList."""
67+
return self._version
68+
69+
@version.setter
70+
def version(self, value: Union[str, None]) -> None:
71+
"""Set the semantic version with X.Y.Z format validation."""
72+
if value is not None and not re.match(r"^\d+\.\d+\.\d+$", value):
73+
raise ValueError(f"Invalid version format: '{value}'. Must be semantic versioning (X.Y.Z)")
74+
self._version = value
75+
76+
@property
77+
def timestamp(self) -> datetime:
78+
"""Get the timestamp as a datetime object."""
79+
return self._timestamp
80+
81+
@timestamp.setter
82+
def timestamp(self, value: Union[str, datetime, None]) -> None:
83+
"""Set the timestamp from a string or datetime object."""
84+
if value is None:
85+
self._timestamp = datetime.now(timezone.utc)
86+
elif isinstance(value, str):
87+
self._timestamp = datetime.fromisoformat(value.replace("Z", "+00:00"))
88+
else:
89+
self._timestamp = value
90+
4791
@property
4892
def full_name(self) -> str:
4993
"""Get the full name of the TopicList in 'owner/name' format."""
@@ -74,7 +118,10 @@ def from_json(cls, json_data: str) -> "TopicList":
74118
topic_list = TopicList(
75119
owner=data.get("owner", ""),
76120
name=data.get("name", ""),
77-
description=data.get("description", ""),
121+
description=data.get("description"),
122+
version=data.get("version"),
123+
timestamp=data.get("timestamp"),
124+
certificate=data.get("certificate"),
78125
)
79126

80127
# Add each topic
@@ -211,10 +258,22 @@ def to_dict(self) -> Dict[str, Any]:
211258
data: Dict[str, Any] = {
212259
"owner": self.owner,
213260
"name": self.name,
214-
"description": self.description,
261+
"timestamp": self.timestamp.isoformat(),
215262
"topics": {},
216263
}
217264

265+
# Add description if set
266+
if self.description is not None:
267+
data["description"] = self.description
268+
269+
# Add version if set
270+
if self.version is not None:
271+
data["version"] = self.version
272+
273+
# Add certificate if set
274+
if self.certificate is not None:
275+
data["certificate"] = self.certificate
276+
218277
# Add each topic
219278
for topic_id, topic in self.topics.items():
220279
# Create topic

0 commit comments

Comments
 (0)