Metadata-Version: 2.1
Name: async-claude-client
Version: 0.1.0
Summary: async client for claude.ai and slack.com
Home-page: https://github.com/canxin121/Async-Claude-Client
Author: canxin
Author-email: 1969730106@qq.com
Requires-Python: >=3.8,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Dist: curl-cffi (>=0.5.7,<0.6.0)
Requires-Dist: loguru (>=0.7.1,<0.8.0)
Requires-Dist: pydantic (>=1.10.12,<2.0.0)
Requires-Dist: slack-sdk (>=3.21.3,<4.0.0)
Description-Content-Type: text/markdown

# Claude Client
[中文文档](README_zh_cn.md)  

Table of Contents

- [Claude Client](#claude-client)
- [Claude Ai](#claude-ai)
    - [1. Initialize Client](#1-initialize-client)
    - [2. Get All Chats](#2-get-all-chats)
    - [3. Get Chat History](#3-get-chat-history)
    - [4. Create a New Chat](#4-create-a-new-chat)
    - [5. Delete a Chat](#5-delete-a-chat)
    - [6. Rename Chat](#6-rename-chat)
    - [7. Stream Ask Claude](#7-stream-ask-claude)
- [Slack Claude](#slack-claude)
    - [1. Create Client](#1-create-client)
    - [2. Create a New Chat Message dict](#2-create-a-new-chat-message-dict)
    - [3. Ask Claude in a Streaming Manner](#3-ask-claude-in-a-streaming-manner)
- [QA](#qa)
    - [1. How to Get Slack User Token?](#1-how-to-get-slack-user-token)
    - [2. Why is Slack Claude not responding?](#2-why-is-slack-claude-not-responding)

# Claude Ai

## 1. Initialize Client

Function:
ClaudeAiClient(cookie).init()
Parameters:
cookie: `str | Path | list[dict]` - It can be a string or a Path to a file, or a direct json.
The cookie can be extracted as a JSON format using a browser extension called "cookie-editor".

```python
from async_claude_client import ClaudeAiClient

claude_ai_client = await ClaudeAiClient(cookie="cookies.json").init()
```

## 2. Get All Chats

Function:
get_all_chats()
Returns:
A dictionary containing all chat windows.

```python
chats = await claude_ai_client.get_all_chats()
```

## 3. Get Chat History

Function:
get_chat_history()
Parameters:
chat_id: `str` - The chat_id of the chat window. It can be extracted from the last UUID in the chat window's link or
from the 'uuid' value in the data returned by the create_new_chat() function.
Returns:
A dictionary containing the chat history of the specified chat window.

```python
history = await claude_ai_client.get_chat_history(chat_id)
```

## 4. Create a New Chat

Function:
create_new_chat()
Returns:
A dictionary containing the information of the newly created chat window. The value corresponding to the key 'uuid' is
the chat_id of the new window.

```python
new_chat = await claude_ai_client.create_new_chat()
```

## 5. Delete a Chat

Function:
delete_chat()
Parameters:
chat_id: `str` - The chat_id of the chat window. It can be extracted from the last UUID in the chat window's link or
from the 'uuid' value in the data returned by the create_new_chat() function.

```python
await claude_ai_client.delete_chat(chat_id)
```

## 6. Rename Chat

Function:
rename_chat()
Parameters:
title: `str` - The new name for the chat window.
chat_id: `str` - The chat_id of the chat window. It can be extracted from the last UUID in the chat window's link or
from the 'uuid' value in the data returned by the create_new_chat() function.

```python
await claude_ai_client.rename_chat(title, chat_id)
```

## 7. Stream Ask Claude

Function:
ask_stream()
Parameters:
question: `str` - The question to ask Claude.
chat_id: `str` - The chat_id of the chat window. It can be extracted from the last UUID in the chat window's link or
from the 'uuid' value in the data returned by the create_new_chat() function.
attachment: `str | Path` - The address string or Path of the file attachment to upload.

```python
new_chat = await claude_ai_client.create_new_chat()
async for text in claude_ai_client.ask_stream("Are you there?", new_chat["uuid"]):
    print(text, end="")
```

# Slack Claude

## 1. Create Client

Function:
ClaudeAiClient(cookie).init()
Parameters:
slack_user_token: `str` - User token for the official Slack API. Refer
to [How to Get Slack User Token](#1-how-to-get-slack-user-token) for obtaining the token.
claude_id: `str` - Member ID of the Claude app added in Slack. To obtain the Member ID, open Claude in the app and click
on Claude's avatar.
channel_id: `str` - ID of the channel to communicate with Claude through the client. To obtain the channel ID, open the
desired channel and extract the concatenated address string before '/thread/' in the URL. It usually starts with 'C',
for example, C0579MZR3LH.
pre_msg: `str` - Prefix for the messages sent to Claude. This is a workaround because Slack adds '@claude' to the
messages sent to Claude in the channel. This prefix is used to make Claude ignore the '@claude' mention.

```python
from async_claude_client import Slack_Claude_Client, Text, ChatUpdate

slack_claude_client = Slack_Claude_Client(
    slack_user_token,
    claude_id,
    channel_id,
    "<Ignore '@Claude', neither say 'not seen' nor say 'seen'>"
)
```

## 2. Create a New Chat Message dict

Function:
create_new_chat()
Return:
A new dict for the chat message

```python
chat = slack_claude_client.create_new_chat()
```

## 3. Ask Claude in a Streaming Manner

Function:
ask_stream_raw()
Parameters:
question: `str` - The question to ask
chat: `dict` - The chat message dict
Return Types:
`ChatUpdate`: Updated chat message dict
`Text`: Text reply message

Note:
After each question, the chat message dict (`chat`) will be updated. The updated `chat` should be used for the next
interaction.

```python
chat = slack_claude_client.create_new_chat()
async for data in client.ask_stream_raw("Are you there?", chat):
    if isinstance(data, Text):
        print(data.content, end="")
    elif isinstance(data, ChatUpdate):
        # Update the chat with the new content
        chat = data.content

async for data in client.ask_stream_raw("Who are you talking about?", chat):
    if isinstance(data, Text):
        print(data.content, end="")
    elif isinstance(data, ChatUpdate):
        chat = data.content
```

# QA

## 1. How to Get Slack User Token?

```md
Go to https://api.slack.com
Create a bot API
Go to the Options

Add the following permissions to OAuth & Permissions

Bot Token Scopes require the following permissions:
channels:history
channels:join
channels:manage
channels:read
channels:write.invites
channels:write.topic
chat:write
chat:write.customize
chat:write.public
groups:history
groups:read
groups:write
groups:write.invites
groups:write.topic
im:history
im:read
im:write
im:write.invites
im:write.topic
usergroups:write
users:read
users:write

User Token Scopes require the following permissions:
admin
Administer a workspace
channels:history
channels:read
channels:write
channels:write.invites
channels:write.topic
chat:write
groups:history
groups:read
groups:write
groups:write.invites
groups:write.topic
im:history
im:read
im:write
im:write.invites
im:write.topic
mpim:history
mpim:read
mpim:write
usergroups:write
users:read
users:write

After adding all the permissions, select Install App to proceed with the installation.

Once installed, you will receive a token starting with 'xoxp', which is the Slack user token.
```

## 2. Why is Slack Claude not responding?

    It could be an issue with the Slack server itself, and developers cannot fix it. You can try creating a new chat window to resolve the issue.
