A while back @John6666 help set up an AI gradio chatbot on my website. Everything was working fine, with the AI chatbot doing a great job.
However, I’ve not been monitoring it, and sometime recently(?) it stopped working. The problem is on the client I get the error:
Access to fetch at [huggingfacespace] from origin [mywebsite] has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The value of the ‘Access-Control-Allow-Credentials’ header in the response is ‘’ which must be ‘true’ when the request’s credentials mode is ‘include’.
After looking around this seems to be related to a change to gradio where they fixed a security issue with CORS. However, the solution I found appeared to suggest the fix was to basically re-write the code to “get around” CORS rather than using it.
It that really the only solution?
This is the code that was working before the “fix” broke it:
(website client code)
<script type="module">
import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client@/dist/index.min.js";
import { marked } from "https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js";
async function initChatWidget() {
const client = await Client.connect("https://[myspace].hf.space/");
const conversationId = crypto.randomUUID(); // NEW FOR LOGGING
const chatToggle = document.getElementById('chat-toggle');
const chatContainer = document.getElementById('chat-container');
const closeChat = document.getElementById('close-chat');
const chatInput = document.getElementById('chat-input');
const sendButton = document.getElementById('send-message');
const messagesContainer = document.getElementById('chat-messages');
chatToggle.addEventListener('click', () => {
chatContainer.classList.remove('hidden');
});
closeChat.addEventListener('click', () => {
chatContainer.classList.add('hidden');
});
// Auto-open chat on contact page
if (window.location.pathname.includes('/contact') ||
window.location.pathname.endsWith('/contact.html') ||
window.location.pathname.includes('/account') ||
window.location.pathname.endsWith('/account.html')) {
chatContainer.classList.remove('hidden');
}
function appendMessage(text, sender) {
const div = document.createElement("div");
div.className = `message ${sender}-message`;
div.textContent = text; // or marked.parse(text) if you're using marked
messagesContainer.appendChild(div);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}
async function sendMessage() {
const userMessage = chatInput.value.trim();
if (!userMessage) return;
appendMessage(userMessage, 'user');
chatInput.value = '';
try {
const result = await client.predict("/chat", {
message: {"text": userMessage, "files": []},
conversation_id: conversationId, // NEW FOR LOGGING
});
const lines = result.data[0]; // list of strings from Python
const botMessage = Array.isArray(lines) ? lines.join("\n") : String(lines);
appendMessage(botMessage, "bot");
} catch (error) {
console.error('Error:', error);
appendMessage('Sorry, there was an error processing your request.', 'bot');
}
}
sendButton.addEventListener('click', sendMessage);
chatInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
// PRE-SEED: show a bot greeting as soon as the widget is ready
appendMessage("Hey there! What can I help you with today?", "bot");
}
initChatWidget();
</script>
(code on huggingface space)
import json
import requests # for API code
import holidays # details of UK holidays
from datetime import datetime, timedelta, date, time
from openai import OpenAI
import gradio as gr
import os
import uuid
say_hello = [
{
"role": "assistant",
"content": "Hey there! What can I help you with today?",
}
]
def chat(message, history, conversation_id):
if not conversation_id:
conversation_id = str(uuid.uuid4())
if isinstance(message, dict): # make sure the user comment is in an acceptable format, and convert to a string
user_text = message.get("text", "")
else:
user_text = str(message)
history = [{"role":h["role"], "content":h["content"]} for h in history] # clean history for some non openai models
messages = [{"role": "system", "content": system_message}] + history + [{"role": "user", "content": user_text}] # illusion of memory
response = openai.chat.completions.create(model=MODEL, messages=messages, tools=tools)
response_as_a_list = [response.choices[0].message.content] # need to change reponse from string to a list of strings for the chatbot widget
return response_as_a_list
conversation_id_input = gr.Textbox(
label="conversation_id",
visible=False,
value="",
)
chatbot = gr.Chatbot(
value=say_hello,
type="messages",
)
my_chat = gr.ChatInterface(
fn=chat,
type="messages",
multimodal=True,
title="Widget Demo Bot",
api_name="chat",
additional_inputs=[conversation_id_input], # extra arg to fn
)
if __name__ == "__main__":
my_chat.launch(ssr_mode=False)