Skip to main content
April 2, 2026Brian McClain/8 min read

JavaScript and Python Flask for AI Chat Applications

Building Real-Time AI Chat with JavaScript and Flask

Course Overview

This lesson demonstrates how to create a full round-trip communication between JavaScript frontend and Python Flask backend for AI chat applications, serving as a crucial stepping stone before integrating with the OpenAI API.

Learning Path Progression

1

Static Chat Interface

Previous lessons covered basic chat UI where users could only talk to themselves without server communication

2

Fetch Communication Setup

Current lesson focuses on establishing POST requests between JavaScript and Flask with JSON data exchange

3

AI Integration Ready

Next step will involve sending user messages to OpenAI API and receiving real AI responses

Key Technologies in This Tutorial

JavaScript Fetch API

Handles asynchronous HTTP requests to send user chat messages as JSON data to Flask backend routes.

Python Flask Framework

Lightweight web framework that receives POST requests and returns JSON responses for chat functionality.

JSON Data Exchange

Structured data format used for sending conversation data back and forth between frontend and backend.

GET vs POST Methods for Chat Data

FeatureGET MethodPOST Method
Data LocationURL query stringRequest body
JSON SupportNot suitableFull support
Data VisibilityVisible in URLHidden transmission
Chat ApplicationsNot recommendedRequired method
Recommended: POST method is essential for chat applications as it supports invisible JSON transmission required for conversation data.

JavaScript Fetch Implementation Process

1

Setup File Structure

Save existing index06.html as index09.html and script06.js as script09.js to build upon previous work

2

Configure Fetch Request

Set method to POST, add content-type headers as application/json, and prepare request body

3

Stringify User Message

Use JSON.stringify to convert user input object with userMessage property into transmittable format

4

Target Flask Route

Direct fetch request to '/chat' route that will be created in Flask backend server

Headers Configuration

The content-type: application/json header tells Flask what type of data is incoming, enabling it to use the correct parsing engine for processing the request body.

Flask Server Setup From Scratch

1

Import Dependencies

Import Flask, render_template, and jsonify from Flask framework for web server functionality

2

Create App Instance

Instantiate Flask app using app = Flask(__name__) to initialize the web server

3

Define Home Route

Create route for '/' that renders index09.html containing the chat interface

4

Build Chat Route

Create '/chat' route with methods=['POST'] to receive and respond to chat messages

Route Method Configuration

Remember to add methods=['POST'] to the chat route in Flask, even though the initial implementation ignores incoming data. This matches the POST method specified in the JavaScript fetch request.

Response Handling Implementation

0/6

Simulated AI Response Approach

Pros
Establishes complete round-trip communication pattern
Allows testing of frontend and backend integration
Provides foundation for real AI implementation
Enables debugging of JSON data exchange
Creates working chat interface for demonstration
Cons
Returns same static message regardless of input
Does not process or analyze user messages
Requires additional work to integrate real AI
May confuse users expecting intelligent responses
Development Strategy

Using a simulated AI response is a necessary stepping stone that allows developers to perfect the communication infrastructure before adding the complexity of real AI integration.

This lesson is a preview from our Python for AI Course Online (includes software) and Python Certification Course Online (includes software & exam). Enroll in a course for detailed lessons, live instructor support, and project-based training.

Welcome back to Python for AI applications with the OpenAI API and Flask, integrated with JavaScript. I'm Brian McLean, and in this lesson, we'll tackle a fundamental aspect of modern web development: establishing bidirectional communication between your frontend and backend.

Specifically, we're implementing the ability to send user chat messages from the webpage to our Flask server using JavaScript's fetch method with POST requests. In our previous lesson, we established basic connectivity—fetch was hitting our Flask route successfully, but only to receive data, not send it. Now we're building the foundation for true conversational AI by enabling message transmission from user to server.

