当前位置:   article > 正文

接入 Claude2 API 的完整 Python 客户端指南_claude2接口

claude2接口
> 想使用Claude 2.0 API 需要排队申请,非常难申请.我们可以能通过python模仿网页端请求了,加上多账号可以无限制使用
  • 1

1.前期准备

  • 梯子
  • python3.9环境
  • claude账号 (没有可以到某宝购买)

2.安装依赖

pip install requests curl_cffi python-dotenv PyPDF2

  • 1
  • 2

3.python 代码

import json
import os
import uuid
import requests
from curl_cffi import requests, Curl, CurlOpt, CurlError
from dotenv import load_dotenv
from common.log import logger
import PyPDF2
# import docx
import re
from io import BytesIO

load_dotenv()  # Load environment variables from .env file


class Client:

    def __init__(self, cookie, use_proxy=False):
        self.cookie = cookie
        self.use_proxy = use_proxy
        self.proxies = self.load_proxies_from_env()
        # logger.info("__init__: use_proxy: {}".format(self.use_proxy))
        # logger.info("__init__: proxies: {}".format(self.proxies))
        self.organization_id = self.get_organization_id()
        # self.organization_id ="28912dc3-bcd3-43c5-944c-a943a02d19fc"

    def load_proxies_from_env(self):
        proxies = {}
        if self.use_proxy:
            http_proxy = os.getenv('HTTP_PROXY')
            https_proxy = os.getenv('HTTPS_PROXY')
            socks5_proxy = os.getenv('SOCKS5_PROXY')
            if http_proxy:
                proxies['http'] = http_proxy
            if https_proxy:
                proxies['https'] = https_proxy
            if socks5_proxy:
                proxies['https'] = socks5_proxy
        return proxies

    def get_organization_id(self):
        url = "https://claude.ai/api/organizations"

        headers = {
            'User-Agent':
                'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36',
            'Accept-Language': 'en-US,en;q=0.5',
            'Referer': 'https://claude.ai/chats',
            'Content-Type': 'application/json',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'same-origin',
            'Connection': 'keep-alive',
            'Cookie': f'{self.cookie}'
        }

        response = self.send_request("GET", url, headers=headers)
        if response.status_code == 200:
            res = json.loads(response.text)
            uuid = res[0]['uuid']
            return uuid
        else:
            print(f"Error: {response.status_code} - {response.text}")

    def get_content_type(self, file_path):
        # Function to determine content type based on file extension
        extension = os.path.splitext(file_path)[-1].lower()
        if extension == '.pdf':
            return 'application/pdf'
        elif extension == '.txt':
            return 'text/plain'
        elif extension == '.csv':
            return 'text/csv'
        # Add more content types as needed for other file types
        else:
            return 'application/octet-stream'

    # Lists all the conversations you had with Claude
    def list_all_conversations(self):
        url = f"https://claude.ai/api/organizations/{self.organization_id}/chat_conversations"

        headers = {
            'User-Agent':
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
            'Accept-Language': 'en-US,en;q=0.5',
            'Referer': 'https://claude.ai/chats',
            'Content-Type': 'application/json',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'Connection': 'keep-alive',
            'Cookie': f'{self.cookie}'
        }

        response = self.send_request("GET", url, headers=headers)
        conversations = response.json()

        # Returns all conversation information in a list
        if response.status_code == 200:
            return conversations
        else:
            print(f"Error: {response.status_code} - {response.text}")

    # Send Message to Claude
    def send_message(self, prompt, conversation_id, attachment=None):
        url = "https://claude.ai/api/append_message"
        # print("send_message,attachment"+attachment)
        # Upload attachment if provided
        attachments = []
        if attachment:
            attachment_response = self.upload_attachment(attachment)
            if attachment_response:
                attachments = [attachment_response]
            else:
                return {"Error: Invalid file format. Please try again."}

        # Ensure attachments is an empty list when no attachment is provided
        if not attachment:
            attachments = []

        payload = json.dumps({
            "completion": {
                "prompt": f"{prompt}",
                "timezone": "Asia/Kolkata",
                "model": "claude-2"
            },
            "organization_uuid": f"{self.organization_id}",
            "conversation_uuid": f"{conversation_id}",
            "text": f"{prompt}",
            "attachments": attachments
        })

        # headers = {
        #     'User-Agent':
        #         'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
        #     'Accept': 'text/event-stream, text/event-stream',
        #     'Accept-Language': 'en-US,en;q=0.5',
        #     'Referer': 'https://claude.ai/chats',
        #     'Content-Type': 'application/json',
        #     'Origin': 'https://claude.ai',
        #     'DNT': '1',
        #     'Connection': 'keep-alive',
        #     'Cookie': f'{self.cookie}',
        #     'Sec-Fetch-Dest': 'empty',
        #     'Sec-Fetch-Mode': 'cors',
        #     'Sec-Fetch-Site': 'same-origin',
        #     'TE': 'trailers'
        # }

        headers = [
            b'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
            b'Accept: text/event-stream, text/event-stream',
            b'Accept-Language: en-US,en;q=0.5',
            b'Referer: https://claude.ai/chats',
            b'Content-Type: application/json',
            b'Origin: https://claude.ai',
            b'DNT: "1"',
            b'Connection: keep-alive',
            b'Cookie: '+self.cookie.encode("utf-8"),
            b'Sec-Fetch-Dest: empty',
            b'Sec-Fetch-Mode: cors',
            b'Sec-Fetch-Site: same-origin',
            b'TE: trailers'
        ]

        # response = self.send_request("POST",url,headers=headers, data=payload, stream=True)
        # decoded_data = response.content.decode("utf-8")
        # #logger.info("send_message {} decoded_data:".format(decoded_data))
        # decoded_data = re.sub('\n+', '\n', decoded_data).strip()
        # data_strings = decoded_data.split('\n')
        # completions = []
        # for data_string in data_strings:
        #     json_str = data_string[6:].strip()
        #     data = json.loads(json_str)
        #     if 'completion' in data:
        #         completions.append(data['completion'])
        #
        # answer = ''.join(completions)
        # logger.info("send_message {} answer:".format(answer))
        buffer = BytesIO()
        c = Curl()

        def stream_callback(data):
            json_str = data.decode('utf-8')

            decoded_data = re.sub('\n+', '\n', json_str).strip()
            data_strings = decoded_data.split('\n')
            for data_string in data_strings:
                json_str = data_string[6:].strip()
                _data = json.loads(json_str)
                if 'completion' in _data:
                    buffer.write(str(_data['completion']).encode('utf-8'))
                    print(_data['completion'], end="")

        c.setopt(CurlOpt.URL, b'https://claude.ai/api/append_message')
        c.setopt(CurlOpt.WRITEFUNCTION, stream_callback)
        c.setopt(CurlOpt.HTTPHEADER, headers)
        c.setopt(CurlOpt.POSTFIELDS, payload)
        c.impersonate("chrome110")

        try:
            c.perform()
        except CurlError as e:
            print(f"请求失败: {e}")
        # c.perform()
        c.close()
        body = buffer.getvalue()
        print(body.decode())
        return body

    # Deletes the conversation
    def delete_conversation(self, conversation_id):
        url = f"https://claude.ai/api/organizations/{self.organization_id}/chat_conversations/{conversation_id}"

        payload = json.dumps(f"{conversation_id}")
        headers = {
            'User-Agent':
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
            'Accept-Language': 'en-US,en;q=0.5',
            'Content-Type': 'application/json',
            'Content-Length': '38',
            'Referer': 'https://claude.ai/chats',
            'Origin': 'https://claude.ai',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'Connection': 'keep-alive',
            'Cookie': f'{self.cookie}',
            'TE': 'trailers'
        }

        response = self.send_request(
            "DELETE", url, headers=headers, data=payload)
        # Returns True if deleted or False if any error in deleting
        if response.status_code == 200:
            return True
        else:
            return False

    # Returns all the messages in conversation
    def chat_conversation_history(self, conversation_id):
        url = f"https://claude.ai/api/organizations/{self.organization_id}/chat_conversations/{conversation_id}"

        headers = {
            'User-Agent':
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
            'Accept-Language': 'en-US,en;q=0.5',
            'Referer': 'https://claude.ai/chats',
            'Content-Type': 'application/json',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'Connection': 'keep-alive',
            'Cookie': f'{self.cookie}'
        }

        response = self.send_request(
            "GET", url, headers=headers, params={'encoding': 'utf-8'})
        print(type(response))

        # List all the conversations in JSON
        return response.json()

    def generate_uuid(self):
        random_uuid = uuid.uuid4()
        random_uuid_str = str(random_uuid)
        formatted_uuid = f"{random_uuid_str[0:8]}-{random_uuid_str[9:13]}-{random_uuid_str[14:18]}-{random_uuid_str[19:23]}-{random_uuid_str[24:]}"
        return formatted_uuid

    def create_new_chat(self):
        url = f"https://claude.ai/api/organizations/{self.organization_id}/chat_conversations"
        uuid = self.generate_uuid()

        payload = json.dumps({"uuid": uuid, "name": ""})
        headers = {
            'User-Agent':
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
            'Accept-Language': 'en-US,en;q=0.5',
            'Referer': 'https://claude.ai/chats',
            'Content-Type': 'application/json',
            'Origin': 'https://claude.ai',
            'DNT': '1',
            'Connection': 'keep-alive',
            'Cookie': self.cookie,
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'TE': 'trailers'
        }
        response = self.send_request(
            "POST", url, headers=headers, data=payload)
        # Returns JSON of the newly created conversation information
        return response.json()

    # Resets all the conversations
    def reset_all(self):
        conversations = self.list_all_conversations()

        for conversation in conversations:
            conversation_id = conversation['uuid']
            delete_id = self.delete_conversation(conversation_id)

        return True

    def upload_attachment(self, file_path):
        # '.docx',
        if file_path.endswith(('.txt', '.pdf', '.csv', '.doc')):
            file_name = os.path.basename(file_path)
            file_size = os.path.getsize(file_path)
            file_type = "text/plain"
            file_content = ""
            if file_path.endswith('.txt'):
                with open(file_path, 'r', encoding='utf-8') as file:
                    file_content = file.read()

            elif file_path.endswith('.pdf'):
                with open(file_path, 'rb') as file:
                    pdf_reader = PyPDF2.PdfFileReader(file)
                    for page_num in range(pdf_reader.numPages):
                        page = pdf_reader.getPage(page_num)
                        file_content += page.extractText()

            # elif file_path.endswith(('.doc', '.docx')):
            #     doc = docx.Document(file_path)
            #     paragraphs = doc.paragraphs
            #     for paragraph in paragraphs:
            #         file_content += paragraph.text

            return {
                "file_name": file_name,
                "file_type": file_type,
                "file_size": file_size,
                "extracted_content": file_content
            }

        url = 'https://claude.ai/api/convert_document'
        headers = {
            'User-Agent':
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
            'Accept-Language': 'en-US,en;q=0.5',
            'Referer': 'https://claude.ai/chats',
            'Origin': 'https://claude.ai',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'Connection': 'keep-alive',
            'Cookie': f'{self.cookie}',
            'TE': 'trailers'
        }

        file_name = os.path.basename(file_path)
        content_type = self.get_content_type(file_path)
        files = {
            'file': (file_name, open(file_path, 'rb'), content_type),
            'orgUuid': (None, self.organization_id)
        }
        response = self.send_request(url, "POST", headers=headers, files=files)
        if response.status_code == 200:
            return response.json()
        else:
            return False

    # Renames the chat conversation title
    def rename_chat(self, title, conversation_id):
        url = "https://claude.ai/api/rename_chat"

        payload = json.dumps({
            "organization_uuid": f"{self.organization_id}",
            "conversation_uuid": f"{conversation_id}",
            "title": f"{title}"
        })
        headers = {
            'User-Agent':
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
            'Accept-Language': 'en-US,en;q=0.5',
            'Content-Type': 'application/json',
            'Referer': 'https://claude.ai/chats',
            'Origin': 'https://claude.ai',
            'Sec-Fetch-Dest': 'empty',
            'Sec-Fetch-Mode': 'cors',
            'Sec-Fetch-Site': 'same-origin',
            'Connection': 'keep-alive',
            'Cookie': f'{self.cookie}',
            'TE': 'trailers'
        }

        response = self.send_request(
            "POST", url, headers=headers, data=payload)
        if response.status_code == 200:
            return True
        else:
            return False

    def send_request(self, method, url, headers, data=None, files=None, params=None, stream=False):
        if self.use_proxy:
            return requests.request(method, url, headers=headers, data=data, files=files, params=params, impersonate="chrome110", proxies=self.proxies, timeout=500)
        else:
            return requests.request(method, url, headers=headers, data=data, files=files, params=params, impersonate="chrome110", timeout=500)


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400

