daysoff_expanse_system / api_data.py
camparchimedes's picture
Update api_data.py
46de342 verified
# ================================
# api-data.py
# ================================
import json
import asyncio
import os
import re
import requests
import chainlit as cl
from dotenv import load_dotenv
# --------------------------------=== API URL ===-----------------------------------
API_URL = "https://firmahytte.daysoff.no/api/bookings"
# --------------------------------=== environment ===-------------------------------
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
token = os.environ.get("DAYSOFF_API_TOKEN")
# ----------------------------=== API error-handling ===--------------------------------
class APIConnectionError(Exception):
"""Raised when API connection fails"""
pass
class APIResponseError(Exception):
"""Raised when API returns an invalid response"""
pass
class BookingNotFoundError(Exception):
"""Raised when booking ID is not found"""
pass
async def async_post_request(url, headers, data):
try:
response = await asyncio.to_thread(requests.post, url, headers=headers, json=data)
response.raise_for_status()
return response
except requests.ConnectionError:
raise APIConnectionError("Failed to connect to booking service")
except requests.Timeout:
raise APIConnectionError("Request timed out")
except requests.RequestException as e:
raise APIResponseError(f"API request failed: {str(e)}")
# ----------------------------=== booking_agent_system ===------------------------------
async def booking_agent_system(message: cl.Message, msg: cl.Message) -> bool:
user_message = message.content # -- doc: extract message text
booking_pattern = r'\b[A-Z]{6}\d{6}\b' # -- raw string (r'')
match = re.search(booking_pattern, user_message)
if match:
preliminary = (
f"Takk for bookingnummer ๐Ÿ‘๐Ÿป "
"Jeg skal sjekke dette for deg nรฅ. Vennligst et รธyeblikk bare..\n"
)
for token in preliminary.split():
await msg.stream_token(token + " ") # --โ€”โ€”> streams each token
await asyncio.sleep(0.05) # --โ€”โ€”> simulates d/-streaming delay
await msg.send()
bookingnumber = match.group()
headers = {
'Authorization': f"Bearer {token}",
"Content-Type": "application/json"
}
payload = {
"token": "0v8mYvhh22REJidE2foWvlu2YQd",
"bookingnumber": bookingnumber
}
try:
response = await async_post_request(API_URL, headers, payload)
response.raise_for_status()
response_data = response.json()
booking_data = response_data.get('data', {})
print("API Response Data:", json.dumps(booking_data, indent=2))
if not booking_data:
raise BookingNotFoundError("Ingen booking funnet med dette bookingnummeret.")
if "error" in booking_data:
raise APIResponseError(booking_data["error"])
table = (
"\n\n## ๐˜ฝ๐™ค๐™ค๐™ ๐™ž๐™ฃ๐™œ ๐™ž๐™ฃ๐™›๐™ค๐™ง๐™ข๐™–๐™จ๐™Ÿ๐™ค๐™ฃ\n\n"
f"| ๐ต๐‘œ๐‘œ๐‘˜๐‘–๐‘›๐‘”๐‘›๐‘ข๐‘š๐‘š๐‘’๐‘Ÿ | {booking_data.get('order_number', 'N/A')} |\n"
f"|:-----|:------------------|\n"
f"| ๐™‰๐™–๐™ข๐™š | {booking_data.get('name', 'N/A')} |\n"
f"| ๐™๐™ž๐™ข๐™š ๐™๐™ง๐™ค๐™ข | {booking_data.get('time_from', 'N/A')} |\n"
f"| ๐˜ผ๐™ง๐™ง๐™ž๐™ซ๐™–๐™ก ๐™๐™ž๐™ข๐™š | {booking_data.get('timearrival', 'N/A')} |\n"
f"| ๐™๐™ž๐™ข๐™š ๐™๐™ค | {booking_data.get('time_to', 'N/A')} |\n"
f"| ๐˜ฟ๐™š๐™ฅ๐™–๐™ง๐™ฉ๐™ช๐™ง๐™š ๐™๐™ž๐™ข๐™š| {booking_data.get('timedeparture', 'N/A')} |\n"
f"| ๐™๐™ž๐™ข๐™š๐™ฏ๐™ค๐™ฃ๐™š | {booking_data.get('timezone', 'N/A')} |\n"
f"| ๐˜ผ๐™™๐™ง๐™š๐™จ๐™จ | {booking_data.get('adress', 'N/A')} |\n"
f"| ๐™•๐™ž๐™ฅ ๐˜พ๐™ค๐™™๐™š | {booking_data.get('zip', 'N/A')} |\n"
f"| ๐™‹๐™ก๐™–๐™˜๐™š | {booking_data.get('place', 'N/A')} |\n"
f"| ๐˜พ๐™ค๐™ช๐™ฃ๐™ฉ๐™ง๐™ฎ | {booking_data.get('country', 'N/A')} |\n"
f"| ๐™‡๐™ค๐™˜๐™–๐™ฉ๐™ž๐™ค๐™ฃ | Lat: {booking_data.get('lat', 'N/A')}, Long: {booking_data.get('long', 'N/A')} |\n"
f"| ๐™‚๐™ช๐™š๐™จ๐™ฉ๐™จ | {booking_data.get('guests', 'N/A')} |\n"
f"| ๐™‚๐™ช๐™š๐™จ๐™ฉ ๐™Ž๐™ช๐™ข | {booking_data.get('guest_sum', 'N/A')} |\n"
f"| ๐˜พ๐™ค๐™ข๐™ฅ๐™–๐™ฃ๐™ฎ ๐˜พ๐™ค๐™ฃ๐™ฉ๐™ง.| {booking_data.get('company_contribution', 'N/A')} |\n"
f"| ๐™‹๐™–๐™ž๐™™ | {booking_data.get('paid', 'N/A')} |\n"
f"| ๐˜ผ๐™˜๐™˜๐™š๐™ฅ๐™ฉ๐™š๐™™ | {booking_data.get('accepted', 'N/A')} |\n"
f"| ๐˜พ๐™–๐™ฃ๐™˜๐™š๐™ก๐™ก๐™š๐™™ | {'Yes' if booking_data.get('cancelled', 0) else 'No'} |\n"
f"| ๐˜พ๐™ค๐™ฃ๐™ฉ๐™–๐™˜๐™ฉ ๐™‰๐™–๐™ข๐™š | {booking_data.get('contactname', 'N/A')} |\n"
f"| ๐˜พ๐™ค๐™ฃ๐™ฉ๐™–๐™˜๐™ฉ ๐™€๐™ข๐™–๐™ž๐™ก| {booking_data.get('contactemail', 'N/A')} |\n"
f"| ๐˜พ๐™ค๐™ฃ๐™ฉ๐™–๐™˜๐™ฉ ๐™‹๐™๐™ค๐™ฃ๐™š| {booking_data.get('contactphone', 'N/A')} |\n"
f"| ๐˜พ๐™ค๐™ช๐™ฃ๐™ฉ๐™ง๐™ฎ ๐˜พ๐™ค๐™™๐™š | {booking_data.get('country_code', 'N/A')} |\n"
)
await msg.stream_token(table)
await asyncio.sleep(0.07)
await msg.send()
header = (
"\n\n# ๐—ฉ๐—ถ๐—ธ๐˜๐—ถ๐—ด ๐—œ๐—ป๐—ณ๐—ผ๐—ฟ๐—บ๐—ฎ๐˜€๐—ท๐—ผ๐—ป ๐—ผ๐—บ ๐—ข๐—ฝ๐—ฝ๐—ต๐—ผ๐—น๐—ฑ๐—ฒ๐˜\n\n"
)
await msg.stream_token(header)
await asyncio.sleep(0.07)
await msg.send()
# ๐˜ฟ๐™š๐™จ๐™˜๐™ง๐™ž๐™ฅ๐™ฉ๐™ž๐™ค๐™ฃ
markdown = (
"\n\n# ๐Ÿ‡ฉ ๐Ÿ‡ช ๐Ÿ‡ธ ๐Ÿ‡จ ๐Ÿ‡ท ๐Ÿ‡ฎ ๐Ÿ‡ต ๐Ÿ‡น ๐Ÿ‡ฎ ๐Ÿ‡ด ๐Ÿ‡ณ\n\n"
f"{booking_data.get('description', 'N/A')}\n\n"
f"โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”"
"\n\n# ๐Ÿ‡ฆ ๐Ÿ‡ท ๐Ÿ‡ท ๐Ÿ‡ฎ ๐Ÿ‡ป ๐Ÿ‡ฆ ๐Ÿ‡ฑ\n\n"
f"{booking_data.get('arrival', 'N/A')}\n\n"
f"โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”"
"\n\n# ๐Ÿ‡ฉ ๐Ÿ‡ช ๐Ÿ‡ต ๐Ÿ‡ฆ ๐Ÿ‡ท ๐Ÿ‡น ๐Ÿ‡บ ๐Ÿ‡ท ๐Ÿ‡ช\n\n"
f"{booking_data.get('departure', 'N/A')}\n\n"
f"โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”"
"\n\n# ๐Ÿ‡ง ๐Ÿ‡ช ๐Ÿ‡ฉ ๐Ÿ‡ฉ ๐Ÿ‡ฎ ๐Ÿ‡ณ ๐Ÿ‡ฌ\n\n"
f"{booking_data.get('bedding', 'N/A')}"
)
await msg.stream_token(markdown)
await asyncio.sleep(0.07)
await msg.send()
except (APIConnectionError, APIResponseError, BookingNotFoundError) as e:
error_msg = (
f"๐Ÿ™„ {str(e)} "
)
for token in error_msg.split():
await msg.stream_token(token + " ")
#await asyncio.sleep(0.01)
await msg.send()
return True
except requests.exceptions.RequestException as e:
unexpected = (
f"๐Ÿคฏ {str(e)} "
"En uventet feil oppstod. Vennligst kontakt Daysoff tech support"
)
for token in unexpected.split():
await msg.stream_token(token + " ")
#await asyncio.sleep(0.01)
await msg.send()
return True