This is Lesson 9, where we transition from passive data consumption to active data exchange. We're returning to our Greenleaf Tree Nursery website with its AI chat assistant interface. When users type a message and click send, that message will now be transmitted via a POST request to our Flask backend—not just displayed locally in the chat window.

The architecture we're building follows industry-standard patterns: the frontend captures user input, packages it as JSON, and transmits it to our custom `/chat` endpoint. Our Flask server will receive this data and return a JSON response simulating an AI reply. While we're not yet connecting to OpenAI's API (that's our next milestone), this lesson establishes the critical communication pipeline that every production chat application requires.

This bidirectional flow—user input → JavaScript → Flask → JSON response → display—represents the backbone of modern conversational interfaces, from customer service bots to sophisticated AI assistants.

Lesson 9: JavaScript fetch and Python Flask Chat Round Trip

We'll implement a complete request-response cycle using JavaScript fetch to transmit chat data as JSON to our Flask backend. The chat data originates from user input in the Greenleaf AI assistant interface—that familiar input box where users type their questions and comments.

Our implementation includes four core components: a Flask route designed to receive JSON data from our JavaScript fetch requests, JSON response handling that simulates AI responses, frontend display logic that renders the simulated AI response in properly formatted chat bubbles, and conversation persistence that maintains the chat flow through multiple message exchanges.

Each user message will generate a corresponding AI response bubble, creating the familiar pattern of alternating user and AI messages. While our initial AI responses will be static (the same message each time), this establishes the essential infrastructure for integrating with OpenAI's API in subsequent lessons.

Step 1: Implementing JavaScript Fetch for JSON Data Transmission

The JavaScript fetch method serves as our primary tool for server communication, enabling asynchronous HTTP requests without page refreshes—a cornerstone of modern single-page application architecture. We'll configure fetch to send the user's complete chat message along with conversation context to our Flask `/chat` endpoint.

This approach mirrors production chat applications where each request includes both the immediate user input and sufficient context for the AI to maintain conversational coherence. Let's begin by creating our updated files, building upon our previous work while adding the new communication layer.

Start by creating a new version of your existing files: save `index06.html` as `index09.html`, ensuring you update the script reference to `script09.js`. Similarly, save `script06.js` as `script09.js`. This versioning approach allows you to maintain working previous versions while developing new features—a best practice in both learning and professional development.

In `script09.js`, rename your function from the previous version to `chat()`, reflecting its new bidirectional capability. Update both the event listener and function definition to use this new name. The function will continue to capture user input and validate that users haven't clicked send without typing anything, but now it will also initiate server communication.


The enhanced chat function includes our fetch implementation at its conclusion. Configure fetch with the POST method, as we're transmitting data rather than simply requesting it. GET requests can include data in URL query strings, but JSON data requires POST transmission for security and data integrity reasons.

Your fetch configuration should target `/chat` as the endpoint, with method set to "POST". Include a headers object specifying `"Content-Type": "application/json"` to inform Flask about the incoming data format. This header ensures Flask activates the appropriate JSON parsing mechanisms.

The request body contains your JSON payload, created using `JSON.stringify()` to convert a JavaScript object into a JSON string. Your object should include a `userMessage` property containing the user's input. Note the syntax differences between JavaScript and Python: JavaScript object keys don't require quotes during object creation, while Python dictionary keys must be quoted.

Building the Python Flask Server Infrastructure

Now we'll construct the Python Flask server that receives and processes our JavaScript requests. Starting from scratch reinforces understanding of Flask's architecture and ensures you can build these servers confidently in your own projects.

Create a new file named `server09.py`. Begin with the essential Flask imports: `Flask`, `render_template`, and `jsonify`. The `jsonify` function will be particularly important for formatting our responses in the JSON format our JavaScript expects.

Initialize your Flask application with `app = Flask(__name__)`, where the `__name__` variable provides Flask with important context about your application's location and configuration. Define your home route (`@app.route("/")`) to serve the `index09.html` file via `render_template()`.

