-
-
Notifications
You must be signed in to change notification settings - Fork 716
Add Government Services Assistant Python script #687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,141 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# # -*- coding: utf-8 -*- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """Chile_Government_Services_Assistant .ipynb | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Automatically generated by Colab. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Original file is located at | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# https://colab.research.google.com/drive/13IOn2Vhg0EUwuIGpVilImW0rEpYYMoFQ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# # Chile Government Services Assistant - AI Chatbot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# This notebook demonstrates how to use an AI-powered assistant to answer questions about Chilean government services and procedures, using the Firecrawl API and a friendly, step-by-step conversational approach. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# [](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Chile_Government_Services_Assistant.ipynb) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# # Install dependencies | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# !pip install flask firecrawl praisonaiagents google-genai python-dotenv deep-translator | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """# Set API Keys""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
os.environ['FIRECRAWL_API_KEY'] = "your api key here" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
os.environ['OPENAI_API_KEY'] = "your api key here" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical Security Issue: Remove hardcoded API keys Hardcoded API keys in source code pose a serious security risk and should never be committed to version control. -os.environ['FIRECRAWL_API_KEY'] = "your api key here"
-os.environ['OPENAI_API_KEY'] = "your api key here"
+# Load API keys from environment variables or .env file
+# os.environ['FIRECRAWL_API_KEY'] should be set externally
+# os.environ['OPENAI_API_KEY'] should be set externally
+
+if not os.environ.get('FIRECRAWL_API_KEY'):
+ raise ValueError("FIRECRAWL_API_KEY environment variable is required")
+if not os.environ.get('OPENAI_API_KEY'):
+ raise ValueError("OPENAI_API_KEY environment variable is required") 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """# Import Libraries & Translator""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from firecrawl import FirecrawlApp, ScrapeOptions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from deep_translator import GoogleTranslator | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import re | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Fix import organization Imports should be placed at the top of the file according to PEP8 standards. Move these imports to the top of the file after the initial comments: +from firecrawl import FirecrawlApp, ScrapeOptions
+from deep_translator import GoogleTranslator
+import re
import os
-from firecrawl import FirecrawlApp, ScrapeOptions
-from deep_translator import GoogleTranslator
-import re 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Flake8 (7.2.0)[error] 29-29: module level import not at top of file (E402) [error] 30-30: module level import not at top of file (E402) [error] 31-31: module level import not at top of file (E402) 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def translate_to_spanish(text): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return GoogleTranslator(source='auto', target='es').translate(text) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print("Translation to Spanish failed:", e) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def translate_to_english(text): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Remove Markdown images and None values before translation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
text = str(text).replace("None", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
text = re.sub(r'!\[.*?\]\(.*?\)', '', text) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return GoogleTranslator(source='auto', target='en').translate(text) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print("Translation to English failed:", e) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """# Firecrawl Tool Class""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class FirecrawlTool: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def __init__(self, api_key, instruction: str, template: str): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if not api_key: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ValueError("Firecrawl API key not provided.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.app = FirecrawlApp(api_key=api_key) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.instruction = instruction | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.template = template | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def search(self, search: str) -> str: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if not search or len(search) < 5: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return "Error: Please provide a valid search query (at least 5 characters)." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
response_md = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
search_result = self.app.search( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
query=self.instruction + search, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
limit=2, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
country="cl", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
lang="es", # Always search in Spanish for best results | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
scrape_options=ScrapeOptions(formats=["markdown", "links"]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if search_result and hasattr(search_result, 'data') and search_result.data: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
filtered_results = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result for result in search_result.data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if str(result.get("url", "")).startswith("https://www.chileatiende.gob.cl/fichas") and not str(result.get("url", "")).endswith("pdf") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if filtered_results: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for num, result in enumerate(filtered_results, start=1): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
response_md += self.template.format( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result_number=num, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
page_title=str(result.get("title", "")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
page_url=str(result.get("url", "")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
page_content=str(result.get("markdown", "")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return response_md | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Remove unnecessary else clause The else clause after return is unnecessary and reduces readability. if filtered_results:
for num, result in enumerate(filtered_results, start=1):
response_md += self.template.format(
result_number=num,
page_title=str(result.get("title", "")),
page_url=str(result.get("url", "")),
page_content=str(result.get("markdown", ""))
)
return response_md
- else:
- return None
+ return None 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Pylint (3.3.7)[refactor] 77-87: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (R1705) 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return f"Error during search: {e}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """# Firecrawl Prompt Template""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# FIRECRAWL_INSTRUCTION = "ChileAtiende: " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# FIRECRAWL_TEMPLATE = """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# # Result {result_number} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# ## Page Name: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# "{page_title}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# ## URL: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# {page_url} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# ## Content: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# {page_content} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical Runtime Error: Uncomment template definitions The template variables are commented out but referenced in the initialization code, causing a runtime error. -# FIRECRAWL_INSTRUCTION = "ChileAtiende: "
-# FIRECRAWL_TEMPLATE = """
-# # Result {result_number}
-
-# ## Page Name:
-# "{page_title}"
-
-# ## URL:
-# {page_url}
-
-# ## Content:
-# {page_content}
-
-# """
+FIRECRAWL_INSTRUCTION = "ChileAtiende: "
+FIRECRAWL_TEMPLATE = """
+# Result {result_number}
+
+## Page Name:
+"{page_title}"
+
+## URL:
+{page_url}
+
+## Content:
+{page_content}
+
+""" 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """# Initialize Firecrawl Tool""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
firecrawl_tool = FirecrawlTool( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
api_key=os.environ['FIRECRAWL_API_KEY'], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instruction=FIRECRAWL_INSTRUCTION, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
template=FIRECRAWL_TEMPLATE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# """# Main Chat Loop""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print("Hello! I am your ChileAtiende assistant, Tomás. How can I help you today?") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print("You can ask me, for example: How to renew your ID card, How to apply for the Winter Bonus, etc.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while True: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
user_input = input("\nYou: ") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if user_input.lower() in ["exit", "quit"]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print("Tomás: It was a pleasure to help you. Goodbye!") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
break | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Translate English input to Spanish for Firecrawl | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
spanish_query = translate_to_spanish(user_input) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
spanish_answer = firecrawl_tool.search(spanish_query) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Only translate if we got a real answer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if spanish_answer and isinstance(spanish_answer, str) and spanish_answer.strip() and "Error" not in spanish_answer: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
english_answer = translate_to_english(spanish_answer) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print("\nTomás (in English):\n", english_answer) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print(f"\nTomás: I found information, but couldn't translate it. Here it is in Spanish:\n{spanish_answer}\n(Translation error: {e})") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
print("\nTomás: Sorry, I couldn't find relevant information. Try rephrasing your question or ask about another service.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using more descriptive variable names than just assigning the string "your api key here". This will improve readability and make it clear what the variables are used for. Suggest replacing with a placeholder such as
YOUR_FIRECRAWL_API_KEY
andYOUR_OPENAI_API_KEY
.