Spaces:
Build error
Build error
# ================================ | |
# 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 | |