# aadith47/chithram-finder architecture

> Architecture diagram of the GitHub repository aadith47/chithram-finder, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/aadith47/chithram-finder
- Repository: https://github.com/aadith47/chithram-finder

## Overview

Image Finder accepts a plain-English image description through either a CLI or web UI, generates structured fields and targeted queries, searches three stock-photo services, deduplicates the results, and ranks them before presenting a gallery or list. The LangGraph workflow in `graph.py` owns the stages and their order; query generation and ranking each have documented fallbacks. The README documents these capabilities, while sampled source confirms the workflow and integrations shown here.

Main entry points: [`search.py`](https://github.com/aadith47/chithram-finder/blob/main/search.py) (Query search and dedupe), [`graph.py`](https://github.com/aadith47/chithram-finder/blob/main/graph.py) (Graph workflow), [`llm.py`](https://github.com/aadith47/chithram-finder/blob/main/llm.py) (Query generation), [`platforms/pexels.py`](https://github.com/aadith47/chithram-finder/blob/main/platforms/pexels.py) (Pexels adapter)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interfaces["User interfaces"]
  node_cli["CLI<br/>[main.py]"]
  node_web["Web UI<br/>[app.py]"]
end

subgraph group_workflow["Search workflow"]
  node_orchestrator["Graph workflow<br/>[graph.py]"]
  node_query_stage["Generate queries<br/>[graph.py]"]
  node_search_pexels["Search Pexels<br/>[graph.py]"]
  node_search_unsplash["Search Unsplash<br/>[graph.py]"]
  node_search_pixabay["Search Pixabay<br/>[graph.py]"]
  node_combine["Combine results<br/>[graph.py]"]
  node_rank_stage["Rank results<br/>[graph.py]"]
end

subgraph group_providers["Search providers"]
  node_query_logic["Query generation<br/>[llm.py]"]
  node_search_helper["Query search and dedupe<br/>[search.py]"]
  node_pexels["Pexels adapter<br/>[pexels.py]"]
  node_unsplash["Unsplash adapter<br/>[unsplash.py]"]
  node_pixabay["Pixabay adapter<br/>[pixabay.py]"]
  node_stock_services{{"Stock photo APIs"}}
  node_gemini{{"Gemini"}}
end

subgraph group_ranking["Ranking and data"]
  node_openrouter{{"OpenRouter"}}
  node_jev["Jev ranker<br/>[jev.py]"]
  node_keyword_ranker["Keyword ranker<br/>[ranker.py]"]
  node_image_model["Image record<br/>[models.py]"]
end

node_user(("User"))

node_user -->|"describes image"| node_cli
node_user -->|"describes image"| node_web
node_cli -->|"invokes graph"| node_orchestrator
node_web -->|"invokes graph"| node_orchestrator
node_orchestrator -->|"dispatches"| node_query_stage
node_query_stage -->|"dispatches"| node_search_pexels
node_search_pexels -->|"dispatches"| node_search_unsplash
node_search_unsplash -->|"dispatches"| node_search_pixabay
node_search_pixabay -->|"dispatches"| node_combine
node_combine -->|"dispatches"| node_rank_stage
node_query_stage -->|"requests queries"| node_query_logic
node_query_logic -->|"requests structured output"| node_gemini
node_query_logic -.->|"tries fallbacks"| node_openrouter
node_search_pexels -->|"searches queries"| node_search_helper
node_search_unsplash -->|"searches queries"| node_search_helper
node_search_pixabay -->|"searches queries"| node_search_helper
node_search_helper -->|"calls search"| node_pexels
node_search_helper -->|"calls search"| node_unsplash
node_search_helper -->|"calls search"| node_pixabay
node_pexels -->|"requests photos"| node_stock_services
node_unsplash -->|"requests photos"| node_stock_services
node_pixabay -->|"requests photos"| node_stock_services
node_pexels -->|"creates records"| node_image_model
node_unsplash -->|"creates records"| node_image_model
node_pixabay -->|"creates records"| node_image_model
node_rank_stage -->|"tries ranking"| node_jev
node_jev -->|"requests decisions"| node_openrouter
node_rank_stage -.->|"fallback ranking"| node_keyword_ranker
node_orchestrator -->|"returns results"| node_cli
node_orchestrator -->|"returns results"| node_web

click node_cli "https://github.com/aadith47/chithram-finder/blob/main/main.py"
click node_web "https://github.com/aadith47/chithram-finder/blob/main/app.py"
click node_orchestrator "https://github.com/aadith47/chithram-finder/blob/main/graph.py"
click node_query_stage "https://github.com/aadith47/chithram-finder/blob/main/graph.py"
click node_search_pexels "https://github.com/aadith47/chithram-finder/blob/main/graph.py"
click node_search_unsplash "https://github.com/aadith47/chithram-finder/blob/main/graph.py"
click node_search_pixabay "https://github.com/aadith47/chithram-finder/blob/main/graph.py"
click node_combine "https://github.com/aadith47/chithram-finder/blob/main/graph.py"
click node_rank_stage "https://github.com/aadith47/chithram-finder/blob/main/graph.py"
click node_query_logic "https://github.com/aadith47/chithram-finder/blob/main/llm.py"
click node_search_helper "https://github.com/aadith47/chithram-finder/blob/main/search.py"
click node_pexels "https://github.com/aadith47/chithram-finder/blob/main/platforms/pexels.py"
click node_unsplash "https://github.com/aadith47/chithram-finder/blob/main/platforms/unsplash.py"
click node_pixabay "https://github.com/aadith47/chithram-finder/blob/main/platforms/pixabay.py"
click node_jev "https://github.com/aadith47/chithram-finder/blob/main/jev.py"
click node_keyword_ranker "https://github.com/aadith47/chithram-finder/blob/main/ranker.py"
click node_image_model "https://github.com/aadith47/chithram-finder/blob/main/models.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_web,node_user toneBlue
class node_orchestrator,node_query_stage,node_search_pexels,node_search_unsplash,node_search_pixabay,node_combine,node_rank_stage toneAmber
class node_query_logic,node_search_helper,node_pexels,node_unsplash,node_pixabay,node_stock_services,node_gemini toneMint
class node_openrouter,node_jev,node_keyword_ranker,node_image_model toneRose
```

## Components

### User interfaces

- [CLI](https://github.com/aadith47/chithram-finder/blob/main/main.py): `main.py`
- [Web UI](https://github.com/aadith47/chithram-finder/blob/main/app.py): `app.py`

### Search workflow

- [Graph workflow](https://github.com/aadith47/chithram-finder/blob/main/graph.py): `graph.py`
- [Generate queries](https://github.com/aadith47/chithram-finder/blob/main/graph.py): `graph.py`
- [Search Pexels](https://github.com/aadith47/chithram-finder/blob/main/graph.py): `graph.py`
- [Search Unsplash](https://github.com/aadith47/chithram-finder/blob/main/graph.py): `graph.py`
- [Search Pixabay](https://github.com/aadith47/chithram-finder/blob/main/graph.py): `graph.py`
- [Combine results](https://github.com/aadith47/chithram-finder/blob/main/graph.py): `graph.py`
- [Rank results](https://github.com/aadith47/chithram-finder/blob/main/graph.py): `graph.py`

### Search providers

- [Query generation](https://github.com/aadith47/chithram-finder/blob/main/llm.py): `llm.py`
- [Query search and dedupe](https://github.com/aadith47/chithram-finder/blob/main/search.py): `search.py`
- [Pexels adapter](https://github.com/aadith47/chithram-finder/blob/main/platforms/pexels.py): `platforms/pexels.py`
- [Unsplash adapter](https://github.com/aadith47/chithram-finder/blob/main/platforms/unsplash.py): `platforms/unsplash.py`
- [Pixabay adapter](https://github.com/aadith47/chithram-finder/blob/main/platforms/pixabay.py): `platforms/pixabay.py`
- **Stock photo APIs**
- **Gemini**

### Ranking and data

- **OpenRouter**
- [Jev ranker](https://github.com/aadith47/chithram-finder/blob/main/jev.py): `jev.py`
- [Keyword ranker](https://github.com/aadith47/chithram-finder/blob/main/ranker.py): `ranker.py`
- [Image record](https://github.com/aadith47/chithram-finder/blob/main/models.py): `models.py`

### Other components

- **User**

## Connections

- User → CLI: describes image
- User → Web UI: describes image
- CLI → Graph workflow: invokes graph
- Web UI → Graph workflow: invokes graph
- Graph workflow → Generate queries: dispatches
- Generate queries → Search Pexels: dispatches
- Search Pexels → Search Unsplash: dispatches
- Search Unsplash → Search Pixabay: dispatches
- Search Pixabay → Combine results: dispatches
- Combine results → Rank results: dispatches
- Generate queries → Query generation: requests queries
- Query generation → Gemini: requests structured output
- Query generation → OpenRouter: tries fallbacks
- Search Pexels → Query search and dedupe: searches queries
- Search Unsplash → Query search and dedupe: searches queries
- Search Pixabay → Query search and dedupe: searches queries
- Query search and dedupe → Pexels adapter: calls search
- Query search and dedupe → Unsplash adapter: calls search
- Query search and dedupe → Pixabay adapter: calls search
- Pexels adapter → Stock photo APIs: requests photos
- Unsplash adapter → Stock photo APIs: requests photos
- Pixabay adapter → Stock photo APIs: requests photos
- Pexels adapter → Image record: creates records
- Unsplash adapter → Image record: creates records
- Pixabay adapter → Image record: creates records
- Rank results → Jev ranker: tries ranking
- Jev ranker → OpenRouter: requests decisions
- Rank results → Keyword ranker: fallback ranking
- Graph workflow → CLI: returns results
- Graph workflow → Web UI: returns results