4.使用

claude 登陆进去之后按下 F12 在 Cookie 里找到你的 sessionKye 把值复制出来
也可以通过 https://claude.ai/chat/xxx-xx-xxx-xx-xxx F12 带xxx-xx-xxx-xx-xxx名称的请求参数 cookie 获取
注意接口请求有限制,可注册多账号轮流使用

from claude_api import Client
from curl_cffi import requests, Curl, CurlOpt

cookie = "xxxxx"
claude_api = Client(cookie)

# conversations = claude_api.list_all_conversations()
# for conversation in conversations:
#     conversation_id = conversation['uuid']
#     print(conversation_id)

# prompt = """
# 根据下文帮我抽取所有人物,及人物特征:
# 这一章主要描述了萧宁和萧薰儿两人在萧家斗技堂的比试。
# 萧宁是萧家大长老的孙子,已修炼到八段斗之气,在萧家年轻一代中实力很强。
# 萧薰儿是萧家九段斗之气的高手,是萧家年轻一代中的第一人。
# 两人比试时,萧宁全力出手,但萧薰儿轻松化解了他的攻击,一掌将萧宁击败。
# 比试结束后,萧宁表现出对萧薰儿的爱慕之情,但萧薰儿态度很生疏。
# 随后萧薰儿去找站在一旁看比试的萧炎说话,萧炎是萧家另一位年轻人。
# 文中还提到萧炎和萧宁关系不太亲密,两人只是有些生疏的打招呼。
# 从人物关系和事件过程来看,主要描述了萧家三位年轻人之间比较复杂的关系。"""


