Automating Zerodha Login without Selenium: A Pythonic Approach
Tags: python, automation, zerodha, algotradingwithoutselein
Published: 2023-06-01 06:22:30

## Introduction
When working with online platforms, automating the login process is a common requirement. Selenium is a popular web automation tool, but it's not always the most effective or lightweight option. In this article, we'll look at a Pythonic method for automating Zerodha logins without using Selenium.

## Requirements
You should have a fundamental knowledge of Python programming and be familiar with the ideas behind web scraping in order to follow along with this tutorial. Make sure you have the following dependencies installed:
- `requests`: The requests library is a popular HTTP client for Python that simplifies making HTTP requests. It allows you to send GET and POST requests to web servers, handle cookies, headers, and retrieve the response data.
- `kiteconnect`: The kiteconnect library is an official API client library provided by Zerodha that allows user to interact with the Zerodha API, including retrieving login URLs, placing orders, accessing market data, and more.
- `onetimepass`: The onetimepass library provides functionality for generating One-Time Passwords (OTP) based on the Time-Based One-Time Password (TOTP) algorithm. It allows you to generate OTPs that can be used for two-factor authentication (2FA) in various applications and services.

## 1. Environment Setup:
Install the necessary dependencies by running the following command in your terminal to confirm:
```bash
pip install requests kiteconnect onetimepass
```

## 2. Implementing the Login Function
Next let's create a function called `get_request_token` to handle the Zerodha login process. This function takes a dictionary of credentials as input and returns the request token. 

The structure of the credentials dictionary is as follows
```py
credentials = {
    "username": "login_id_here",
    "password": "password_here",
    "totp_key": "totp_key_here",
    "api_key": "api_key_here",
    "api_secret": "api_secret_here",
}
```

The `get_request_token`function can be divided into three parts:
1. Initializing KiteConnect instance to retrive the login URL.
2. Sending requests, submitting forms and handling 2FA.
3. Extracting the request token from the redirect URL.

Here's a skeleton code for the function:
```py
def get_request_token(credentials: dict) -> str:
    # Initialize KiteConnect instance 

    # Send requests, submit form, and handle 2FA
    
    # Extract and return the request token
```

## 3. Initializing KiteConnect
Initialize a KiteConnect instance which will be used to retrieve the login URL using the provided API key.
```py
kite = KiteConnect(api_key=credentials["api_key"])
```

## 4.  Sending GET Requests
Using the `requests` library to send GET requests to the Zerodha login page. This will allow you to obtain the necessary cookies and hidden form fields required for authentication.
```py
session = requests.Session()
response = session.get(kite.login_url())
```

## 5. Submitting the Login Form
Construct a login payload with the provided username and password. Send a POST request to the Zerodha login endpoint to submit the login form.

```py
login_payload = {
    "user_id": credentials["username"],
    "password": credentials["password"],
}
login_response = session.post("https://kite.zerodha.com/api/login", login_payload)

```

## 6. Handling Two-Factor Authentication:
Zerodha may require two-factor authentication (2FA) for login. Use the `onetimepass` library to generate a Time-Based One-Time Password (TOTP) based on the provided TOTP key. Include this OTP in the payload and send another POST request to complete the login process.

```py
totp_payload = {
    "user_id": credentials["username"],
    "request_id": login_response.json()["data"]["request_id"],
    "twofa_value": onetimepass.get_totp(credentials["totp_key"]),
    "twofa_type": "totp",
    "skip_session": True,
}
totp_response = session.post("https://kite.zerodha.com/api/twofa", totp_payload)
```

## 7. Obtaining the Request Token
After successfully logging in, fetch the login URL again to extract the request token from the URL query parameters using `urlparse` and `parse_qs` functions of `urllib.parse` library.

```py
try:
    # Extracting query parameters from redirect URL
    response = session.get(kite.login_url())
    parse_result = urlparse(response.url)
    query_parms = parse_qs(parse_result.query)
except Exception as e:
    # Extracting query parameters from error message in case of error
    pattern =  r"request_token=[A-Za-z0-9]+"
    # Extracting request token
    query_parms = parse_qs(re.findall(pattern, e.__str__())[0])
request_token = query_parms["request_token"][0]
```


Let's take a look at the complete code snippet that handles the Zerodha login and retrieves the request token:

{% gist https://gist.github.com/sagamantus/949737c6cf3c94a9901a4830c4c5cf9b %}

## Conclusion
In this article, we looked into a Pythonic approach to automating the Zerodha login procedure independent of Selenium. We were able to simulate the login process programmatically by utilising the requests library, KiteConnect API, and onetimepass library providing a simple and effective Selenium substitute that enables workflow automation and seamless integration. 

By avoiding the use of Selenium, we have achieved a more lightweight and efficient solution, enabling seamless integration of Zerodha's services into our Python-based trading workflows. 

Remember to always use automation responsibly and be mindful of any limitations or restrictions imposed by the platform you are interacting with. With the knowledge gained from this article, you can now leverage Python to take your Zerodha trading experience to new heights. Happy automating!