# ks0vibe/photographer-style-search-engine architecture

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

- Interactive diagram: https://gitdiagram.com/ks0vibe/photographer-style-search-engine
- Repository: https://github.com/ks0vibe/photographer-style-search-engine

## Overview

DeepStyle is an image-reference search product with a Streamlit interface and FastAPI backend. Its user workflow accepts text or an image, encodes the query with CLIP, retrieves image candidates from Qdrant, applies filters and optional reranking, and returns enriched ranked results. A separate offline workflow prepares the image corpus and search data. The README documents additional object-aware retrieval and a FAISS baseline; their precise runtime wiring is not established by the sampled excerpts, so those links are not inferred.

Main entry points: [`app/search/qdrant_retrieval_service.py`](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/qdrant_retrieval_service.py) (Qdrant retrieval), [`app/api/routes.py`](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/routes.py) (FastAPI routes), [`app/database/create_database.py`](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/database/create_database.py) (SQLite metadata), [`app/api/dependencies.py`](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/dependencies.py) (API metadata lookup)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["User experience"]
  node_streamlit["Streamlit demo<br/>[streamlit_app.py]"]
  node_api["FastAPI routes<br/>[routes.py]"]
  node_app_lifecycle["App lifecycle<br/>[main.py]"]
  node_app_dependencies["Search wiring<br/>[dependencies.py]"]
  node_results["Ranked image results<br/>[schemas.py]"]
end

subgraph group_search["Search runtime"]
  node_retrieval["Qdrant retrieval"]
  node_encoder["CLIP encoder<br/>[clip_encoder.py]"]
  node_style_reranker["Style reranker<br/>[style_reranker.py]"]
  node_object_reranker["Object-aware reranker"]
end

subgraph group_data["Metadata and indexes"]
  node_qdrant_store["Qdrant store<br/>[qdrant_store.py]"]
  node_qdrant_db[("Qdrant collection<br/>[qdrant_config.py]")]
  node_metadata_lookup["API metadata lookup<br/>[dependencies.py]"]
  node_metadata_repo["Search metadata repository"]
  node_sqlite[("SQLite metadata<br/>[create_database.py]")]
end

subgraph group_preparation["Offline preparation"]
  node_database_setup["Metadata database setup<br/>[create_database.py]"]
  node_descriptors["Visual descriptors"]
  node_object_detection["YOLO object extraction"]
  node_clip_embeddings["CLIP image embeddings"]
  node_faiss_index["FAISS index baseline"]
  node_qdrant_setup["Qdrant collection setup"]
  node_qdrant_upload["Embedding upload"]
end

node_user(("Search user"))
node_unsplash["Unsplash corpus"]

node_user -->|"searches"| node_streamlit
node_streamlit -->|"requests search"| node_api
node_api -->|"gets application"| node_app_dependencies
node_app_dependencies -->|"constructs service"| node_retrieval
node_api -->|"dispatches query"| node_retrieval
node_retrieval -->|"encodes query"| node_encoder
node_retrieval -->|"searches candidates"| node_qdrant_store
node_qdrant_store -->|"queries vectors"| node_qdrant_db
node_retrieval -->|"reranks candidates"| node_style_reranker
node_retrieval -.->|"optional object reranking"| node_object_reranker
node_api -->|"enriches results"| node_metadata_lookup
node_metadata_lookup -->|"reads metadata"| node_sqlite
node_metadata_lookup -->|"populates response"| node_results
node_retrieval -->|"returns ranked matches"| node_results
node_unsplash -->|"supplies metadata"| node_database_setup
node_database_setup -->|"creates and imports"| node_sqlite
node_descriptors -->|"stores descriptors"| node_sqlite
node_object_detection -->|"stores detections"| node_sqlite
node_clip_embeddings -->|"provides embeddings"| node_faiss_index
node_clip_embeddings -->|"provides embeddings"| node_qdrant_upload
node_qdrant_setup -->|"creates collection"| node_qdrant_db
node_qdrant_upload -->|"uploads vectors"| node_qdrant_db

