I started with a simple Bible Q&A app and grew it into one application with three services: KJV Q&A, curated insights browsing, and ministry recommendation matching.
Extracting the KJV Bible
First I needed the text. The API made extracting the full KJV straightforward because verses come back in a structured format.
Note: Bible verses taken from the King James Version (KJV) and sourced from api.bible (bible id: de4e12af7f28f599-02).
Generating Embeddings with OpenAI
Next I needed a way to search by meaning. I used OpenAI’s text-embedding-ada-002 model to turn verses into embeddings.
Storing Embeddings in Pinecone
Q&A only feels usable if retrieval is fast. I stored the embeddings in a Pinecone index so related verses come back quickly when someone asks a question.
Creating the Unified Platform with Python Flask
For the UI and API layer I used Flask with Blueprints so each service stays separate:
- Bible Q&A: the original question-answering flow
- Bible Insights: browse curated notes by book and chapter
- Ministry Matching: recommend ministries from user interests with OpenAI
Leveraging OpenAI for Response Generation
When someone asks a question, the app sends it through OpenAI’s chat completions path with LangChain’s Pinecone vector store so the closest verse embeddings come back first.
The ministry matcher also uses OpenAI, but for a different job: suggest ministries from what the user says they care about.
Displaying Results
All three services share one UI and navigation, so you can move between Q&A, insights, and ministry matching without jumping apps.
Modern Deployment with Azure Container Apps
I moved hosting from AWS EC2 to Azure Container Apps. Compared with the old setup:
- Scales from 1-10 replicas with demand
- Managed SSL and custom domains
- Docker-based deploys
- Built-in logging and health checks
- Pay for what you use
The unified platform is now live at https://uba.josephvelliah.com, showcasing all three services in one cohesive experience.

Insights now live in the same app as Q&A instead of a separate project. Container Apps handles scaling when traffic changes.
Architecture notes
A few choices that mattered in practice:
- Separate services so one missing config does not take the whole app down
- Rate limiting, input sanitization, and CSP headers
- Health checks and structured logging
- Docker for consistent deploys
The live app is at https://uba.josephvelliah.com.