Indian financial statement parsers for CAMS, CDSL, and NSDL PDFs
Project description
saransh-workflows
Python parsers for Indian financial statement PDFs — CAMS Consolidated Account Statement, CDSL CAS, and NSDL e-CAS. Each parser extracts text from the PDF using pypdf and returns a fully structured JSON object.
Installation
From PyPI (once published)
pip install saransh-workflows
From source (development)
git clone https://github.com/sagarchandagarwal/saransh-workflows.git
cd saransh-workflows
pip install -e .
CLI Usage
After installation three commands are available on your PATH:
# CAMS parser
parse-cams path/to/cams_statement.pdf
parse-cams path/to/cams_statement.pdf --pretty -o output.json
parse-cams path/to/cams_statement.pdf --password your_pdf_password --pretty
# CDSL parser
parse-cdsl path/to/cdsl_cas.pdf
parse-cdsl path/to/cdsl_cas.pdf --pretty -o output.json
parse-cdsl path/to/cdsl_cas.pdf --password your_pdf_password --pretty
# NSDL parser
parse-nsdl path/to/nsdl_ecas.pdf
parse-nsdl path/to/nsdl_ecas.pdf --pretty -o output.json
parse-nsdl path/to/nsdl_ecas.pdf --password your_pdf_password --pretty
All three commands accept the same flags:
| Flag | Description |
|---|---|
input_pdf |
Path to the source PDF (required) |
-o / --output |
Output JSON path (default: same name as PDF with .json suffix) |
--pretty |
Pretty-print JSON with 2-space indentation |
--password |
Password for encrypted/password-protected PDF files |
Python API
from pathlib import Path
from saransh_workflows import parse_cams_pdf, parse_cdsl_pdf, parse_nsdl_pdf
cams_data = parse_cams_pdf(Path("cams_statement.pdf"))
cdsl_data = parse_cdsl_pdf(Path("cdsl_cas.pdf"))
nsdl_data = parse_nsdl_pdf(Path("nsdl_ecas.pdf"))
# Encrypted PDFs
nsdl_encrypted = parse_nsdl_pdf(Path("nsdl_ecas.pdf"), password="your_pdf_password")
All three functions return a plain dict that can be serialised with json.dumps.
Output JSON Schemas
CAMS
{
"source_file": str,
"statement_period": {"from": str, "to": str} | null,
"investor": {
"email": str | null,
"name": str | null,
"address": [str],
"phone_res": str | null,
"mobile": str | null
},
"portfolio_summary": [
{"fund_house": str, "cost_value_inr": float, "market_value_inr": float}
],
"folios": [
{
"fund_house": str,
"folio_no": str | null,
"pan": str | null,
"kyc": str | null,
"holder_name": str | null,
"scheme_code": str | null,
"scheme_name": str | null,
"isin": str | null,
"registrar": str | null,
"nominees": [str],
"opening_unit_balance": float | null,
"transactions": [
{
"date": str,
"transaction": str,
"amount_inr": float | null,
"units": float | null,
"price_inr": float | null,
"unit_balance": float | null,
"charges": [{"date": str, "amount_inr": float}]
}
],
"closing_unit_balance": float | null,
"nav": {"date": str, "value_inr": float} | null,
"total_cost_value_inr": float | null,
"market_value": {"date": str, "value_inr": float} | null,
"notes": [str]
}
],
"warnings": [str]
}
CDSL
{
"source_file": str,
"cas_id": str | null,
"statement_period": {"from": str, "to": str} | null,
"investor": {"name": str, "pan": str, "address": [str]},
"summary": {
"accounts": [...],
"total_portfolio_value_inr": float | null,
"grand_total_inr": float | null,
"monthly_portfolio_valuation": [...],
"asset_allocation": [...]
},
"cdsl_accounts": [
{
"bo_id": str,
"dp_name": str,
"transactions": [...],
"holdings": [...],
"holding_sections": [...],
"no_transaction": bool,
"nil_holding": bool,
"portfolio_values": [float]
}
],
"nsdl_accounts": [...],
"mutual_fund_folios": [
{
"amc_name": str,
"scheme_name": str,
"scheme_code": str,
"folio_no": str | null,
"isin": str | null,
"opening_balance": float | null,
"closing_balance": float | null,
"transactions": [...]
}
]
}
NSDL
{
"source_file": str,
"nsdl_id": str | null,
"statement_period": {"from": str, "to": str} | null,
"investor": {
"name": str | null,
"pan": str | null,
"address": [str],
"portfolio_value_inr": float | null
},
"summary": {
"accounts": [...],
"total_inr": float | null,
"grand_total_inr": float | null,
"portfolio_trend": [
{
"month": str,
"portfolio_value_inr": float | null,
"change_inr": float | null,
"change_percent": float | null,
"remark": str | null
}
],
"asset_composition": [
{"asset_class": str, "value_inr": float, "percent": float}
]
},
"holdings": {
"account": {...},
"securities": [
{
"isin": str,
"security": str,
"current_balance": float,
"free_balance": float,
"value_inr": float,
...
}
]
},
"transactions": {
"account": {...},
"isin_sections": [
{
"isin": str,
"security": str,
"opening_balance": float | null,
"closing_balance": float | null,
"transactions": [...]
}
]
}
}
Project Structure
saransh-workflows/
├── saransh_workflows/ # Installable Python package
│ ├── __init__.py # Public API re-exports
│ ├── cams.py # CAMS parser
│ ├── cdsl.py # CDSL parser
│ └── nsdl.py # NSDL parser
├── cams-parser/
│ ├── parse_cams_pdf.py # Standalone script (standalone usage)
│ └── requirements.txt
├── cdsl-parser/
│ ├── parse_cdsl_pdf.py # Standalone script
│ └── requirements.txt
├── nsdl-parser/
│ ├── parse_nsdl_pdf.py # Standalone script
│ └── requirements.txt
├── pyproject.toml # Package metadata & build config
├── README.md
└── AGENTS.md # Development log & change history
Publishing to PyPI
pip install build twine
python -m build
twine upload dist/*
Requirements
- Python ≥ 3.11
- pypdf ≥ 6.0.0
- cryptography ≥ 3.1 (required for AES-encrypted PDFs)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file saransh_workflows-0.1.0.tar.gz.
File metadata
- Download URL: saransh_workflows-0.1.0.tar.gz
- Upload date:
- Size: 25.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72dcfedc3f991f0934658f8485690502f9982245fee65f9bcf5e093a5b4a1790
|
|
| MD5 |
0d33d875dff7abb050d87a7d63f3c0c6
|
|
| BLAKE2b-256 |
5af4fb86a0baefbc8e87eff11d5e3973740a6a32add5435ec226fb9bc454e6eb
|
File details
Details for the file saransh_workflows-0.1.0-py3-none-any.whl.
File metadata
- Download URL: saransh_workflows-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
840633e9cf29157ce56be4f1aa6029353699bbf974db2c00467a4907e0d227d8
|
|
| MD5 |
c5f0de5989fa90ee935e675e4a203d67
|
|
| BLAKE2b-256 |
5294c4aa878e7ea875165c9a1e06a30a5248ad2292bf68f7774915a4b501289a
|