https://github.com/alok-ahirrao/tally-odbc-integration-with-python
This project provides a Flask-based REST API to integrate with Tally ERP 9 / TallyPrime.
https://github.com/alok-ahirrao/tally-odbc-integration-with-python
api-rest debugging flask odbc odbc-api odbcsql python python3 tally tally-odbc
Last synced: 2 months ago
JSON representation
This project provides a Flask-based REST API to integrate with Tally ERP 9 / TallyPrime.
- Host: GitHub
- URL: https://github.com/alok-ahirrao/tally-odbc-integration-with-python
- Owner: alok-ahirrao
- License: other
- Created: 2025-04-06T05:37:10.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2025-04-06T07:47:25.000Z (2 months ago)
- Last Synced: 2025-04-06T08:23:46.210Z (2 months ago)
- Topics: api-rest, debugging, flask, odbc, odbc-api, odbcsql, python, python3, tally, tally-odbc
- Language: Python
- Homepage:
- Size: 719 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Tally Integration API
## Overview
This project provides a Flask-based REST API to integrate with Tally ERP 9 / TallyPrime. It allows external applications to programmatically create Sales Invoices in Tally by sending structured data, which is then converted into Tally-compatible XML format. The API handles communication with the Tally instance, processes responses, and provides clear feedback.
## Output Screenshots
### Tally Invoice Image
### Tally Invoice PDF
[View PDF](output/tally_invoice.pdf)### Tally Output
### Post API Output
## 📘 Tally Initial Setup
Before running the integration, make sure Tally is properly configured.
👉 For full setup instructions, **[check out Tally Initial Setup.md](./Tally%20Initial%20Setup.md)**
This includes:
- Enabling Tally HTTP Server
- Creating necessary ledgers and inventory items
- Configuring the company name for XML import
- Common errors and how to resolve them## Features
* **Create Sales Invoices:** Endpoint to create sales vouchers (invoice mode) in Tally.
* **Tally XML Generation:** Dynamically generates Tally-compatible XML for voucher import based on input JSON data.
* **Data Validation:** Validates incoming request data (required fields, data types, amounts, dates).
* **Tally Communication:** Sends XML requests to the configured Tally instance URL.
* **Response Parsing:** Interprets Tally's XML response to determine success or failure.
* **Environment-Based Configuration:** Uses `.env` file for easy configuration of Tally URL, company name, ledger names, logging level, and server settings.
* **Structured Error Handling:** Returns informative JSON error messages with appropriate HTTP status codes.
* **Logging:** Configurable logging to track requests, responses, and errors.## Tech Stack
* **Python 3.x**
* **Flask:** Micro web framework for the API.
* **Requests:** For making HTTP requests to Tally.
* **python-dotenv:** For managing environment variables.
* **Standard Libraries:** `xml.etree.ElementTree`, `logging`, `os`, `uuid`, `datetime`, `decimal`.## Setup Instructions
1. **Clone the repository:**
```bash
git clone https://github.com/alok-ahirrao/Tally-ODBC-Integration-with-Python.git
cd Tally-ODBC-Integration-with-Python
```2. **Create and activate a virtual environment (recommended):**
```bash
# Windows
python -m venv venv
.\venv\Scripts\activate# macOS/Linux
python3 -m venv venv
source venv/bin/activate
```3. **Install dependencies:**
```bash
pip install -r requirements.txt
```4. **Create a `.env` file:**
Copy the example below and create a `.env` file in the project root. Fill in your specific Tally configuration details.## Environment Variables (`.env`)
Create a `.env` file in the project root with the following variables:
```dotenv
# Tally Configuration
TALLY_URL=http://localhost:9000 # Your Tally instance URL (ensure Tally is running and configured for ODBC/HTTP access)
DEFAULT_COMPANY_NAME="Your Company Name Ltd" # The exact name of the company loaded in Tally
SALES_LEDGER_NAME="Sales Account" # The exact name of your Sales Ledger in Tally
TAX_LEDGER_NAME="Output GST" # The exact name of your primary Tax Ledger (e.g., Output CGST, Output SGST, Output IGST, or a combined GST ledger)# Logging Configuration
LOG_LEVEL=INFO # Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)# Flask Server Configuration (Optional - Defaults are usually fine for development)
# FLASK_RUN_HOST=0.0.0.0 # Host to bind to (0.0.0.0 to allow external access)
# FLASK_RUN_PORT=5001 # Port to run the server on
# FLASK_DEBUG=True # Enable Flask debug mode (DO NOT use True in production)# Security (Recommended - Implement API Key check in your code)
# API_KEY="your_secret_api_key_here"
```**Important:** Ensure the `DEFAULT_COMPANY_NAME`, `SALES_LEDGER_NAME`, and `TAX_LEDGER_NAME` exactly match the names configured in your Tally company data.
## How to Run the Server
Ensure your virtual environment is activated and the `.env` file is configured.
```bash
flask run
```Alternatively, you can run the script directly:
```bash
python app.py
```The server will start, typically on `http://127.0.0.1:5001` (or as configured in `.env`).
## API Endpoints
### 1. Create Sales Invoice
* **URL:** `/create-invoice`
* **Method:** `POST`
* **Content-Type:** `application/json`
* **Description:** Creates a new Sales voucher (in Invoice mode) in the specified Tally company. Requires detailed invoice data in the request body.
* **Request Body (Example JSON):**```json
{
"date": "2025-04-06", // YYYY-MM-DD format
"invoice_number": "API-INV-001", // Unique invoice number
"customer_name": "Customer Ledger Name", // Must exist in Tally
"items": [
{
"name": "Stock Item A", // Must exist in Tally
"quantity": "2",
"rate": "150.50",
"unit": "Nos" // Optional, defaults to 'Nos' if omitted. Must match Tally unit.
},
{
"name": "Stock Item B",
"quantity": "1",
"rate": "500.00"
}
],
"total_amount": "801.00", // Sum of (item quantity * item rate)
"tax": "72.09", // Total tax amount for the invoice
"grand_total": "873.09", // total_amount + tax
"narration": "Optional narration for the voucher", // Optional
"company_name": "Optional Company Name Ltd" // Optional: Overrides DEFAULT_COMPANY_NAME from .env if provided
}
```* **Success Response (201 Created):**
```json
{
"message": "Voucher processed successfully by Tally. (LastVchId: 123)", // Example success message
"invoice_reference_id": "API-INV-001",
"request_id": "unique-request-uuid"
}
```* **Error Response (e.g., 400 Bad Request, 422 Unprocessable Entity, 50x Server Error):**
```json
// Validation Error (400)
{
"error": "Data validation failed: Missing required fields: customer_name",
"request_id": "unique-request-uuid"
}// Tally Rejection Error (422)
{
"error": "Tally rejected the voucher.",
"tally_message": "Tally Error: Ledger 'NonExistent Customer' does not exist.",
"request_id": "unique-request-uuid"
}// Connection Error (503)
{
"error": "Could not connect to Tally at http://localhost:9000. Is Tally running and accessible?",
"request_id": "unique-request-uuid"
}
```### 2. Get Sales Invoice (Planned)
* **URL:** `/get-invoice/`
* **Method:** `GET`
* **Description:** (This endpoint is planned but not yet implemented in the current version). It would fetch details of an existing sales invoice from Tally using its voucher number.## Error Handling
The API handles several types of errors:
* **Request Validation Errors (400 Bad Request):** Missing fields, invalid data types (dates, numbers), inconsistent amounts.
* **Invalid Content-Type (415 Unsupported Media Type):** If the request is not `application/json`.
* **Tally Functional Errors (422 Unprocessable Entity):** Tally receives the request but rejects it due to issues like non-existent ledgers/items, incorrect periods, etc. The specific error from Tally is included in the response.
* **Tally Connection Errors (502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout):** Failure to connect to the Tally instance (Tally not running, network issues, incorrect URL, timeout).
* **Internal Server Errors (500 Internal Server Error):** Unexpected errors during XML generation or response processing.Error responses include a descriptive `error` message and a unique `request_id` for tracking.
## Logging
* Logging is configured using Python's standard `logging` module.
* The log level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`) can be set via the `LOG_LEVEL` environment variable.
* Logs include timestamps, level, and messages, providing insights into request processing, Tally communication, and errors.
* By default, logs are printed to the console where the Flask server is running.## Security Notes
* **API Key:** The current code does *not* implement API key authentication. **It is strongly recommended to add API key validation** to secure the endpoints. This typically involves:
* Adding an `API_KEY` variable to the `.env` file.
* Requiring clients to send the API key in a request header (e.g., `X-API-Key`).
* Adding a decorator or middleware in Flask to check the provided key against the one in `.env` before processing requests.
* **HTTPS:** In a production environment, run the Flask application behind a proper web server (like Nginx or Apache) configured with HTTPS/SSL to encrypt communication.
* **Network Security:** Ensure the Tally instance is accessible only from trusted network locations. Restrict access to the Tally port (default 9000).
* **Input Sanitization:** While basic validation is done, ensure robust validation against potential injection or unexpected data, especially if data originates from untrusted sources.## Tally Configuration Requirements
For the integration to work, ensure the following in your Tally setup:
1. **Tally ERP 9 / TallyPrime is running.**
2. **Enable ODBC/HTTP Access:** In Tally's Gateway Server configuration (or Tally.ini), ensure the port (default 9000) is enabled for external connections. Configure security settings appropriately (e.g., allow specific client IPs if needed).
3. **Company Loaded:** The company specified in `DEFAULT_COMPANY_NAME` (or the `company_name` in the request) must be loaded in Tally when the request is made.
4. **Ledgers Exist:** The `customer_name`, `SALES_LEDGER_NAME`, and `TAX_LEDGER_NAME` must exist in the loaded Tally company.
5. **Stock Items Exist:** All item names provided in the `items` array must exist as Stock Items in Tally.
6. **Units Exist:** Item units (`unit`) must match units defined in Tally.
7. **Voucher Type:** The "Sales" voucher type should exist and be configured appropriately (e.g., for inventory tracking if used).## Troubleshooting Tips
* **Connection Refused/Timeout:** Verify Tally is running, the company is loaded, the `TALLY_URL` in `.env` is correct, and the port is open/accessible from where the API server is running. Check firewall settings.
* **"Ledger/Stock Item does not exist" Error (422):** Double-check the spelling and case of ledger names and stock item names in your request against Tally data. Ensure they exist in the *currently loaded* company.
* **XML Errors / "Invalid XML" (500/422):** Check the generated XML structure in `app.py` (`create_tally_xml` function) against Tally's required format. Look for encoding issues (should be UTF-8). Check Tally's `tally.imp` file (in the Tally application folder) for detailed import errors.
* **Amount Mismatches (400/422):** Ensure `total_amount`, `tax`, and `grand_total` are calculated correctly and consistently with the sum of item amounts. Check for rounding differences.
* **Date Errors (400/422):** Ensure the date format is `YYYY-MM-DD`. Tally might reject dates outside the current financial period.
* **Check API Logs:** Set `LOG_LEVEL=DEBUG` in `.env` for detailed logs, including request data and Tally responses.## 📜 License
Copyright © 2025, Alok Ahirrao
Licensed under the **Creative Commons Attribution-NonCommercial 4.0 International License**. You may use or modify this project for personal or educational purposes only. Commercial usage requires explicit permission.
For inquiries, please contact [[email protected]](mailto:[email protected]).
## Author
**Alok Ahirrao**
[GitHub](https://github.com/alok-ahirrao) | [LinkedIn](https://www.linkedin.com/in/alokahirrao/) | [Resume](https://alokahirrao.netlify.app)
📧 [email protected]🌟 **Happy Coding!** 🌟