From b42b879761b61ff464fdae20cd1ce496f32359ce Mon Sep 17 00:00:00 2001 From: Madhu Date: Thu, 13 Feb 2025 04:29:26 +0530 Subject: [PATCH] few additions --- .../ai_real_estate_agent.cpython-312.pyc | Bin 0 -> 10664 bytes .../ai_real_estate_agent.py | 24 ++++++++-------- .../ai_real_estate_agent/requirements.txt | 3 ++ .../test_property_agent.py | 26 ++++++++++++++++++ 4 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 ai_agent_tutorials/ai_real_estate_agent/__pycache__/ai_real_estate_agent.cpython-312.pyc create mode 100644 ai_agent_tutorials/ai_real_estate_agent/test_property_agent.py diff --git a/ai_agent_tutorials/ai_real_estate_agent/__pycache__/ai_real_estate_agent.cpython-312.pyc b/ai_agent_tutorials/ai_real_estate_agent/__pycache__/ai_real_estate_agent.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2292b9bb2897f16e18fd23e2c06e441ff0ee4fa GIT binary patch literal 10664 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 G&i?`{ECSO2 literal 0 HcmV?d00001 diff --git a/ai_agent_tutorials/ai_real_estate_agent/ai_real_estate_agent.py b/ai_agent_tutorials/ai_real_estate_agent/ai_real_estate_agent.py index 75dca1a..28412b8 100644 --- a/ai_agent_tutorials/ai_real_estate_agent/ai_real_estate_agent.py +++ b/ai_agent_tutorials/ai_real_estate_agent/ai_real_estate_agent.py @@ -26,12 +26,12 @@ class FirecrawlResponse(BaseModel): status: str expiresAt: str -class PriceFindingAgent: +class PropertyFindingAgent: """Agent responsible for finding properties and providing recommendations""" - def __init__(self, firecrawl_api_key: str): + def __init__(self, firecrawl_api_key: str, openai_api_key: str): self.agent = Agent( - model=OpenAIChat(id="o3-mini"), + model=OpenAIChat(id="o3-mini", api_key=openai_api_key), markdown=True, description="I am a real estate expert who helps find and analyze properties based on user preferences." ) @@ -52,7 +52,6 @@ class PriceFindingAgent: f"https://www.99acres.com/property-in-{formatted_location}-ffid/*", f"https://housing.com/in/buy/{formatted_location}/{formatted_location}", f"https://www.squareyards.com/sale/property-for-sale-in-{formatted_location}/*", - f"https://www.nobroker.in/*", f"https://www.nobroker.in/property/sale/{city}/{formatted_location}", f"https://www.magicbricks.com/*" ] @@ -62,7 +61,7 @@ class PriceFindingAgent: raw_response = self.firecrawl.extract( urls=urls, params={ - 'prompt': f"""Extract {property_category} {property_type_prompt} from {city} that cost less than {max_price} crores. + 'prompt': f"""Extract at least 2-3 different {property_category} {property_type_prompt} from {city} that cost less than {max_price} crores. Requirements: - Property Category: {property_category} properties only @@ -70,11 +69,11 @@ class PriceFindingAgent: - Location: {city} - Maximum Price: {max_price} crores - Include complete property details with exact location + - IMPORTANT: Return at least 2 different property listings """, 'schema': PropertyData.model_json_schema() - } - ) - + } ) + print(raw_response) # Process the properties data properties = [] if isinstance(raw_response, dict): @@ -83,7 +82,7 @@ class PriceFindingAgent: elif isinstance(raw_response, list): responses = [FirecrawlResponse(**item) for item in raw_response] properties = [resp.data for resp in responses] - + print(properties) # Now use the agent to analyze and provide recommendations properties_context = "\n".join([ f"Property: {p['Building_name']}\nPrice: {p['Price']}\nLocation: {p['location_address']}\nType: {p['Property_type']}\nDescription: {p['Description']}" @@ -114,9 +113,9 @@ class PriceFindingAgent: class MarketAnalysisAgent: """Agent responsible for analyzing market trends and conditions""" - def __init__(self, firecrawl_api_key: str): + def __init__(self, firecrawl_api_key: str, openai_api_key: str): self.agent = Agent( - model=OpenAIChat(id="o3-mini"), + model=OpenAIChat(id="o3-mini", api_key=openai_api_key), markdown=True, description="I am a real estate market analyst who provides insights on market trends and conditions." ) @@ -186,10 +185,11 @@ class MarketAnalysisAgent: def main(): """Main function to demonstrate the agents""" firecrawl_api_key = "YOUR_FIRECRAWL_API_KEY" + openai_api_key = "OPENAI_API_KEY" try: # Initialize agents - property_agent = PriceFindingAgent(firecrawl_api_key) + property_agent = PropertyFindingAgent(firecrawl_api_key, openai_api_key) market_agent = MarketAnalysisAgent(firecrawl_api_key) # Get property recommendations diff --git a/ai_agent_tutorials/ai_real_estate_agent/requirements.txt b/ai_agent_tutorials/ai_real_estate_agent/requirements.txt index e69de29..9233a09 100644 --- a/ai_agent_tutorials/ai_real_estate_agent/requirements.txt +++ b/ai_agent_tutorials/ai_real_estate_agent/requirements.txt @@ -0,0 +1,3 @@ +agno +firecrawl +pydantic \ No newline at end of file diff --git a/ai_agent_tutorials/ai_real_estate_agent/test_property_agent.py b/ai_agent_tutorials/ai_real_estate_agent/test_property_agent.py new file mode 100644 index 0000000..fb65f78 --- /dev/null +++ b/ai_agent_tutorials/ai_real_estate_agent/test_property_agent.py @@ -0,0 +1,26 @@ +from ai_real_estate_agent import PropertyFindingAgent + +def test_property_agent(): + # Initialize the agent with your Firecrawl and OpenAI API keys + agent = PropertyFindingAgent( + firecrawl_api_key="", # Replace with your Firecrawl key + openai_api_key="" + ) + + try: + # Test property search + results = agent.find_properties( + city="Visakhapatnam", + max_price=4.0, + property_category="Residential", + property_type="Individual House" + ) + + print("\n=== Property Search Results ===") + print(results.content) + + except Exception as e: + print(f"Error during testing: {str(e)}") + +if __name__ == "__main__": + test_property_agent() \ No newline at end of file