Skip to content

Commit

Permalink
docs: Add README explaining logid usage (#150)
Browse files Browse the repository at this point in the history
  • Loading branch information
chyroc authored Dec 25, 2024
1 parent cdeb532 commit fde9d4e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 31 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,31 @@ coze = Coze(auth=TokenAuth(oauth_token.access_token))
oauth_token = device_oauth_app.refresh_access_token(oauth_token.refresh_token)
```

### Debug

The SDK support returning the logid of the request, which can be used to debug the request.
You can get the logid from the response of the request and submit it to the coze support team for further assistance.

```python
import os
from cozepy import Coze, AsyncCoze, TokenAuth

coze = Coze(auth=TokenAuth(os.getenv("COZE_API_TOKEN")))

bot = coze.bots.retrieve(bot_id='bot id')
print(bot.response.logid) # support for CozeModel

stream = coze.chat.stream(bot_id='bot id', user_id='user id')
print(stream.response.logid) # support for stream

workspaces = coze.workspaces.list()
print(workspaces.response.logid) # support for paged

messages = coze.chat.messages.list(conversation_id='conversation id', chat_id='chat id')
print(messages.response.logid) # support for list(simple list, not paged)
```


### Async usage

cozepy supports asynchronous calls through `httpx.AsyncClient`.
Expand Down
28 changes: 18 additions & 10 deletions cozepy/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,18 +583,22 @@ def _check_has_more(self, has_more: Optional[bool] = None, last_id: Optional[str
return False


class Stream(Generic[T], HTTPResponse):
class Stream(Generic[T]):
def __init__(
self,
raw_response: httpx.Response,
iters: Iterator[str],
fields: List[str],
handler: Callable[[Dict[str, str], httpx.Response], T],
):
super().__init__(raw_response)
self._iters = iters
self._fields = fields
self._handler = handler
self._raw_response = raw_response

@property
def response(self) -> HTTPResponse:
return HTTPResponse(self._raw_response)

def __iter__(self):
return self
Expand All @@ -611,7 +615,7 @@ def _extra_event(self) -> Dict[str, str]:
if line == "":
continue

log_debug("receive event, logid=%s, event=%s", self.logid, line)
log_debug("receive event, logid=%s, event=%s", self.response.logid, line)

field, value = self._extra_field_data(line, data)
data[field] = value
Expand All @@ -624,23 +628,27 @@ def _extra_field_data(self, line: str, data: Dict[str, str]) -> Tuple[str, str]:
if data[field] == "":
return field, line[len(field) + 1 :].strip()
else:
raise CozeInvalidEventError(field, line, self.logid)
raise CozeInvalidEventError("", line, self.logid)
raise CozeInvalidEventError(field, line, self.response.logid)
raise CozeInvalidEventError("", line, self.response.logid)


class AsyncStream(Generic[T], HTTPResponse):
class AsyncStream(Generic[T]):
def __init__(
self,
iters: AsyncIterator[str],
fields: List[str],
handler: Callable[[Dict[str, str], httpx.Response], T],
raw_response: httpx.Response,
):
super().__init__(raw_response)
self._iters = iters
self._fields = fields
self._handler = handler
self._iterator = self.__stream__()
self._raw_response = raw_response

@property
def response(self) -> HTTPResponse:
return HTTPResponse(self._raw_response)

async def __aiter__(self) -> AsyncIterator[T]:
async for item in self._iterator:
Expand All @@ -658,7 +666,7 @@ async def __stream__(self) -> AsyncIterator[T]:
if line == "":
continue

log_debug("async receive event, logid=%s, event=%s", self.logid, line)
log_debug("async receive event, logid=%s, event=%s", self.response.logid, line)

field, value = self._extra_field_data(line, data)
data[field] = value
Expand All @@ -678,8 +686,8 @@ def _extra_field_data(self, line: str, data: Dict[str, str]) -> Tuple[str, str]:
if data[field] == "":
return field, line[len(field) + 1 :].strip()
else:
raise CozeInvalidEventError(field, line, self.logid)
raise CozeInvalidEventError("", line, self.logid)
raise CozeInvalidEventError(field, line, self.response.logid)
raise CozeInvalidEventError("", line, self.response.logid)

def _make_data(self):
return dict(map(lambda x: (x, ""), self._fields))
22 changes: 11 additions & 11 deletions tests/test_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def test_sync_chat_stream(self, respx_mock):
stream = coze.chat.stream(bot_id="bot", user_id="user")

assert stream
assert stream.logid == mock_logid
assert stream.response.logid == mock_logid

events = list(stream)
assert len(events) == 8
Expand Down Expand Up @@ -211,8 +211,8 @@ def test_sync_chat_audio_stream(self, respx_mock):
],
)
assert stream
assert stream.logid is not None
assert stream.logid == mock_logid
assert stream.response.logid is not None
assert stream.response.logid == mock_logid

events = list(stream)
assert events
Expand All @@ -229,8 +229,8 @@ def test_sync_chat_stream_error(self, respx_mock):
mock_logid = mock_chat_stream(respx_mock, read_file("testdata/chat_error_resp.txt"))
stream = coze.chat.stream(bot_id="bot", user_id="user")
assert stream
assert stream.logid is not None
assert stream.logid == mock_logid
assert stream.response.logid is not None
assert stream.response.logid == mock_logid

with pytest.raises(Exception, match="error event"):
list(stream)
Expand All @@ -241,8 +241,8 @@ def test_sync_chat_stream_failed(self, respx_mock):
mock_logid = mock_chat_stream(respx_mock, read_file("testdata/chat_failed_resp.txt"))
stream = coze.chat.stream(bot_id="bot", user_id="user")
assert stream
assert stream.logid is not None
assert stream.logid == mock_logid
assert stream.response.logid is not None
assert stream.response.logid == mock_logid

events = list(stream)
assert events
Expand All @@ -256,8 +256,8 @@ def test_sync_chat_stream_invalid_event(self, respx_mock):

stream = coze.chat.stream(bot_id="bot", user_id="user")
assert stream
assert stream.logid is not None
assert stream.logid == mock_logid
assert stream.response.logid is not None
assert stream.response.logid == mock_logid

with pytest.raises(Exception, match="invalid chat.event: invalid"):
list(stream)
Expand Down Expand Up @@ -296,8 +296,8 @@ def test_sync_submit_tool_outputs_stream(self, respx_mock):
conversation_id="conversation", chat_id="chat", tool_outputs=[], stream=True
)
assert stream
assert stream.logid is not None
assert stream.logid == mock_logid
assert stream.response.logid is not None
assert stream.response.logid == mock_logid

events = list(stream)
assert events
Expand Down
6 changes: 3 additions & 3 deletions tests/test_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def test_sync_workflows_runs_stream(self, respx_mock):

mock_logid = mock_create_workflows_runs_stream(respx_mock, read_file("testdata/workflow_run_stream_resp.txt"))
stream = coze.workflows.runs.stream(workflow_id="id")
assert stream.logid == mock_logid
assert stream.response.logid == mock_logid
events = list(stream)
assert events
assert len(events) == 9
Expand All @@ -131,7 +131,7 @@ def test_sync_workflows_runs_resume(self, respx_mock):
resume_data="resume_data",
interrupt_type=123,
)
assert stream.logid == mock_logid
assert stream.response.logid == mock_logid
events = list(stream)
assert events
assert len(events) == 9
Expand All @@ -148,7 +148,7 @@ def test_sync_workflows_runs_invalid_stream_event(self, respx_mock):
resume_data="resume_data",
interrupt_type=123,
)
assert stream.logid == mock_logid
assert stream.response.logid == mock_logid
with pytest.raises(Exception, match="invalid workflows.event: invalid"):
list(stream)

Expand Down
14 changes: 7 additions & 7 deletions tests/test_workflows_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_sync_workflows_chat_stream(self, respx_mock):
stream = coze.workflows.chat.stream(workflow_id="workflow", bot_id="bot")

assert stream
assert stream.logid == mock_logid
assert stream.response.logid == mock_logid

events = list(stream)
assert len(events) == 8
Expand Down Expand Up @@ -80,8 +80,8 @@ def test_sync_chat_stream_error(self, respx_mock):
mock_logid = mock_workflows_chat_stream(respx_mock, read_file("testdata/chat_error_resp.txt"))
stream = coze.workflows.chat.stream(workflow_id="workflow", bot_id="bot")
assert stream
assert stream.logid is not None
assert stream.logid == mock_logid
assert stream.response.logid is not None
assert stream.response.logid == mock_logid

with pytest.raises(Exception, match="error event"):
list(stream)
Expand All @@ -92,8 +92,8 @@ def test_sync_chat_stream_failed(self, respx_mock):
mock_logid = mock_workflows_chat_stream(respx_mock, read_file("testdata/chat_failed_resp.txt"))
stream = coze.workflows.chat.stream(workflow_id="workflow", bot_id="bot")
assert stream
assert stream.logid is not None
assert stream.logid == mock_logid
assert stream.response.logid is not None
assert stream.response.logid == mock_logid

events = list(stream)
assert events
Expand All @@ -107,8 +107,8 @@ def test_sync_chat_stream_invalid_event(self, respx_mock):

stream = coze.workflows.chat.stream(workflow_id="workflow", bot_id="bot")
assert stream
assert stream.logid is not None
assert stream.logid == mock_logid
assert stream.response.logid is not None
assert stream.response.logid == mock_logid

with pytest.raises(Exception, match="invalid chat.event: invalid"):
list(stream)
Expand Down

0 comments on commit fde9d4e

Please sign in to comment.