The crucial addition is your chat route: `@app.route("/chat", methods=["POST"])`. The `methods=["POST"]` parameter is essential—it tells Flask this route accepts POST requests containing data. Without this specification, Flask assumes GET-only routes, which would generate a "405 Method Not Allowed" error when your JavaScript attempts to POST data.

For now, your chat route function can ignore the incoming JSON data (we'll parse it in the next lesson) and simply return a consistent response using `jsonify(aiMessage="AI says: Let's chat!")`. This creates a JSON object with an `aiMessage` property that your JavaScript can parse and display.

Complete your server with the standard Flask application runner: `if __name__ == "__main__": app.run(debug=True)`. The debug mode provides helpful error messages during development—invaluable for troubleshooting as you build more complex functionality.

Handling Server Responses in JavaScript

Back in your JavaScript file, chain `.then()` methods to your fetch call to handle the server response. The first `.then()` receives the raw response and parses it into a JavaScript object using `response.json()`. The second `.then()` receives this parsed object and handles the actual AI message display.

Create a new chat bubble element for the AI response, similar to your user message bubbles but with distinct styling. Set the bubble's `className` to "chat-bubble" for consistent base styling, then differentiate it with a background color—perhaps a subtle green like "#EFE" to distinguish AI responses from user messages.


Set the bubble's `textContent` to `responseObj.aiMessage` (matching the property name from your Flask jsonify response), then append it to your chat window with `chatWindow.appendChild(aiChatBubble)`.

Enhance the user experience with several finishing touches: add a `.catch()` method to handle potential network errors gracefully, clear the input box after successful message sending with `inputBox.value = ""`, and implement auto-scrolling with `chatWindow.scrollTop = chatWindow.scrollHeight` to ensure new messages remain visible without manual scrolling.

Testing and Troubleshooting Your Implementation

Launch your Flask server with `python server09.py` and navigate to the server URL (typically `http://localhost:5000`). Test the complete flow by typing a message and clicking send. You should see your user message appear, followed immediately by the AI response: "AI says: Let's chat!"

Common issues include syntax errors in your fetch configuration (remember to use commas, not semicolons, in JavaScript objects), CORS errors from accessing files directly rather than through the Flask server, and 405 Method Not Allowed errors if you forget the `methods=["POST"]` parameter in your Flask route.

Each subsequent message will generate the same AI response, creating a somewhat one-sided conversation. This is intentional—we're establishing the communication infrastructure before adding the complexity of dynamic AI responses.

Understanding the Complete Data Flow

What you've built represents the fundamental architecture of modern chat applications. User input is captured client-side, transmitted securely to your server via POST requests, processed by your backend logic, and returned as structured JSON for frontend rendering.

While we're not yet utilizing the incoming message data in our Flask route, you're sending it with each request, laying the groundwork for our next lesson where we'll parse that data and forward it to OpenAI's API for genuine AI responses.

This pattern—capture, transmit, process, respond—scales from simple chat bots to enterprise-level conversational AI systems. You've just implemented the same communication architecture used by production applications serving millions of users daily.

In Lesson 10, we'll complete the AI chat assistant by integrating with OpenAI's API, transforming your static responses into dynamic, context-aware AI interactions. The infrastructure you've built today will seamlessly support that enhancement, demonstrating the value of well-architected communication layers in modern web development.

Key Takeaways

1JavaScript fetch with POST method is required for sending JSON chat data to Flask backend servers
2Flask routes receiving JSON data must specify methods=['POST'] and use jsonify for responses
3The content-type: application/json header enables proper server-side parsing of request bodies
4JSON.stringify converts JavaScript objects into transmittable string format for server communication
5Two chained .then() methods handle response parsing and UI updates in the correct sequence
6Auto-scroll functionality using scrollTop and scrollHeight improves user experience in chat interfaces
7Simulated AI responses provide essential testing infrastructure before real AI API integration
8Error handling with .catch() method is considered best practice for fetch request debugging

RELATED ARTICLES