Introduction: Beyond Basic Search – Crafting a Smarter Python Search Engine
In an age defined by information, the ability to find, aggregate, and understand data efficiently is paramount. Traditional search engines, while incredibly powerful, often provide a static list of results, leaving you to sift through numerous links. But what if your search engine could do more? What if it could intelligently decide which sources to consult, summarize findings, and present a coherent, actionable answer, complete with all relevant sources?
This is precisely what we’re going to build: a next-generation, AI-powered Python Search Engine. This isn’t just a basic web crawler; it’s an intelligent agent capable of accessing multiple data sources like Google, Bing, ChatGPT, Perplexity, Reddit, and X (formerly Twitter). It will then aggregate information from these diverse platforms, summarize the key findings, and provide you with a comprehensive answer, including all the links and references it used. This is a transformative approach to information retrieval, giving you unparalleled control and insight.
Ready to dive into the future of search? Let’s get started on building this innovative solution that redefines what a Python Search Engine can do.
Why Build Your Own Python Search Engine?
You might wonder, why bother building a custom search solution when Google or Bing are readily available? The answer lies in control, customization, and intelligence.
- Tailored Information Retrieval: A custom Python Search Engine allows you to specify exactly which data sources are relevant to your needs. If you’re researching market sentiment, you can prioritize social media; if you need technical documentation, academic databases take precedence.
- Intelligent Aggregation & Summarization: Instead of raw links, your AI agent processes information, identifying key points across various sources and synthesizing them into a concise, understandable answer. This saves immense time and effort.
- Bypassing Limitations: Traditional search engines have their own biases and limitations. By building your own, you gain the ability to scrape and access data more dynamically, often bypassing rate limits or geographical restrictions through specialized tools.
- Empowering AI Decisions: Our agent doesn’t just execute commands; it reasons. It decides which tools are most appropriate for a given query, how to formulate sub-queries, and how to combine results for optimal output. This makes it a truly smart information retrieval system.
This project goes beyond simple scripting; it’s about engineering an intelligent system that learns and adapts, making it an invaluable asset for researchers, developers, and anyone seeking deeper, more organized insights from the web.
The Core Technologies Powering Your Python Search Engine
At the heart of our next-gen Python Search Engine are a few powerful technologies working in concert:
- Python: The undisputed champion for scripting, automation, and AI development. Its extensive ecosystem of libraries makes it the perfect language for this project.
- LangGraph: A cutting-edge Python library built on top of LangChain. LangGraph excels at creating robust, multi-step AI agents by modeling their behavior as a graph of states and transitions. This allows our agent to make complex decisions, use various tools, and process information in a structured, iterative manner. You can explore more about LangGraph’s capabilities in their official documentation.
- Bright Data: This is a crucial component, acting as our all-in-one platform for proxies and web scraping. Bright Data provides a reliable interface to various SERP APIs (Google, Bing), web scrapers for dynamic sites (ChatGPT, Perplexity, Reddit, X/Twitter), and ensures that our requests don’t get blocked. It handles the complexities of IP rotation, geo-targeting, and large-scale data collection. Think of it as the secure, high-speed pipeline for all our data needs. We’re proud to have Bright Data as a sponsor, and their service is an essential part of making this project feasible. Learn more and sign up at Bright Data.
- OpenAI API: This is the brain of our intelligent agent. We leverage OpenAI’s powerful large language models (LLMs), such as GPT-4, to handle the core reasoning, decision-making, tool selection, query reformulation, and final summarization of information. The LLM acts as the orchestrator, guiding the entire search process. You’ll need an API key from OpenAI to integrate their models.
By combining these technologies, we create a robust, intelligent, and highly effective Python Search Engine.
Step-by-Step Tutorial: Setting Up Your Python Search Engine Environment
Before we write any code, we need to set up our environment and gather the necessary API keys. This ensures our Python Search Engine has access to all its data sources.
Step 1: Bright Data & OpenAI API Keys Acquisition
First, obtain the necessary credentials for accessing external services.
- Bright Data API Key:
- Create an account or log in to Bright Data.
- Once logged in, navigate to your “Account Settings” (usually found by clicking on your profile icon).
- Look for the “API Keys” section. If you don’t have one, there will be an option to generate a new key. Copy this key – you’ll need it shortly.
- OpenAI API Key:
- Create an account or log in to OpenAI.
- Go to the “API keys” section within your account dashboard.
- Generate a new secret key. Copy this key immediately as it will only be shown once.
Step 2: Configure Bright Data Services
Next, we’ll configure specific Bright Data services that our Python Search Engine will utilize.
- SER API Zone: This zone is for general search engine results (Google, Bing).
- In your Bright Data dashboard, go to “Proxies and Scraping.”
- Click “Add” and select “SER API” (Instance Scraping for Search Engines).
- Give your new zone a name (e.g., “SER API 1”). Remember this name, as it will be used in your
.envfile. - Create the zone. You don’t need any other details from the zone itself, just its name.
- Dataset IDs for ChatGPT & Perplexity: These IDs are for accessing specialized web scrapers.
- In Bright Data, navigate to “Web Scrapers.”
- Click “New” and then “Browse Scrapers Marketplace.”
- Search for “ChatGPT,” select the scraper, and proceed to the “API Request Builder” section. Here you’ll find the “Data Set ID.” Copy it.
- Repeat the process for “Perplexity AI.” Search for “Perplexity AI,” select the scraper, and copy its “Data Set ID” from the API Request Builder.
Step 3: Secure Your Credentials with .env
It’s critical to keep your API keys secure and out of your main codebase. We’ll use a .env file for this.
- Create a new file named
.envin the root directory of your project. - Add the following lines to it, replacing the placeholder values with the keys and IDs you collected:
```ini
BRIGHT_DATA_API_KEY="your_bright_data_api_key_here"
BRIGHT_DATA_SER_ZONE="SER API 1" # Or whatever you named your SER API zone
GPT_DATA_SET_ID="your_chatgpt_dataset_id_here"
PERPLEXITY_DATA_SET_ID="your_perplexity_dataset_id_here"
OPENAI_API_KEY="your_openai_api_key_here"
```
- Important: Never share your
.envfile or commit it to version control (like Git). Add.envto your.gitignorefile.
Step 4: Prepare Your Python Environment
A virtual environment is essential for managing project dependencies without conflicts.
- Create a Virtual Environment:
- Using
venv(standard Python module):bash python3 -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate - Using
uv(modern, fast package installer):bash uv init source .venv/bin/activate # uv init often activates automatically, but good to ensure
Note: If you’re new touv, you might need to install it first:pip install uv.
- Using
- Install Required Python Packages:
- With your virtual environment activated, install the necessary libraries:
# If using uv uv add requests python-dotenv langchain langchain-openai langgraph # If using pip pip install requests python-dotenv langchain langchain-openai langgraphThese packages are the building blocks of our Python Search Engine. - Requests for HTTP requests.
- python-dotenv for loading environment variables.
- LangChain and LangGraph for agent orchestration.
- langchain-openai for OpenAI integration.
- With your virtual environment activated, install the necessary libraries:
Coding Your Intelligent Python Search Engine Agent (main.py)
Now that our environment is ready, let’s write the core logic for our Python Search Engine in a file named main.py.
Step 5: Essential Imports and Environment Loading
We start by importing all the necessary modules and loading our environment variables.
import os
import time
import requests
from dotenv import load_dotenv
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from langgraph.graph import StateGraph, END
from requests.utils import quote # For URL encoding queries
# Load environment variables from .env file
load_dotenv()
BRIGHT_DATA_API_KEY = os.getenv("BRIGHT_DATA_API_KEY")
BRIGHT_DATA_SER_ZONE = os.getenv("BRIGHT_DATA_SER_ZONE")
GPT_DATA_SET_ID = os.getenv("GPT_DATA_SET_ID")
PERPLEXITY_DATA_SET_ID = os.getenv("PERPLEXITY_DATA_SET_ID")
# Define request headers for Bright Data API calls
headers = {
"Authorization": f"Bearer {BRIGHT_DATA_API_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
}
This section initializes our environment, pulling sensitive keys and IDs from the .env file, and sets up the standard headers needed for authenticating with the Bright Data API.
Step 6: Crafting Your Smart Search Tools
The heart of our Python Search Engine lies in its tools. Each tool is a Python function decorated with @tool, making it discoverable and usable by our AI agent. The description provided in the @tool decorator is crucial; it helps the LLM understand when and how to use each tool.
Let’s define each of our search and information retrieval tools:
@tool
def google_search(query: str) -> str:
"""Search using Google to find relevant web pages and information."""
print("Google tool is being used...")
payload = {
"zone": BRIGHT_DATA_SER_ZONE,
"url": f"https://google.com/search?q={quote(query)}", # URL encode the query
"brd_json": 1, # Request JSON output from Bright Data
"format": "raw",
"country": "US", # Can change country as needed
}
response = requests.post(
"https://api.brightdata.com/serp/request?async=true", # Async request for SERP
headers=headers,
json=payload,
)
data = response.json()
results = []
for item in data.get("organic", []): # Extract organic search results
results.append(
f"Title: {item.get('title')}\n"
f"Link: {item.get('link')}\n"
f"Snippet: {item.get('description', '')}"
)
return "\n\n".join(results)[:10000] # Limit context length
@tool
def bing_search(query: str) -> str:
"""Search using Bing to find relevant web pages and information."""
print("Bing tool is being used...")
payload = {
"zone": BRIGHT_DATA_SER_ZONE,
"url": f"https://bing.com/search?q={quote(query)}",
"brd_json": 1,
"format": "raw",
"country": "US",
}
response = requests.post(
"https://api.brightdata.com/serp/request?async=true",
headers=headers,
json=payload,
)
data = response.json()
results = []
for item in data.get("organic", []):
results.append(
f"Title: {item.get('title')}\n"
f"Link: {item.get('link')}\n"
f"Snippet: {item.get('description', '')}"
)
return "\n\n".join(results)[:10000]
@tool
def reddit_search(query: str) -> str:
"""Search for discussions and sentiment on Reddit about a specific topic."""
print("Reddit tool is being used...")
# Using Google's site-specific search for Reddit results
payload = {
"zone": BRIGHT_DATA_SER_ZONE,
"url": f"https://google.com/search?q=site:reddit.com {quote(query)}",
"brd_json": 1,
"format": "raw",
"country": "US",
}
response = requests.post(
"https://api.brightdata.com/serp/request?async=true",
headers=headers,
json=payload,
)
data = response.json()
results = []
for item in data.get("organic", []):
results.append(
f"Title: {item.get('title')}\n"
f"Link: {item.get('link')}\n"
f"Snippet: {item.get('description', '')}"
)
return "\n\n".join(results)[:10000]
@tool
def x_search(query: str) -> str:
"""Search for real-time updates and public opinions on X (Twitter) about a topic."""
print("X tool is being used...")
# Using Google's site-specific search for X (Twitter) results
payload = {
"zone": BRIGHT_DATA_SER_ZONE,
"url": f"https://google.com/search?q=site:x.com {quote(query)}",
"brd_json": 1,
"format": "raw",
"country": "US",
}
response = requests.post(
"https://api.brightdata.com/serp/request?async=true",
headers=headers,
json=payload,
)
data = response.json()
results = []
for item in data.get("organic", []):
results.append(
f"Title: {item.get('title')}\n"
f"Link: {item.get('link')}\n"
f"Snippet: {item.get('description', '')}"
)
return "\n\n".join(results)[:10000]
@tool
def gpt_prompt(query: str) -> str:
"""Use ChatGPT to get a direct answer or explanation to a question."""
print("GPT tool is being used...")
payload = [{"url": "https://chatgpt.com", "prompt": query}]
url = (
f"https://api.brightdata.com/datasets/v3/trigger?dataset_id={GPT_DATA_SET_ID}"
f"&format=json&custom_output_fields=answer_text_markdown"
)
response = requests.post(url, headers=headers, json=payload)
snapshot_id = response.json()["snapshot_id"]
# Poll Bright Data until the snapshot is ready
while True:
progress_url = (
f"https://api.brightdata.com/datasets/v3/progress/{snapshot_id}"
)
status = requests.get(progress_url, headers=headers).json()["status"]
if status == "ready":
break
time.sleep(5) # Wait 5 seconds before checking again
# Retrieve the final data from the snapshot
data_url = (
f"https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}?format=json"
)
data = requests.get(data_url, headers=headers).json()[0]
return data["answer_text_markdown"]
@tool
def perplexity_prompt(query: str) -> str:
"""Use Perplexity AI to perform research and get answers with sources."""
print("Perplexity tool is being used...")
payload = [{"url": "https://www.perplexity.ai", "prompt": query}]
url = (
f"https://api.brightdata.com/datasets/v3/trigger?dataset_id={PERPLEXITY_DATA_SET_ID}"
f"&format=json&custom_output_fields=answer_text_markdown|sources" # Request answer and sources
)
response = requests.post(url, headers=headers, json=payload)
snapshot_id = response.json()["snapshot_id"]
# Poll Bright Data until the snapshot is ready
while True:
progress_url = (
f"https://api.brightdata.com/datasets/v3/progress/{snapshot_id}"
)
status = requests.get(progress_url, headers=headers).json()["status"]
if status == "ready":
break
time.sleep(5)
# Retrieve the final data from the snapshot
data_url = (
f"https://api.brightdata.com/datasets/v3/snapshot/{snapshot_id}?format=json"
)
data = requests.get(data_url, headers=headers).json()[0]
sources = data.get("sources", [])
return data["answer_text_markdown"] + "\n\nSources:\n" + "\n".join(sources)
Each of these functions represents a specialized tool for our Python Search Engine.
- Google Search and Bing Search provide traditional web results via Bright Data’s SERP API. Note the
quote(query)for proper URL encoding andbrd_json=1to get structured JSON output. - Reddit Search and X Search leverage Google’s
site:operator to specifically target content from these platforms, ideal for sentiment analysis or community discussions. - ChatGPT Prompt and Perplexity AI Prompt use Bright Data’s dedicated web scrapers. These tools involve an asynchronous process: triggering a request, receiving a
snapshot_id, polling a progress endpoint until the result isready, and then retrieving the final data. Perplexity is configured to also return sources, enriching the output of our search solution.
Step 7: Orchestrating the Agent with LangGraph
With our tools defined, we now build the intelligent agent using LangGraph. This component orchestrates which tools to use, when, and how to process their outputs.
# Initialize the Language Model (LLM)
llm = ChatOpenAI(model_name="gpt-4-turbo-preview", temperature=0) # Using a powerful model, temperature 0 for deterministic answers
# List all the tools our agent can use
tools = [
google_search,
bing_search,
gpt_prompt,
perplexity_prompt,
reddit_search,
x_search,
]
# Define the system prompt to guide the agent's behavior
system_prompt = """Use all tools at your disposal to answer user questions.
Always use at least two tools, preferably more.
When giving an answer, aggregate and summarize all information you get.
Always provide a complete list of all sources which you used to find the information you provided.
Make sure to add all links and sources here, not just a few superficial ones.
"""
# Create the ReAct agent
agent = create_react_agent(llm, tools, system_prompt)
# Define the agent node for LangGraph
def agent_node(state: dict) -> dict:
"""Agent node in the LangGraph graph, invokes the ReAct agent."""
agent_response = agent.invoke({"messages": [("human", state["query"])]})
# Extract the content from the last message in the agent's response
return {"answer": agent_response["messages"][-1].content}
# Define the state graph
graph = StateGraph({"query": str, "answer": str}) # Define the schema for the graph's state
graph.add_node("agent", agent_node) # Add our agent node to the graph
graph.set_entry_point("agent") # The agent node is where our graph starts
graph.add_edge("agent", END) # The agent node directly leads to the end state after processing
app = graph.compile() # Compile the graph into a runnable application
In this crucial section:
- We initialize
ChatOpenAIwithgpt-4-turbo-preview(ensure you have access to this model or select another suitable one likegpt-3.5-turbo). Thetemperature=0makes the LLM’s responses more consistent. - All our defined tools are collected into a
toolslist. - A
system_promptis crafted. This prompt is vital for instructing the LLM on how to behave: always use multiple tools, summarize, and provide complete sources. This guidance ensures our Python Search Engine delivers high-quality, comprehensive answers. create_react_agentcombines the LLM, tools, and system prompt to form our intelligent agent. The ReAct (Reasoning and Acting) framework allows the agent to reason about a task and then execute appropriate actions (tools).- The
agent_nodefunction wraps the agent’s invocation, fitting it into LangGraph’s state-based model. - Finally,
StateGraphdefines the flow of our application. It’s a simple graph: start at the “agent” node, invoke the agent, and then transition toEND(the terminating state).graph.compile()prepares the graph for execution.
Running Your CLI Python Search Engine
Now that all the pieces are in place, let’s run our Python Search Engine as a command-line application.
if __name__ == "__main__":
while True: # Keep the search engine running for multiple queries
query = input("\nEnter your query (type 'exit' to quit): ")
if query.lower() == 'exit':
break
if not query:
print("Please enter a query.")
continue
try:
print("\nSearching...\n")
result = app.invoke({"query": query}) # Invoke the compiled graph with the user's query
print("--- Final Answer ---")
print(result["answer"])
print("--------------------\n")
except Exception as e:
print(f"An error occurred: {e}")
print("Please check your API keys and Bright Data zone/dataset IDs.")
To run your Python Search Engine:
- Save the complete code as
main.py. - Open your terminal or command prompt.
- Ensure your virtual environment is activated.
- Execute the script:
bash python main.py - You’ll be prompted to “Enter your query:”. Type your question and press Enter.
As the agent processes your query, you’ll see messages indicating which tools are being used (e.g., “Google tool is being used…”, “Perplexity tool is being used…”). Once the agent has gathered and summarized all the information, it will print the final comprehensive answer, complete with all the sources.
Example Queries from the Context:
- “Who is neural9?”
- “Python 3.14 release date?”
- “Current sentiment on Intel CPUs?”
When you ask about “Current sentiment on Intel CPUs?”, you’ll observe the agent intelligently leveraging Reddit and X (Twitter) alongside Google and Perplexity to gather a comprehensive understanding of public opinion, demonstrating the true power of this AI-driven Python Search Engine.
Beyond the Command Line: Web Application Integration (Flask)
While our command-line interface is functional, a web application can provide a much more user-friendly experience. The original video context briefly showcased how this Python Search Engine can be integrated into a Flask application.
The core logic of the agent and its tools remains the same. The Flask integration primarily involves:
- Creating a Flask
app.pyfile with routes to handle web requests. - Designing an
index.htmltemplate (with CSS and JavaScript for styling and loading animations) for the user interface. - In the Flask route that handles search queries, you would take the user’s input, invoke
app.invoke({"query": user_query})to get the agent’s response, and then render this response in the HTML template.
This allows users to interact with your powerful Python Search Engine through a beautiful, intuitive web interface. You can find the complete code for the Flask integration on the accompanying GitHub repository, linked in the original video’s description. This separation of concerns allows us to focus on the core search engine logic in this tutorial while still offering a pathway to a more polished user experience.
Key Improvements and Advanced Considerations
Building a robust Python Search Engine is an ongoing process. Here are some areas for further enhancement and advanced considerations:
- Error Handling: Implement more sophisticated
try-exceptblocks to gracefully handle API errors, network issues, or malformed responses from data sources. This will make your search solution more resilient. - Rate Limiting: If you plan for heavy usage, be mindful of rate limits for both Bright Data and OpenAI. Implement delays or token-bucket algorithms to prevent exceeding them.
- Asynchronous Operations: For improved performance, especially when calling multiple external APIs, consider refactoring your tool functions to use
asyncioandaiohttp. This would allow parallel execution of requests, significantly speeding up the overall search process. - Prompt Engineering: The quality of the agent’s answers and tool selection heavily depends on the
system_promptand the descriptions in your@tooldecorators. Experiment with different phrasing, add examples, or provide specific instructions for complex scenarios to fine-tune your Python Search Engine‘s behavior. - Adding More Data Sources: Integrate other specialized APIs or web scrapers (e.g., academic databases, news aggregators, e-commerce sites) to broaden the scope of your search capabilities.
- Caching: Implement a caching layer for frequently asked queries or tool results to reduce API calls and improve response times.
- User Feedback Loop: For a production-grade system, consider adding a mechanism for users to provide feedback on the quality of answers. This data can then be used to further refine the agent’s prompts or tool selection logic.
- Deployment: For production, explore deployment options like Docker, Kubernetes, or serverless functions (AWS Lambda, Google Cloud Functions) to host your Python Search Engine.
Conclusion: Unlock New Insights with Your Custom Python Search Engine
You’ve just embarked on an exciting journey, building a sophisticated Python Search Engine that harnesses the power of AI to transform how you find and consume information. By integrating diverse data sources through Bright Data, orchestrating intelligent decisions with LangGraph, and leveraging the reasoning capabilities of OpenAI’s LLMs, you’ve created a system far more dynamic and insightful than conventional search tools.
This project empowers you with a highly customizable information retrieval solution, capable of delivering aggregated, summarized, and thoroughly sourced answers. It’s a testament to the incredible potential when modern AI and robust data infrastructure combine.
We encourage you to experiment, expand its capabilities, and tailor it to your specific needs. Start querying your new AI-powered Python Search Engine today and unlock a new level of informational clarity! Don’t forget to check out Bright Data, our essential sponsor, whose services made this advanced data access possible. Your support helps us continue creating valuable content like this.
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.