prompt = "根据下文帮我抽取所有人物,及人物特征。内容如下: 姜峰是神桥境界的强者,但是因为神力源泉枯竭而无法施展神通。叶凡出手将姜峰打飞出去,脸上留下印记。这让姜峰感到极度羞辱。他愤怒地想报复叶凡,但叶凡的体魄更强,直接将姜峰打跪在地。叶凡继续羞辱姜峰,称他高高在上目中无人,最后扭断了姜峰的脖子,为两年前的仇报了回去。这场景吸引了周围所有人的注意,他们看到一个凡人的叶凡居然能打败神桥境界的强者,感到震惊。叶凡继续杀死其他想阻止他的人。姜家的长老姜汉忠出手相救,和叶凡发生了激烈交战。三大家族的长老都意识到叶凡服用了圣药,拥有异于常人的强大力量。他们想留下叶凡,让叶凡去神山上采摘神药。叶凡明白他们的意图,表面上同意,心里却暗自盘算要利用他们,再想办法逃脱。"

conversation_id = claude_api.create_new_chat()['uuid']
# print("新窗口ID:"+conversation_id)

# prompt = "举个例子"
response = claude_api.send_message(
    prompt, conversation_id)
print(response)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/365266
推荐阅读
相关标签
  

闽ICP备14008679号