Practical Examples & Recipes¶
This page provides practical, copy-pasteable examples for common tasks with folioman-client.
1. Quickstart with Environment Variables¶
Set your environment variables:
export FOLIOMAN_BASE_URL="http://localhost:8000"
export FOLIOMAN_USERNAME="advisor_demo"
export FOLIOMAN_PASSWORD="secretpassword"
Run script:
import asyncio
from folioman_client import FoliomanClient
async def main() -> None:
async with FoliomanClient.from_env() as client:
investors = await client.investors.list()
print(f"Total investors found: {len(investors)}")
for inv in investors:
print(f"- {inv.name} (ID: {inv.id})")
if __name__ == "__main__":
asyncio.run(main())
2. Querying Portfolio Summaries & Holdings¶
Retrieve full portfolio metrics, asset mix, and underlying holdings for an investor:
import asyncio
from folioman_client import FoliomanClient
async def main() -> None:
async with FoliomanClient.from_env() as client:
investor_id = 1
summary = await client.portfolio.get(investor_id)
print(f"=== Portfolio for Investor #{summary.investor_id} ===")
print(f"As of: {summary.as_of}")
print(f"Total Value: INR {summary.total_inr:,.2f}")
print(f"Day Change: INR {summary.day_change_inr} " if summary.day_change_inr else "")
print(f"XIRR: {summary.xirr * 100:.2f}%" if summary.xirr is not None else "XIRR: N/A")
print("\n--- Asset Allocation Mix ---")
for mix in summary.asset_mix:
print(f"{mix.security_type.upper():<12} : INR {mix.value_inr:>12,.2f}")
print("\n--- Priced Holdings ---")
for holding in summary.holdings:
print(
f"{holding.name:<30} | Units: {holding.units:>10} | Value: INR {holding.value_inr}"
)
if __name__ == "__main__":
asyncio.run(main())
3. Scheme Detail and Historical NAV Curves¶
Drill down into a specific scheme holding to inspect historical NAV points and folio breakdown:
import asyncio
from folioman_client import FoliomanClient
async def main() -> None:
async with FoliomanClient.from_env() as client:
investor_id = 1
security_id = 10 # Scheme ID
scheme = await client.holdings.get(investor_id, security_id)
print(f"Scheme: {scheme.security.name}")
print(f"ISIN: {scheme.security.isin} | Category: {scheme.security.category}")
print(f"Total Units: {scheme.units} | Value: INR {scheme.value_inr}")
print(f"\nHistorical NAV Points (Total {len(scheme.nav_history)}):")
for pt in scheme.nav_history[-5:]:
print(f" {pt.date}: NAV {pt.nav}")
print(f"\nFolios ({len(scheme.folios)}):")
for folio in scheme.folios:
print(f" Folio #{folio.number}: {folio.units} units ({folio.broker})")
if __name__ == "__main__":
asyncio.run(main())
4. Historical Net Worth Valuation Series¶
Reconstruct an investor's historical net worth time series across monthly intervals:
import asyncio
from folioman_client import FoliomanClient
async def main() -> None:
async with FoliomanClient.from_env() as client:
investor_id = 1
series = await client.valuations.list(
investor_id,
from_date="2025-01-01",
to_date="2026-01-01",
granularity="monthly",
)
print(f"Valuation Series from {series.start} to {series.end}")
for pt in series.points:
gain = pt.value_inr - pt.invested_inr
print(
f"{pt.date} | Value: INR {pt.value_inr:>12,.2f} | "
f"Cost: INR {pt.invested_inr:>12,.2f} | Unrealized Gain: INR {gain:>12,.2f}"
)
if __name__ == "__main__":
asyncio.run(main())
5. Tax Capital Gains Reporting¶
Fetch realized capital gains reports for tax filing:
import asyncio
from folioman_client import FoliomanClient
async def main() -> None:
async with FoliomanClient.from_env() as client:
investor_id = 1
# Summary across all financial years
fy_summaries = await client.capital_gains.list(investor_id)
print("Capital Gains by Financial Year:")
for pt in fy_summaries:
print(f" FY {pt.fy} -> STCG: INR {pt.stcg:,.2f} | LTCG: INR {pt.ltcg:,.2f}")
# Detailed report for a specific financial year
target_fy = "2024-25"
report = await client.capital_gains.get(investor_id, fy=target_fy)
print(f"\nDetailed Gains for {report.fy}:")
print(f"Total STCG: INR {report.stcg_total:,.2f}")
print(f"Total LTCG: INR {report.ltcg_total:,.2f}")
for row in report.rows:
print(
f" - {row.sold_on} | {row.name} ({row.term}) | "
f"Proceeds: INR {row.sale_value} | Cost: INR {row.cost} | Gain: INR {row.gain}"
)
if __name__ == "__main__":
asyncio.run(main())
6. Concurrent Investor Fetching with asyncio.gather¶
Execute multiple async operations concurrently with shared connection pooling and single-flight token authentication:
import asyncio
from folioman_client import FoliomanClient, PortfolioSummary
async def get_summary_safe(client: FoliomanClient, investor_id: int) -> PortfolioSummary | None:
try:
return await client.portfolio.get(investor_id)
except Exception as exc:
print(f"Failed to fetch portfolio for investor {investor_id}: {exc}")
return None
async def main() -> None:
async with FoliomanClient.from_env() as client:
investors = await client.investors.list()
investor_ids = [inv.id for inv in investors]
# Fetch portfolios concurrently
tasks = [get_summary_safe(client, inv_id) for inv_id in investor_ids]
summaries = await asyncio.gather(*tasks)
valid_summaries = [s for s in summaries if s is not None]
total_aum = sum(s.total_inr for s in valid_summaries)
print(f"Total Assets Under Management across {len(valid_summaries)} investors: INR {total_aum:,.2f}")
if __name__ == "__main__":
asyncio.run(main())