44import warnings
55from functools import partial
66from typing import Any , Literal
7+ from urllib .parse import urlparse
78
89from httpx import AsyncClient , AsyncHTTPTransport , Response
910from httpx ._utils import URLPattern
1011
1112from ..client .gql import GQLClient
1213from ..client .v11 import V11Client
13- from ..constants import TOKEN
14+ from ..constants import DOMAIN , TOKEN
1415from ..errors import (
1516 BadRequest ,
1617 Forbidden ,
2223 Unauthorized
2324)
2425from ..utils import Result , find_dict , find_entry_by_type , httpx_transport_to_url
26+ from ..x_client_transaction import ClientTransaction
2527from .tweet import Tweet
2628from .user import User
2729
@@ -48,7 +50,6 @@ def tweet_from_data(client: GuestClient, data: dict) -> Tweet:
4850 return Tweet (client , tweet_data , User (client , user_data ))
4951
5052
51-
5253class GuestClient :
5354 """
5455 A client for interacting with the Twitter API as a guest.
@@ -71,7 +72,7 @@ class GuestClient:
7172
7273 def __init__ (
7374 self ,
74- language : str | None = None ,
75+ language : str = 'en-US' ,
7576 proxy : str | None = None ,
7677 ** kwargs
7778 ) -> None :
@@ -93,6 +94,7 @@ def __init__(
9394 self ._guest_token : str | None = None # set when activate method is called
9495 self .gql = GQLClient (self )
9596 self .v11 = V11Client (self )
97+ self .client_transaction = ClientTransaction ()
9698
9799 async def request (
98100 self ,
@@ -102,7 +104,23 @@ async def request(
102104 ** kwargs
103105 ) -> tuple [dict | Any , Response ]:
104106 ':meta private:'
105- response = await self .http .request (method , url , ** kwargs )
107+ headers = kwargs .pop ('headers' , {})
108+
109+ if not self .client_transaction .home_page_response :
110+ cookies_backup = dict (self .http .cookies ).copy ()
111+ ct_headers = {
112+ 'Accept-Language' : f'{ self .language } ,{ self .language .split ("-" )[0 ]} ;q=0.9' ,
113+ 'Cache-Control' : 'no-cache' ,
114+ 'Referer' : f'https://{ DOMAIN } ' ,
115+ 'User-Agent' : self ._user_agent
116+ }
117+ await self .client_transaction .init (self .http , ct_headers )
118+ self .http .cookies = cookies_backup
119+
120+ tid = self .client_transaction .generate_transaction_id (method = method , path = urlparse (url ).path )
121+ headers ['X-Client-Transaction-Id' ] = tid
122+
123+ response = await self .http .request (method , url , headers = headers , ** kwargs )
106124
107125 try :
108126 response_data = response .json ()
@@ -167,7 +185,7 @@ def _base_headers(self) -> dict[str, str]:
167185 'authorization' : f'Bearer { self ._token } ' ,
168186 'content-type' : 'application/json' ,
169187 'X-Twitter-Active-User' : 'yes' ,
170- 'Referer' : 'https://twitter.com/ ' ,
188+ 'Referer' : f 'https://{ DOMAIN } ' ,
171189 }
172190
173191 if self .language is not None :
0 commit comments