What it does
PDF annual report parsing
BSE/NSE formatting support
Multiple analysis templates
Claude for deep analysis
Tree-summarize for long reports
Stack
PythonLlamaIndexAnthropic ClaudeStreamlit
Deploy on
✓ Streamlit Cloud✓ HuggingFace Spaces
Full source code
Install commands are in the top comments. Copy and run.
from llama_index.core import VectorStoreIndex
from llama_index.readers.file import PDFReader
from llama_index.llms.anthropic import Anthropic
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core import Settings
import streamlit as st, tempfile, os
Settings.llm = Anthropic(model='claude-sonnet-4-6',max_tokens=2000)
Settings.embed_model = OpenAIEmbedding()
TEMPLATES = {'Key Ratios':'Calculate P/E, P/B, ROE, ROA, D/E, current ratio, EBITDA margin.',
'Top Risks':'List 10 business risks with management mitigation.','Revenue Growth':'Extract revenue and profit growth for last 3 years.'}
@st.cache_resource
def load_report(fb):
with tempfile.NamedTemporaryFile(delete=False,suffix='.pdf') as tmp:
tmp.write(fb); path = tmp.name
docs = PDFReader().load_data(file=path); os.unlink(path)
return VectorStoreIndex.from_documents(docs).as_query_engine(similarity_top_k=6,response_mode='tree_summarize')
st.title('Annual Report Analyser (BSE/NSE)')
uploaded = st.file_uploader('Drop annual report PDF',type='pdf')
if uploaded:
engine = load_report(uploaded.read())
atype = st.selectbox('Analysis',list(TEMPLATES.keys()))
custom = st.text_input('Or ask a custom question')
if st.button('Analyse'):
st.write(str(engine.query(custom or TEMPLATES[atype])))