Top Ad unit 728 × 90

Welcome !!! To The World of Programming

OOPS FEATURES

Oops

Connecting Flask Web Client to Flask REST API

 Build a Flask Web App with Secure MySQL Login (REST API + Frontend)

Today, we are creating a simple Flask web client to consume our earlier API services.

We will demonstrate login, dashboard, admin panel access — all using JWT authentication!

You'll see how Frontend and Backend work together securely.

What is a Web Client?

A web client is the gateway between users and your backend.

A web client is a software application or interface that requests and displays data from a web server, enabling users to interact with websites, web apps, or APIs.

It acts as the frontend that users see and interact with, while communicating with backend servers to fetch or submit data.

How a Web Client Works ?

Sends a Request → Uses HTTP/HTTPS (e.g., GET /users).

Receives a Response → Gets data (HTML, JSON, XML) from the server.

Renders/Processes Data → Displays it to the user or performs actions


What is JSON? (JavaScript Object Notation):

JSON (JavaScript Object Notation) is a lightweight data  interchange format used to store and transmit structured  data between systems.

It is human-readable and machine-parsable, making it ideal for APIs, configuration files, and web applications.

Key Features of JSON

Text-Based – Uses plain text to represent data.
Language-Independent – Works with any programming language.
Easy to Read & Write – Simple syntax similar to JavaScript objects.
Supports Nested Data – Can represent complex structures.

HTML Forms: A Complete Guide:

HTML forms are essential for collecting user input on websites. They enable login systems, registration, contact forms, surveys, and more.

HTMLforms are the backbone of user interaction on the web. Whether you're building a login page, survey, or checkout system, mastering forms is crucial for web development.

Directory Structure of Web client

WebClientApp/

├── client.py

├── templates/

│   ├── base.html

│   ├── login.html

│   ├── register.html

│   ├── dashboard.html

│   ├── admin_panel.html

├── static/

│   └── style.css (optional)

The code for client.py is as under:


from flask import Flask, render_template, request, redirect, url_for, session, flash
import requests

app = Flask(__name__)
app.secret_key = 'testapi'  # Important for session management

# API URL (adjust if hosted elsewhere)
API_BASE_URL = "http://localhost:5000"

# Home Route
@app.route('/')
def home():
    return redirect(url_for('login'))

# Register Page
@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        data = {
            "username": request.form['username'],
            "password": request.form['password'],
            "role": request.form['role']
        }
        response = requests.post(f"{API_BASE_URL}/register", json=data)
        if response.status_code == 201:
            flash('Registered successfully! Please log in.', 'success')
            return redirect(url_for('login'))
        else:
            flash(response.json().get('error', 'Registration failed.'), 'danger')
    return render_template('register.html')

# Login Page
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        data = {
            "username": request.form['username'],
            "password": request.form['password']
        }
        response = requests.post(f"{API_BASE_URL}/login", json=data)
        if response.status_code == 200:
            session['token'] = response.json()['access_token']
            flash('Logged in successfully!', 'success')
            return redirect(url_for('dashboard'))
        else:
            flash(response.json().get('error', 'Login failed.'), 'danger')
    return render_template('login.html')

# Dashboard Page (Protected)
@app.route('/dashboard')
def dashboard():
    token = session.get('token')
    if not token:
        flash('Please log in first.', 'warning')
        return redirect(url_for('login'))
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(f"{API_BASE_URL}/dashboard", headers=headers)
    if response.status_code == 200:
        return render_template('dashboard.html', data=response.json())
    else:
        flash(response.json().get('error', 'Access denied.'), 'danger')
        return redirect(url_for('login'))

# Admin Panel (Protected for Admin Role)
@app.route('/admin')
def admin_panel():
    token = session.get('token')
    if not token:
        flash('Please log in first.', 'warning')
        return redirect(url_for('login'))
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(f"{API_BASE_URL}/admin", headers=headers)
    if response.status_code == 200:
        return render_template('admin_panel.html', data=response.json())
    else:
        flash(response.json().get('error', 'Access denied.'), 'danger')
        return redirect(url_for('dashboard'))

# Logout
@app.route('/logout')
def logout():
    session.clear()
    flash('Logged out successfully.', 'success')
    return redirect(url_for('login'))

if __name__ == "__main__":
    app.run(port=5001, debug=True)



1) base.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Flask Web Client{% endblock %}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Web Client</a>
  <div class="collapse navbar-collapse">
    <ul class="navbar-nav ml-auto">
      {% if session.token %}
      <li class="nav-item"><a class="nav-link" href="{{ url_for('dashboard') }}">Dashboard</a></li>
      <li class="nav-item"><a class="nav-link" href="{{ url_for('admin_panel') }}">Admin Panel</a></li>
      <li class="nav-item"><a class="nav-link" href="{{ url_for('logout') }}">Logout</a></li>
      {% else %}
      <li class="nav-item"><a class="nav-link" href="{{ url_for('login') }}">Login</a></li>
      <li class="nav-item"><a class="nav-link" href="{{ url_for('register') }}">Register</a></li>
      {% endif %}
    </ul>
  </div>
</nav>

<div class="container mt-4">
    {% with messages = get_flashed_messages(with_categories=true) %}
      {% if messages %}
        {% for category, message in messages %}
          <div class="alert alert-{{ category }}">{{ message }}</div>
        {% endfor %}
      {% endif %}
    {% endwith %}

    {% block content %}{% endblock %}
</div>

</body>
</html>




2) login.html


{% extends "base.html" %}
{% block title %}Login{% endblock %}
{% block content %}
<h2>Login</h2>
<form method="POST">
    <div class="mb-3">
        <label>Username:</label>
        <input type="text" name="username" class="form-control" required>
    </div>
    <div class="mb-3">
        <label>Password:</label>
        <input type="password" name="password" class="form-control" required>
    </div>
    <button type="submit" class="btn btn-primary">Login</button>
</form>
{% endblock %}



3) register.html



{% extends "base.html" %}
{% block title %}Register{% endblock %}
{% block content %}
<h2>Register</h2>
<form method="POST">
    <div class="mb-3">
        <label>Username:</label>
        <input type="text" name="username" class="form-control" required>
    </div>
    <div class="mb-3">
        <label>Password:</label>
        <input type="password" name="password" class="form-control" required>
    </div>
    <div class="mb-3">
        <label>Role:</label>
        <select name="role" class="form-control" required>
            <option value="user">User</option>
            <option value="admin">Admin</option>
        </select>
    </div>
    <button type="submit" class="btn btn-success">Register</button>
</form>
{% endblock %}



4) dashboard.html


{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<h2>Dashboard</h2>
<p>Welcome to the user dashboard!</p>
<pre>{{ data | tojson(indent=2) }}</pre>
{% endblock %}



5) admin_panel.html


{% extends "base.html" %}
{% block title %}Admin Panel{% endblock %}
{% block content %}
<h2>Admin Panel</h2>
<p>Welcome, Admin!</p>
<pre>{{ data | tojson(indent=2) }}</pre>
{% endblock %}


Connecting Flask Web Client to Flask REST API Reviewed by Syed Hafiz Choudhary on May 07, 2025 Rating: 5

No comments:

Contact Form

Name

Email *

Message *

Powered by Blogger.
!-- JavaScript for Ad Block Detection -->