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
33 changes: 33 additions & 0 deletions src/gradient_labs/_article_topic_read.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from typing import Optional
from dataclasses import dataclass

from dataclasses_json import dataclass_json

from .topic import Topic
from ._http_client import HttpClient


@dataclass_json
@dataclass(frozen=True)
class ReadTopicParams:
"""Parameters for reading a topic."""

# support_platform specifies which platform's topic to read.
# Valid values include "public-api" and "intercom". If not provided,
# defaults to "public-api". This allows reading topics from
# different support platforms within the same organization.
support_platform: Optional[str] = None


def read_topic(
*, client: HttpClient, topic_id: str, params: Optional[ReadTopicParams] = None
) -> Topic:
"""read_topic reads an article topic by ID.

Note: requires a `Management` API key."""
query_params = {}
if params and params.support_platform:
query_params["support_platform"] = params.support_platform

response = client.get(path=f"topic/{topic_id}", query_params=query_params)
return Topic.from_dict(response)
41 changes: 41 additions & 0 deletions src/gradient_labs/_article_topics_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from typing import List, Optional
from dataclasses import dataclass

from dataclasses_json import dataclass_json

from .topic import Topic
from ._http_client import HttpClient


@dataclass_json
@dataclass(frozen=True)
class ListTopicsParams:
"""Parameters for listing topics."""

# support_platform optionally filters topics by support platform.
# Valid values include "public-api" and "intercom". If not provided,
# defaults to "public-api". This allows reading topics from
# different support platforms within the same organization.
support_platform: Optional[str] = None


@dataclass_json
@dataclass(frozen=True)
class ListTopicsResponse:
"""Response containing a list of topics."""

topics: List[Topic]


def list_topics(
*, client: HttpClient, params: Optional[ListTopicsParams] = None
) -> ListTopicsResponse:
"""list_topics lists a company's topics, optionally filtered by support platform.

Note: requires a `Management` API key."""
query_params = {}
if params and params.support_platform:
query_params["support_platform"] = params.support_platform

response = client.get(path="topics", query_params=query_params)
return ListTopicsResponse.from_dict(response)
27 changes: 27 additions & 0 deletions src/gradient_labs/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
from ._article_delete import delete_article
from ._article_set_status import set_article_usage_status, SetArticleUsageStatusParams
from ._article_topic_upsert import upsert_article_topic, ArticleTopicUpsertParams
from ._article_topic_read import read_topic, ReadTopicParams
from ._article_topics_list import list_topics, ListTopicsParams, ListTopicsResponse
from ._article_upsert import upsert_article, UpsertArticleParams

from .topic import Topic

from .conversation import Conversation
from ._conversation_add_message import add_message, AddMessageParams, Message
from ._conversation_assign import assign_conversation, AssignmentParams
Expand Down Expand Up @@ -125,6 +129,29 @@ def upsert_article(self, *, params: UpsertArticleParams) -> None:
params=params,
)

def list_topics(
self, *, params: Optional[ListTopicsParams] = None
) -> ListTopicsResponse:
"""list_topics lists a company's topics, optionally filtered by support platform.

Note: requires a `Management` API key."""
return list_topics(
client=self.http_client,
params=params,
)

def read_topic(
self, *, topic_id: str, params: Optional[ReadTopicParams] = None
) -> Topic:
"""read_topic reads an article topic by ID.

Note: requires a `Management` API key."""
return read_topic(
client=self.http_client,
topic_id=topic_id,
params=params,
)

def assign_conversation(
self,
*,
Expand Down
46 changes: 46 additions & 0 deletions src/gradient_labs/topic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from dataclasses import dataclass
from datetime import datetime
from typing import Optional, Any

from dataclasses_json import dataclass_json

from .article import Visibility


@dataclass_json
@dataclass(frozen=True)
class Topic:
"""Topic represents an article topic for categorizing help articles."""

# source identifies the CRM or support platform that the topic comes from
source: str

# external_id identifies this topic in the Source
external_id: str

# name is the human-readable name for this topic
name: str

# visibility describes who can see the topic
visibility: Visibility

# created is when the topic was created in the source
created: datetime

# last_edited is when the topic was last changed in the source
last_edited: datetime

# last_seen is the last time we saw this topic when crawling
last_seen: datetime

# data is a raw representation of the topic from the support platform
data: Any

# description is the optional subtext for the topic
description: Optional[str] = None

# parent_external_id identifies the topic that this topic is nested under
parent_external_id: Optional[str] = None

# public_url optionally points to the public resource for this topic
public_url: Optional[str] = None