click node_streamlit "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/demo/streamlit_app.py"
click node_api "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/routes.py"
click node_app_lifecycle "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/main.py"
click node_app_dependencies "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/dependencies.py"
click node_retrieval "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/qdrant_retrieval_service.py"
click node_encoder "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/ml/clip_encoder.py"
click node_style_reranker "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/style_reranker.py"
click node_object_reranker "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/object_aware_reranker.py"
click node_qdrant_store "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/qdrant_store.py"
click node_qdrant_db "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/qdrant_config.py"
click node_metadata_lookup "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/dependencies.py"
click node_metadata_repo "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/metadata_repository.py"
click node_sqlite "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/database/create_database.py"
click node_database_setup "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/database/create_database.py"
click node_descriptors "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/extract_visual_features.py"
click node_object_detection "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/extract_detected_objects.py"
click node_clip_embeddings "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/extract_clip_embeddings.py"
click node_faiss_index "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/build_flat_index.py"
click node_qdrant_setup "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/setup_qdrant_collection.py"
click node_qdrant_upload "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/upload_embeddings_to_qdrant.py"
click node_results "https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/schemas.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_streamlit,node_api,node_app_lifecycle,node_app_dependencies,node_results,node_user toneBlue
class node_retrieval,node_encoder,node_style_reranker,node_object_reranker toneAmber
class node_qdrant_store,node_qdrant_db,node_metadata_lookup,node_metadata_repo,node_sqlite toneMint
class node_database_setup,node_descriptors,node_object_detection,node_clip_embeddings,node_faiss_index,node_qdrant_setup,node_qdrant_upload toneRose
class node_unsplash toneIndigo
```

## Components

### User experience

- [Streamlit demo](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/demo/streamlit_app.py): `app/demo/streamlit_app.py`
- [FastAPI routes](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/routes.py): `app/api/routes.py`
- [App lifecycle](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/main.py): `app/main.py`
- [Search wiring](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/dependencies.py): `app/api/dependencies.py`
- [Ranked image results](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/schemas.py): `app/api/schemas.py`

### Search runtime

- [Qdrant retrieval](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/qdrant_retrieval_service.py): `app/search/qdrant_retrieval_service.py`
- [CLIP encoder](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/ml/clip_encoder.py): `app/ml/clip_encoder.py`
- [Style reranker](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/style_reranker.py): `app/search/style_reranker.py`
- [Object-aware reranker](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/object_aware_reranker.py): `app/search/object_aware_reranker.py`

### Metadata and indexes

- [Qdrant store](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/qdrant_store.py): `app/search/qdrant_store.py`
- [Qdrant collection](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/qdrant_config.py): `app/search/qdrant_config.py`
- [API metadata lookup](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/api/dependencies.py): `app/api/dependencies.py`
- [Search metadata repository](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/search/metadata_repository.py): `app/search/metadata_repository.py`
- [SQLite metadata](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/database/create_database.py): `app/database/create_database.py`

### Offline preparation

- [Metadata database setup](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/app/database/create_database.py): `app/database/create_database.py`
- [Visual descriptors](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/extract_visual_features.py): `scripts/extract_visual_features.py`
- [YOLO object extraction](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/extract_detected_objects.py): `scripts/extract_detected_objects.py`
- [CLIP image embeddings](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/extract_clip_embeddings.py): `scripts/extract_clip_embeddings.py`
- [FAISS index baseline](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/build_flat_index.py): `scripts/build_flat_index.py`
- [Qdrant collection setup](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/setup_qdrant_collection.py): `scripts/setup_qdrant_collection.py`
- [Embedding upload](https://github.com/ks0vibe/photographer-style-search-engine/blob/main/scripts/upload_embeddings_to_qdrant.py): `scripts/upload_embeddings_to_qdrant.py`

### Other components

- **Search user**
- **Unsplash corpus**

## Connections

- Search user → Streamlit demo: searches
- Streamlit demo → FastAPI routes: requests search
- FastAPI routes → Search wiring: gets application
- Search wiring → Qdrant retrieval: constructs service
- FastAPI routes → Qdrant retrieval: dispatches query
- Qdrant retrieval → CLIP encoder: encodes query
- Qdrant retrieval → Qdrant store: searches candidates
- Qdrant store → Qdrant collection: queries vectors
- Qdrant retrieval → Style reranker: reranks candidates
- Qdrant retrieval → Object-aware reranker: optional object reranking
- FastAPI routes → API metadata lookup: enriches results
- API metadata lookup → SQLite metadata: reads metadata
- API metadata lookup → Ranked image results: populates response
- Qdrant retrieval → Ranked image results: returns ranked matches
- Unsplash corpus → Metadata database setup: supplies metadata
- Metadata database setup → SQLite metadata: creates and imports
- Visual descriptors → SQLite metadata: stores descriptors
- YOLO object extraction → SQLite metadata: stores detections
- CLIP image embeddings → FAISS index baseline: provides embeddings
- CLIP image embeddings → Embedding upload: provides embeddings
- Qdrant collection setup → Qdrant collection: creates collection
- Embedding upload → Qdrant collection: uploads vectors
