This project is the Smart Funding Advisor demo for Business Turku. It helps advisors find funding instruments and investors for companies using a hybrid of curated rules and LLM reasoning.
Long-form documentation (technical description, pilot plan, roadmap, and demo script) can be found in the docs/ folder.
- Start at
docs/index.mdfor detailed materials. - Read the full Hackathon PDF Report
Quick start (dev):
- Create a Python virtual environment and install dependencies:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r requirements.txt-
Configure Environment Variables (Crucial): Create a
.envfile in the root directory and add your Google Gemini API key. This is required for the "Justification Engine."echo "GEMINI_API_KEY=your_actual_api_key_here" > .env
(Alternatively, export it in your terminal:
export GEMINI_API_KEY=...)
Optional: Qdrant (local vector DB for RAG)
If you want to enable the semantic/RAG path using Qdrant, add these variables to your .env (or export them):
```bash
QDRANT_URL=http://localhost:6333
QDRANT_API_KEY=
QDRANT_COLLECTION=funding_sources
```
To run Qdrant locally (Docker):
docker run -p 6333:6333 -v qdrant_storage:/qdrant/storage qdrant/qdrant:latestAfter starting Qdrant, build/upload the vectors (the script will read the QDRANT_* env vars or accept CLI args):
python3 scripts/build_qdrant_index.pyNote: For local testing you can leave QDRANT_API_KEY blank. In production, set a strong API key and secure the service behind a firewall.
Qdrant queries rely on the TF-IDF artifacts (vectors/tfidf_model.pkl and data/vectors.json) built by scripts/build_tfidf_index.py; there is no live embedding path today, so ensure those files exist before expecting Qdrant similarity boosts.
-
Optional: Build TF-IDF vectors and upload to Qdrant (Prototype RAG):
# 1) scrape source pages python3 scripts/scrape_sources.py # 2) build local TF-IDF index and mapping python3 scripts/build_tfidf_index.py # 3) (optional) upload to Qdrant (if QDRANT_URL env var configured) python3 scripts/build_qdrant_index.py
-
Pull fresh EU funding calls (Optional Data Expansion):
# Attempts live scrape; fall back to --input-file if portal blocks the request python3 scripts/scrape_eu_calls.py --programme HORIZON --limit 100 \ --output data/eu_calls.jsonThe script writes normalised call metadata that you can review before merging into
data/funding_sources.json.
Use scripts/funding_api_client.py to pull live opportunities into a Pandas DataFrame and merge them into your pipeline:
python3 -m scripts.funding_api_clientKey sources and endpoints:
- EU Funding & Tenders:
https://ec.europa.eu/.../api/data/topicSearch(no auth) - data.europa.eu datasets:
https://data.europa.eu/api/hub/search/datasets(no auth) - ESIF/Cohesion open data:
https://cohesiondata.ec.europa.eu/resource/<dataset>.json(default dataseteui7-9a3k, override withESIF_DATASET_ID) - Business Finland open calls: scrapes
https://www.businessfinland.fi/en/whats-new/calls-for-applications(override withBUSINESS_FINLAND_CALLS_URL) - Finnvera financing instruments: scrapes
https://www.finnvera.fi/eng/for-smes(override withFINNVERA_PRODUCTS_URL) - If the EU Funding & Tenders endpoint returns HTML, download the JSON payload manually (or use
scripts/scrape_eu_calls.py --output data/eu_calls.json) and setEU_TOPIC_FILE=data/eu_calls.json.
Example Python use:
from scripts.funding_api_client import FundingApiClient, shortlist_opportunities
client = FundingApiClient()
opps = (
client.fetch_funding_tenders()
+ client.fetch_business_finland_calls()
+ client.fetch_finnvera_products()
)
df = shortlist_opportunities(
{"name": "DemoCo", "industry": "software", "growth_stage": "Seed"},
opps,
)
print(df[["name", "source", "deadline"]])- Start the demo UI:
streamlit run app.py- Admin metrics:
streamlit run admin_dashboard.py
# Or open the Admin Dashboard via the sidebar shortcut in the main app.- Ensure virtual environment is active and dependencies installed (
requirements.txt). - Start the app:
streamlit run app.py. - In the sidebar: enter a sample
Business IDor company name and click Fetch / Search. - Confirm PRH autofill populates the company data; if not, fill
Company Nameand chooseIndustry. - Add a short funding need (e.g., "R&D grant to develop prototype") and click Find Funding.
- Verify: top recommendations appear with match scores, justifications, and action plan.
- Download the generated report via Download Funding Report and show the PDF/Markdown.
To run the whole demo in a single terminal after setting up the venv:
source .venv/bin/activate && streamlit run app.pyOptional: run the packaged demo script:
bash scripts/run_demo.shNotes:
- The app uses a combination of local rule-based scoring and a Google Gemini LLM for justifications.
- TF-IDF + Qdrant are optional and used for semantic matching; the app falls back to TF-IDF if Qdrant is not present.
- Curated funding coverage now includes Business Finland, Finnvera, ELY regional aid, and EU programmes (Digital Europe, LIFE, Innovation Fund) plus Nordic examples. Use
data/funding_sources.jsonas the stable base and layer live calls viascripts/funding_api_client.pyif internet is available.