Reports¶
Use NubraReports to discover and generate back-office, tax, trade, portfolio, and mutual fund reports for the logged-in client.
Reports can return either JSON view data, downloadable PDF/XLSX files, or an email acknowledgement depending on the report and action_type.
Confidential data
Reports can contain client name, PAN, bank details, balances, holdings, trades, and tax data. Do not print or store full report payloads in shared logs.
Basic Setup¶
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv
from nubra_python_sdk.reports.reports_data import NubraReports
from nubra_python_sdk.reports.reports_enum import (
ReportActionType,
ReportExportFormat,
)
nubra = InitNubraSdk(NubraEnv.PROD, env_creds=True)
reports = NubraReports(nubra)
Action Types¶
| Action | Meaning |
|---|---|
ReportActionType.VIEW |
Returns JSON parsed into an SDK response model |
ReportActionType.DOWNLOAD |
Returns a ReportFile containing PDF/XLSX bytes |
ReportActionType.EMAIL |
Sends the report to the client's registered email and returns an acknowledgement |
Email action
EMAIL sends a real email to the logged-in client's registered email address. Use it only when the client expects the report by email.
Export Formats¶
| Format | Usage |
|---|---|
ReportExportFormat.PDF |
Back-office report downloads where PDF is supported |
ReportExportFormat.EXCEL |
Back-office report downloads where Excel is supported |
ReportExportFormat.JSON |
Used internally for VIEW; do not pass it manually |
Back-office reports can support PDF, EXCEL, VIEW, and EMAIL depending on the report. Tax, trade, portfolio snapshot, and mutual fund reports are XLSX-only for downloads.
Dates¶
Date arguments accept YYYY-MM-DD strings, ISO datetimes, datetime.date, and datetime.datetime.
reports.financial_ledger("2025-04-01", "2025-06-30")
reports.holding_statement("2025-07-28")
Naive dates are treated as IST midnight and sent to the API in RFC3339 format, such as 2025-04-01T00:00:00+05:30.
Discover Available Reports¶
Use report_options() to fetch the reports, actions, formats, password flag, and date range available for the logged-in client.
options = reports.report_options()
catalogue = options.res
if catalogue:
for item in catalogue.reports:
print(
item.type,
item.title,
item.downloadFileTypes,
item.actionTypes,
item.minDate,
item.maxDate,
item.passwordProtected,
item.password,
)
Example response shape:
ReportOptionsResponse(
message="report-options",
res=ReportOptionsResult(
categories=["ACCOUNT_STATEMENT", "HOLDING", "MUTUAL_FUND_REPORT", "PROFIT_LOSS"],
reports=[
ReportOption(
category="ACCOUNT_STATEMENT",
title="Financial ledger",
type="summary",
downloadFileTypes=["PDF", "EXCEL"],
actionTypes=["DOWNLOAD"],
dateRangeOptions=["DATE_RANGE"],
passwordProtected=True,
password="PAN",
minDate="2025-04-01",
maxDate="2026-07-28",
)
],
),
)
Note
If passwordProtected=True and password="PAN", open the downloaded PDF with the client's PAN in upper case.
Report Method Map¶
Report type from report_options() |
SDK method | Date input | Actions |
|---|---|---|---|
summary |
financial_ledger() |
from_date, to_date |
VIEW, DOWNLOAD, EMAIL |
profit_loss |
profit_loss() |
from_date, to_date |
VIEW, DOWNLOAD, EMAIL |
demat |
demat() |
from_date, to_date |
VIEW, DOWNLOAD, EMAIL |
contract_note |
contract_note() |
from_date, to_date |
VIEW, DOWNLOAD, EMAIL |
daily_margin |
daily_margin() |
date |
VIEW, DOWNLOAD, EMAIL |
holding |
holding_statement() |
date |
VIEW, DOWNLOAD, EMAIL |
open_positions |
open_positions() |
date |
VIEW, DOWNLOAD, EMAIL |
dividend |
dividend() |
from_date, to_date |
VIEW, DOWNLOAD |
tradebook-report |
tradebook() |
from_date, to_date |
VIEW, DOWNLOAD |
trader-diary |
trader_diary() |
from_date, to_date |
DOWNLOAD |
transaction |
mf_transactions() |
from_date, to_date |
VIEW, DOWNLOAD |
orderbook |
mf_orderbook() |
from_date, to_date |
VIEW, DOWNLOAD |
holdings |
mf_holdings() |
date |
VIEW, DOWNLOAD |
capital_gains |
mf_capital_gains() |
from_date, to_date |
VIEW, DOWNLOAD |
| no catalogue entry | portfolio_snapshot() |
none | DOWNLOAD |
Back-Office Reports¶
These reports support VIEW, DOWNLOAD, and EMAIL.
# View financial ledger as JSON
ledger = reports.financial_ledger(
"2025-04-01",
"2025-06-30",
action_type=ReportActionType.VIEW,
)
payload = ledger.model_dump(by_alias=True, exclude_none=True)
print(payload.keys())
print(len(payload.get("Financial", [])))
# Download demat statement as PDF
pdf = reports.demat(
"2025-04-01",
"2025-06-30",
action_type=ReportActionType.DOWNLOAD,
export_format=ReportExportFormat.PDF,
save_to="./reports",
)
print(pdf.filename, len(pdf), pdf.saved_path)
# Single-date holding statement
holding = reports.holding_statement(
"2025-07-28",
action_type=ReportActionType.VIEW,
)
print(holding.model_dump(by_alias=True, exclude_none=True).keys())
# Email profit and loss report
ack = reports.profit_loss(
"2025-04-01",
"2025-06-30",
action_type=ReportActionType.EMAIL,
)
print(ack.message)
Tax And Trade Reports¶
These reports are XLSX-only for downloads. dividend() and tradebook() support VIEW; trader_diary() is download-only.
dividend = reports.dividend(
"2025-04-01",
"2026-03-31",
action_type=ReportActionType.VIEW,
)
print(dividend.total_dividend_fy)
print(len(dividend.dividends))
tradebook = reports.tradebook(
"2025-04-01",
"2025-06-30",
action_type=ReportActionType.VIEW,
)
print(len(tradebook.data))
diary = reports.trader_diary(
"2025-04-01",
"2025-06-30",
save_to="./reports",
)
print(diary.filename, diary.saved_path)
Portfolio Snapshot¶
portfolio_snapshot() generates an XLSX workbook from live trading data. It has no date input and no report_options() entry.
snapshot = reports.portfolio_snapshot(save_to="./reports")
print(snapshot.filename, snapshot.saved_path)
Mutual Fund Reports¶
Mutual fund reports are XLSX-only for downloads and support VIEW and DOWNLOAD.
transactions = reports.mf_transactions(
"2025-04-01",
"2025-06-30",
action_type=ReportActionType.VIEW,
)
rows = [row for group in transactions.transactions for row in group]
print(len(rows))
mf_orders = reports.mf_orderbook(
"2025-04-01",
"2025-06-30",
action_type=ReportActionType.VIEW,
)
print(len(mf_orders.transactions))
mf_holdings = reports.mf_holdings(
"2025-07-28",
action_type=ReportActionType.VIEW,
)
print(mf_holdings.current_value, mf_holdings.pnl)
capital_gains = reports.mf_capital_gains(
"2025-04-01",
"2026-03-31",
action_type=ReportActionType.VIEW,
)
print(len(capital_gains.capital_gains))
Downloaded Files¶
Every download returns a ReportFile.
report = reports.financial_ledger("2025-04-01", "2025-06-30")
print(report.filename)
print(report.content_type)
print(len(report))
path = report.save("./reports")
print(path)
save_to can be a directory or a full file path. Parent directories are created automatically.
Response Types¶
| Action or method | SDK return type |
|---|---|
Back-office VIEW |
BackOfficeReportView |
dividend(..., VIEW) |
DividendReportResponse |
tradebook(..., VIEW) |
TradebookResponse |
mf_transactions(..., VIEW) |
MFTransactionReportView |
mf_orderbook(..., VIEW) |
MFOrderbookReportView |
mf_holdings(..., VIEW) |
MFHoldingsReportView |
mf_capital_gains(..., VIEW) |
MFCapitalGainsReportView |
Any DOWNLOAD |
ReportFile |
Back-office EMAIL |
EmailAck |
Error Handling¶
from nubra_python_sdk.interceptor.errors import (
NubraValidationError,
BadRequestError,
ServerError,
UnauthorizedError,
RetryLimitExceeded,
)
try:
report = reports.demat("2025-04-01", "2025-06-30", save_to="./reports")
except NubraValidationError as e:
print("Bad input:", e.validation_error)
except BadRequestError as e:
print("Request rejected:", e)
except ServerError as e:
print("Report generation failed or no data:", e)
except UnauthorizedError:
print("Session refresh failed")
except RetryLimitExceeded:
print("Network failure")
No-data windows
A report window with no rows can return a server error such as failed to generate report. please try again after some time. Treat this as a possible no-data window and retry with a report date range confirmed by report_options().
Important Rules¶
Important Rules
- Call
report_options()first when you need the available report list, date limits, supported formats, and password flag. - Clamp report dates to the report's
minDateandmaxDate. - For
VIEW, the SDK sendsexport_format=JSONinternally. EMAILis supported only for back-office reports and sends a real email.- Tax, trade, portfolio snapshot, and mutual fund report downloads are XLSX-only.
- Downloaded files and JSON payloads can contain sensitive client information.