Skip to content

Commit

Permalink
Added totp_secret parameter to the login method for handling two-fact…
Browse files Browse the repository at this point in the history
…or authentication
  • Loading branch information
d60 committed Jun 3, 2024
1 parent 0404e25 commit 33be84f
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 11 deletions.
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
httpx
filetype
beautifulsoup4
beautifulsoup4
pyotp
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
install_requires=[
'httpx',
'filetype',
'beautifulsoup4'
'beautifulsoup4',
'pyotp'
],
python_requires='>=3.10',
python_requires='>=3.8',
description='Twitter API wrapper for python with **no API key required**.',
long_description=long_description,
long_description_content_type='text/markdown',
Expand Down
2 changes: 1 addition & 1 deletion twikit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
A Python library for interacting with the Twitter API.
"""

__version__ = '1.7.0'
__version__ = '1.7.1'

from ._captcha import Capsolver
from .bookmark import BookmarkFolder
Expand Down
17 changes: 13 additions & 4 deletions twikit/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import filetype
import httpx
import pyotp
from httpx import Response

from .bookmark import BookmarkFolder
Expand Down Expand Up @@ -114,7 +115,7 @@ def request(
if isinstance(response_data, dict) and 'errors' in response_data:
error_code = response_data['errors'][0]['code']
error_message = response_data['errors'][0].get('message')
if error_code == 37:
if error_code in (37, 64):
# Account suspended
raise AccountSuspended(error_message)

Expand Down Expand Up @@ -298,7 +299,8 @@ def login(
*,
auth_info_1: str,
auth_info_2: str | None = None,
password: str
password: str,
totp_secret: str | None = None
) -> dict:
"""
Logs into the account using the specified login information.
Expand All @@ -319,6 +321,9 @@ def login(
It can be a username, email address, or phone number.
password : :class:`str`
The password associated with the account.
totp_secret : :class:`str`
The TOTP (Time-Based One-Time Password) secret key used for
two-factor authentication (2FA).
Examples
--------
Expand Down Expand Up @@ -385,12 +390,16 @@ def login(
self._user_id = find_dict(flow.response, 'id_str')[0]

if flow.task_id == 'LoginTwoFactorAuthChallenge':
print(find_dict(flow.response, 'secondary_text')[0]['text'])
if totp_secret is None:
print(find_dict(flow.response, 'secondary_text')[0]['text'])
totp_code = input('>>>')
else:
totp_code = pyotp.TOTP(totp_secret).now()

flow.execute_task({
'subtask_id': 'LoginTwoFactorAuthChallenge',
'enter_text': {
'text': input('>>> '),
'text': totp_code,
'link': 'next_link'
}
})
Expand Down
15 changes: 12 additions & 3 deletions twikit/twikit_async/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import filetype
import httpx
import pyotp
from httpx import Response

from ..errors import (
Expand Down Expand Up @@ -116,7 +117,7 @@ async def request(
if isinstance(response_data, dict) and 'errors' in response_data:
error_code = response_data['errors'][0]['code']
error_message = response_data['errors'][0].get('message')
if error_code == 37:
if error_code in (37, 64):
# Account suspended
raise AccountSuspended(error_message)

Expand Down Expand Up @@ -314,6 +315,7 @@ async def login(
auth_info_1: str,
auth_info_2: str | None = None,
password: str,
totp_secret: str | None = None
) -> dict:
"""
Logs into the account using the specified login information.
Expand All @@ -334,6 +336,9 @@ async def login(
It can be a username, email address, or phone number.
password : :class:`str`
The password associated with the account.
totp_secret : :class:`str`
The TOTP (Time-Based One-Time Password) secret key used for
two-factor authentication (2FA).
Examples
--------
Expand Down Expand Up @@ -400,12 +405,16 @@ async def login(
self._user_id = find_dict(flow.response, 'id_str')[0]

if flow.task_id == 'LoginTwoFactorAuthChallenge':
print(find_dict(flow.response, 'secondary_text')[0]['text'])
if totp_secret is None:
print(find_dict(flow.response, 'secondary_text')[0]['text'])
totp_code = input('>>>')
else:
totp_code = pyotp.TOTP(totp_secret).now()

await flow.execute_task({
'subtask_id': 'LoginTwoFactorAuthChallenge',
'enter_text': {
'text': input('>>> '),
'text': totp_code,
'link': 'next_link'
}
})
Expand Down

0 comments on commit 33be84f

Please sign in to comment.