Files
LLM_Engineering_OLD/week1/community-contributions/D2-property-rental-assistant/day2.ipynb
2025-08-15 14:47:31 +01:00

218 lines
7.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "57112e5c-7b0f-4ba7-9022-ae21e8ac0f42",
"metadata": {},
"outputs": [],
"source": [
"# imports\n",
"\n",
"import requests\n",
"from bs4 import BeautifulSoup\n",
"from IPython.display import Markdown, display"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3b71a051-fc0e-46a9-8b1b-b58f685e800d",
"metadata": {},
"outputs": [],
"source": [
"# Constants\n",
"OLLAMA_API = \"http://localhost:11434/api/chat\"\n",
"HEADERS = {\"Content-Type\": \"application/json\"}\n",
"MODEL = \"deepseek-r1:14b\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ed3be9dc-d459-46ac-a8eb-f9b932c4302f",
"metadata": {},
"outputs": [],
"source": [
"headers = {\n",
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36\"\n",
"}\n",
"\n",
"class Website:\n",
" def __init__(self, url):\n",
" self.url = url\n",
" try:\n",
" response = requests.get(url, headers=headers, timeout=10)\n",
" response.raise_for_status()\n",
" soup = BeautifulSoup(response.content, 'html.parser')\n",
" self.title = soup.title.string if soup.title else \"No title found\"\n",
" if soup.body:\n",
" for irrelevant in soup.body([\"script\", \"style\", \"img\", \"input\"]):\n",
" irrelevant.decompose()\n",
" self.text = soup.body.get_text(separator=\"\\n\", strip=True)\n",
" else:\n",
" self.text = \"No body content found\"\n",
" except requests.RequestException as e:\n",
" print(f\"Error fetching website: {e}\")\n",
" self.title = \"Error loading page\"\n",
" self.text = \"Could not load page content\""
]
},
{
"cell_type": "markdown",
"id": "17ea76f8-38d9-40b9-8aba-eb957d690a0d",
"metadata": {},
"source": [
"## Without Ollama package"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3a6fd698-8e59-4cd7-bb53-b9375e50f899",
"metadata": {},
"outputs": [],
"source": [
"def house_renting(system_prompt, user_prompt):\n",
" messages = [\n",
" {\"role\": \"system\", \"content\": system_prompt},\n",
" {\"role\": \"user\", \"content\": user_prompt}\n",
" ]\n",
" payload = {\n",
" \"model\": MODEL,\n",
" \"messages\": messages,\n",
" \"stream\": False\n",
" }\n",
" response = requests.post(OLLAMA_API, json=payload, headers=HEADERS)\n",
" return response.json()['message']['content']"
]
},
{
"cell_type": "markdown",
"id": "c826a52c-d1d3-493a-8b7c-6e75b848b453",
"metadata": {},
"source": [
"## Introducing Ollama package "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "519e27da-eeff-4c1b-a8c6-e680fdf01da2",
"metadata": {},
"outputs": [],
"source": [
"import ollama\n",
"\n",
"def house_renting_ollama(system_prompt, user_prompt):\n",
" try:\n",
" messages = [\n",
" {\"role\": \"system\", \"content\": system_prompt},\n",
" {\"role\": \"user\", \"content\": user_prompt}\n",
" ]\n",
" response = ollama.chat(model=MODEL, messages=messages)\n",
" return response['message']['content']\n",
" except Exception as e:\n",
" return f\"Error communicating with Ollama: {e}\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "60e98b28-06d9-4303-b8ca-f7b798244eb4",
"metadata": {},
"outputs": [],
"source": [
"system_prompt = \"\"\"\n",
"You are a helpful real estate assistant specializing in UK property rentals. Your job is to guide users in finding houses to rent, especially in Durham. Follow these rules:\n",
"1. Always ask clarifying questions if user input is vague. Determine location, budget, number of bedrooms, and tenant type (e.g. student, family, professional).\n",
"2. Use structured data provided from the website (like property listings) to identify relevant options.\n",
"3. If listings are provided, filter and rank them based on the user's preferences.\n",
"4. Recommend up to 5 top properties with rent price, bedroom count, key features, and location.\n",
"5. Always respond in markdown with clean formatting using headers, bold text, and bullet points.\n",
"6. If no listings match well, provide tips (e.g. \"try adjusting your budget or search radius\").\n",
"7. Stay concise, helpful, and adapt to whether the user is a student, family, couple, or solo tenant.\n",
"\"\"\"\n",
"\n",
"def user_prompt_for_renting(website, user_needs):\n",
" return f\"\"\"\n",
"I want to rent a house and here's what I'm looking for:\n",
"{user_needs}\n",
"\n",
"Here are the property listings I found on the website titled: \"{website.title}\".\n",
"\n",
"Please analyze them and recommend the best 35 options that match my needs. If none are suitable, tell me why and offer suggestions.\n",
"\n",
"The page content is below:\n",
"{website.text[:4000]}\n",
"\"\"\" # content is truncated for token limits"
]
},
{
"cell_type": "markdown",
"id": "ef420f4b-e3d2-4fbd-bf6f-811f2c8536e0",
"metadata": {},
"source": [
"## Ollama Package"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1cf128af-4ece-41ab-b353-5c8564c7de1d",
"metadata": {},
"outputs": [],
"source": [
"if __name__ == \"__main__\": \n",
" print(\"Starting AI Property Rental Assistant...\")\n",
" print(\"=\" * 50)\n",
" \n",
" website_url = \"https://www.onthemarket.com/to-rent/property/durham/\"\n",
" print(f\"🔍 Scraping properties from: {website_url}\")\n",
" \n",
" website = Website(website_url)\n",
" print(f\"Website Title: {website.title}\")\n",
" print(f\"Content Length: {len(website.text)} characters\")\n",
" print(f\"Successfully scraped property listings\\n\")\n",
" \n",
" user_needs = \"I'm a student looking for a 2-bedroom house in Durham under £2,000/month\"\n",
" print(f\"User Requirements: {user_needs}\\n\")\n",
" \n",
" user_prompt = user_prompt_for_renting(website, user_needs)\n",
" print(\"Generating AI recommendations...\")\n",
" \n",
" # Choose which method to use (comment out the one you don't want)\n",
" \n",
" # Method 1: Using ollama Python library\n",
" output = house_renting_ollama(system_prompt, user_prompt)\n",
" \n",
" # Method 2: Using direct API call\n",
" # output = house_renting(system_prompt, user_prompt)\n",
" \n",
" display(Markdown(output))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:llms]",
"language": "python",
"name": "conda-env-llms-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}