Join our WhatsApp Channel
Cart / 0.00$

No products in the cart.

Visit Support Portal
No Result
View All Result
Wednesday, July 15, 2026
  • Home
  • Tutorials
    • Machine Learning
    • Python
    • Web Development
    • Javascript
    • Mathematics
    • Deep Learning
    • Artificial Intelligence
  • Store
  • Our ServicesBook Now
    • Managed Hosting Services
    • Web Development Services
  • Our Softwares
    • JaggoRe AIFree
    • Email ExtractorPaid
    • TimeWell AppFree
Get a Free Quote
  • Login
  • Register
Neuraldemy
Wednesday, July 15, 2026
Cart / 0.00$

No products in the cart.

No Result
View All Result
Neuraldemy
Get A Free Quote
Home Free

How To Create A Signup And Login Form In Python With Validation

Python Tutorial For Registration form and Login Form

Neuraldemy by Neuraldemy
November 29, 2023 - Updated on July 10, 2026
in Python
Reading Time: 31 mins read
A A
How To Create A Signup And Login Form In Python With Validation

In this post, you will see how you can design your own signup and login form in Python with user validation and start building your own apps. Before we go to the production approach, we first need to see the beginners model and then part 2 covers the production part.

Table of Contents

  • Prerequisites:
  • What You Will Learn:
  • Part 1: Beginner Level For Practice
  • Part 2: Advanced Level (Close To Production)
    • Step 1: Establishing a Persistent Database
    • Step 2: Securing Passwords with Hashing
    • Step 3: Object-Oriented System Architecture
    • Step 4: The Advanced Signup Form
    • Step 5: The Secure Login System
    • Step 6: Advanced Account Management (Editor Status & Archiving)

Prerequisites:

  1. Familiarity with Python functions, classes, and little bit about sqlite3.
  2. Familiarity with Regex.
  3. Understanding of user input validation.
  4. Understanding of error validation.

What You Will Learn:

  1. How to transition from temporary dictionaries to a persistent relational database using sqlite3.
  2. How to design a database schema suited for complex administrative platforms (including hierarchical roles and statuses).
  3. How to implement strong password security using Python’s hashlib library.
  4. How to use Regular Expressions (Regex) for strict, reliable email validation.
  5. How to encapsulate your logic within Python Classes for clean, modular, and reusable code.
  6. How to handle real-world account management, such as archiving users or toggling editor statuses, rather than just hard-deleting them.

Part 1: Beginner Level For Practice

So, let’s get started.

First of all, we are going to import the regex for email validation and create a database. Here I am using a simple dictionary but you can use Pandas or other database tools based on SQL as per the projects this is sufficient to show you how you can interact with the database.

import re
#create a database for users 
users = {}

Next, we are going to write a function to allow users to sign up:

# create a signup form
def signup():
    
    details = {}
    
    # asking for name
    name = input("Enter your name")
    details["Name"] = name

    # asking for age and verifying
    try:
        age = int(input("Enter your age. You must be at least 13."))
    except ValueError:
        print("Only numbers are allowed")
    else:
        if age < 13:
            print("You must be at least 13")
        else:
            details["Age"] = age
    
    # asking for email and verifying 
    email = input("Enter your email.")
    # Create a Regex for Email Addresses
    emailRegex = re.compile(r'''(
                        
                        [a-zA-Z0-9._%+-1]+   #username
                        @                    # @symbol
                        [a-zA-Z0-9.-]+       #domain name
                        (\.[a-zA-Z]{2,4})    #dot-something
                        )''', re.VERBOSE)    
    e = []
    f = emailRegex.search(email)
    if f == "None":
        print("Enter an email")
    else:
        try:
            e.append(f.group())
            if e[0] in users:
                print("This email is already taken")
            else:
                details["Email"] = e[0]
        except AttributeError:
            print("One email address is needed!")
        
    # enter address
    address = input("Enter your address")
    details["Address"] = address
    
    # enter username 
    username = input("Enter your username")
    if username in users:
        username = input("Enter a different username")
        details["Username"] = username
    else: 
        details["Username"] = username
    
    # enter password -- You can also encrypt and decrypt the password using third party libarary
    password = input("Enter your password")
    details["Password"] = password

    # updating our database   
    users.update({username : details})
    print("\n")
    print("Your Details Are:")
    print(details)

Next, we are going to write a code to allow users to log in:

# to allow users to login
def login():
    username = input("Enter your username")
    if username not in users:
        print("You don't have an account. Please create one")
    else: 
        password = input("Enter your password")
        if password != users[username]["Password"]:
            print("Password did not match. Try again")
        else:
            print("You are successfully logged in") # you can input the process you want to start here. 

Finally, a code to allow users to delete or remove their data:

# A function to allow users to deleted their accounts
def delete():
    username = input("Enter your username")
    if username not in users:
        username = input("Enter your username")
    else:
        users.pop(username)
        print("Account Deleted")

Part 2: Advanced Level (Close To Production)

Now we are taking a massive leap forward. We will rewrite the basic signup and login script using a much more advanced, robust, and production-ready approach. We will utilize SQLite3 for persistent database management, implement Password Hashing for top-tier security, and structure our code using Object-Oriented Programming (OOP).

Step 1: Establishing a Persistent Database

Temporary variables are great for learning the basics of logic, but professional software requires persistent storage. Python comes with a powerful built-in library called sqlite3, which allows us to interact with an SQL database natively without needing to install complex, external server software.

Let’s begin by creating our database schema. Instead of just saving a username and a password, we will design our system to support different user roles (like ‘editor’ or ‘user’) and dynamic account states.

import sqlite3

def initialize_database():
    # Connect to the database file (it will be created if it doesn't exist)
    conn = sqlite3.connect('platform_users.db')
    cursor = conn.cursor()
    
    # Create the users table with advanced fields
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT UNIQUE NOT NULL,
            email TEXT UNIQUE NOT NULL,
            password_hash TEXT NOT NULL,
            role TEXT DEFAULT 'user',
            status TEXT DEFAULT 'active'
        )
    ''')
    
    conn.commit()
    conn.close()
    print("Database initialized successfully.")

if __name__ == "__main__":
    initialize_database()

Explaination:

  • import sqlite3: We import the built-in SQLite module. Because it’s included in Python’s standard library, no pip installs are necessary.
  • sqlite3.connect('platform_users.db'): This line opens a connection to a database file. If the file doesn’t exist, Python will seamlessly create it right there in your project folder.
  • cursor = conn.cursor(): A cursor is an object that allows us to execute SQL commands one by one. Think of it as your virtual assistant that carries your instructions to the database server.
  • CREATE TABLE IF NOT EXISTS users (...): This is a SQL command. We define our columns meticulously:
    • id: A unique identification number for every user that increments automatically (AUTOINCREMENT).
    • username & email: Defined as UNIQUE NOT NULL, meaning no two users can share the same username or email, and they absolutely cannot be left blank.
    • password_hash: We will store the hash of the password, not the actual text.
    • role: Defaults to ‘user’, but we can selectively upgrade accounts to ‘editor’ or ‘admin’.
    • status: Defaults to ‘active’. This crucial addition allows us to soft-delete or ‘archive’ accounts later without losing data.
  • conn.commit(): This executes and saves the changes to the database.
  • conn.close(): Always close your connection when you are done to free up system memory and resources.

Step 2: Securing Passwords with Hashing

You must never store plain text passwords. If a malicious actor gains access to your database file, they will instantly have everyone’s passwords. Instead, we use a cryptographic hash function. A hash function takes an input (the password) and returns a fixed-size string of seemingly random characters. It is a one-way street; you cannot easily reverse a hash back into the original password.

We will use Python’s built-in hashlib. For enhanced, production-grade security, we will add a “salt” which is a randomly generated string added to the password before hashing to protect against pre-computed dictionary attacks.

import hashlib
import os

def hash_password(password: str) -> str:
    # Generate a random 16-byte salt
    salt = os.urandom(16)
    
    # Hash the password combined with the salt using SHA-256
    hash_obj = hashlib.pbkdf2_hmac(
        'sha256', 
        password.encode('utf-8'), 
        salt, 
        100000 # Number of iterations
    )
    
    # Combine the salt and the hash into a single string for storage
    return salt.hex() + ':' + hash_obj.hex()

def verify_password(stored_password: str, provided_password: str) -> bool:
    # Split the stored string back into salt and hash
    salt_hex, original_hash = stored_password.split(':')
    salt = bytes.fromhex(salt_hex)
    
    # Hash the provided password with the extracted salt
    hash_obj = hashlib.pbkdf2_hmac(
        'sha256', 
        provided_password.encode('utf-8'), 
        salt, 
        100000
    )
    
    # Compare the newly generated hash with the original stored hash
    return hash_obj.hex() == original_hash

Code Explaination:

  • os.urandom(16): This generates cryptographically secure random bytes. We use this unique randomness as our ‘salt’ for every individual user.
  • hashlib.pbkdf2_hmac(...): This is a highly robust hashing algorithm. It requires the hashing method (sha256), the password converted to byte format (encode('utf-8')), the salt, and the number of iterations (100,000). The high iteration count intentionally slows down the computational process slightly. To a user logging in, the delay is imperceptible, but it makes brute-force attacks painfully slow for hackers.
  • salt.hex() + ':' + hash_obj.hex(): We need to store both the salt and the hash in the database to verify the password later. We convert both to readable hexadecimal strings and join them with a colon separator.
  • verify_password(...): When a user attempts to log in, we pull this combined string from the database. We split it by the colon to retrieve the unique salt, apply that exact same salt to the newly typed password, and check if the resulting hashes match. If they match, the password is correct!

Step 3: Object-Oriented System Architecture

To ensure our code is clean, scalable, and easy to integrate into larger software systems (like expansive administrative portals), we should wrap our logic inside a Python Class. This allows us to keep the database connection organized and prevents our global namespace from becoming cluttered.

import sqlite3
import re

class AuthManager:
    def __init__(self, db_name='platform_users.db'):
        # The constructor initializes the database filename for the instance
        self.db_name = db_name
    
    def _connect(self):
        # A helper method to establish a fresh connection when needed
        return sqlite3.connect(self.db_name)

    # We will add signup, login, and management methods inside this class next

Explaination:

  • class AuthManager:: We define a structural blueprint for our authentication system. By treating the authentication system as an object, it can hold its own localized state.
  • def __init__(self, db_name): The constructor method. It triggers automatically the moment we create a new AuthManager object. It sets up the database name dynamically.
  • def _connect(self): A utility helper method. The underscore (_) prefix is a Python convention indicating that this method is intended for internal use by the class itself, not to be called externally. It reliably opens a fresh database connection whenever we need to query or insert data.

Step 4: The Advanced Signup Form

Now, let’s implement the core signup process inside our AuthManager class. We need to sequentially take user inputs, strictly validate the user’s email using a Regular Expression (Regex), ensure they meet an administrative age requirement, hash their secure password, and safely insert them into our persistent database.

def signup(self):
        print("\n--- Create a New Account ---")
        username = input("Choose a username: ").strip()
        email = input("Enter your email address: ").strip()
        
        # Strict Email Validation using Regex
        email_pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
        if not email_pattern.match(email):
            print("Error: Invalid email format. Please try again.")
            return

        # Age Validation with Error Handling
        try:
            age = int(input("Enter your age (must be 18+ for admin tools): "))
            if age < 18:
                print("Error: You must be at least 18 years old to register.")
                return
        except ValueError:
            print("Error: Age must be a valid numerical value.")
            return
            
        password = input("Create a strong password: ")
        if len(password) < 8:
            print("Error: Password must be at least 8 characters long.")
            return
            
        # Hash the password for secure storage
        hashed_pw = hash_password(password)
        
        # Connect to Database safely
        conn = self._connect()
        cursor = conn.cursor()
        
        try:
            # We use placeholders (?) to prevent SQL Injection attacks
            cursor.execute('''
                INSERT INTO users (username, email, password_hash)
                VALUES (?, ?, ?)
            ''', (username, email, hashed_pw))
            conn.commit()
            print(f"Success! Account for '{username}' created successfully.")
        except sqlite3.IntegrityError:
            # Catching the UNIQUE constraint failure gracefully
            print("Error: That username or email is already registered in our system.")
        finally:
            conn.close()

Explaination:

  • input(...).strip(): The .strip() function actively removes any accidental white spaces (like hitting the spacebar before typing) at the beginning or end of the user’s input, preventing difficult-to-track bugs.
  • re.compile(...): This Regex pattern is a strict, mathematical rulebook for what an email structure should look like. It demands alphabetical characters/numbers, an obligatory @ symbol, more characters for the domain name, a literal dot, and a top-level domain (like .com or .net). If match() fails, we stop the function early using the return keyword.
  • try... except ValueError: When asking for an integer (int()), if the user playfully types the word “twenty” instead of the number “20”, the program would normally crash. The try/except block actively catches this error gracefully and prints a helpful message instead.
  • VALUES (?, ?, ?): This is vitally important. Never inject Python variables directly into an SQL string using f-strings (e.g., f"INSERT INTO users VALUES ({username})"). Doing so opens your software up to SQL Injection, a catastrophic security flaw where users can write malicious code into the input boxes. Using ? tells SQLite to safely sanitize the inputs before processing them.
  • sqlite3.IntegrityError: Since we explicitly defined the username and email columns as UNIQUE in Step 1, the database engine itself will forcefully reject duplicate entries. We catch this specific error and inform the user cleanly instead of throwing a massive wall of red error text.

Step 5: The Secure Login System

Logging in involves checking if the provided username exists, fetching their hashed password block from the database, evaluating their account status, and passing the data to our cryptographic verification function.

def login(self):
        print("\n--- System Login ---")
        username = input("Enter your username: ").strip()
        password = input("Enter your password: ")
        
        conn = self._connect()
        cursor = conn.cursor()
        
        # Fetch the user's necessary data bundle
        cursor.execute("SELECT password_hash, role, status FROM users WHERE username = ?", (username,))
        result = cursor.fetchone()
        conn.close()
        
        if result is None:
            print("Error: Account not found.")
            return False
            
        # Unpack the tuple
        stored_hash, role, status = result
        
        # Check if the account has been administratively archived
        if status == 'archived':
            print("Error: This account has been archived. Please contact platform support.")
            return False
            
        # Verify the password computationally
        if verify_password(stored_hash, password):
            print(f"Welcome back, {username}! Role Privileges: [{role.upper()}]")
            return True
        else:
            print("Error: Incorrect password. Access denied.")
            return False

Explaination:

  • cursor.execute("SELECT ..."): We query the database exclusively for the password hash, role, and current status associated with the exact entered username.
  • cursor.fetchone(): This retrieves the very first row that matches our query. Because usernames are entirely unique, there will only ever be a maximum of one match. If the user doesn’t exist, it safely returns None.
  • stored_hash, role, status = result: This neat Python trick is called “unpacking.” The database returns a tuple containing three items (e.g., ('the_hash_string', 'user', 'active')), and we assign those three separate values to three named variables instantaneously.
  • We check the status flag immediately. This guarantees that users whose accounts have been archived are physically barred from authenticating, regardless of if they remember their password.
  • Finally, verify_password() does the heavy cryptographic lifting.

Step 6: Advanced Account Management (Editor Status & Archiving)

In professional platform environments, you rarely want to permanently delete data using a basic .pop() or DELETE FROM command. Permanent deletion permanently destroys vital historical records. Instead, administrative systems utilize “soft deletes” changing an account’s database status to “archived.”

Furthermore, administrators need the capability to manage platform privileges, such as toggling editor status up and down. Let’s build a dedicated administrative management method to handle this context.

    def manage_user(self):
        print("\n--- Administrative User Management ---")
        target_user = input("Enter the exact username to manage: ").strip()
        
        conn = self._connect()
        cursor = conn.cursor()
        
        # Check if target user exists in the system
        cursor.execute("SELECT id, role, status FROM users WHERE username = ?", (target_user,))
        user = cursor.fetchone()
        
        if not user:
            print(f"Error: User '{target_user}' does not exist.")
            conn.close()
            return
            
        print(f"User Found: {target_user} | Current Role: {user[1]} | Status: {user[2]}")
        print("1. Toggle Archive/Active Status")
        print("2. Promote to Editor Privileges")
        choice = input("Select an action (1-2): ")
        
        if choice == '1':
            # Flip the status dynamically
            new_status = 'active' if user[2] == 'archived' else 'archived'
            cursor.execute("UPDATE users SET status = ? WHERE username = ?", (new_status, target_user))
            print(f"Action Completed: User status changed to '{new_status}'.")
            
        elif choice == '2':
            if user[1] == 'editor':
                print("Notice: User is already an editor.")
            else:
                cursor.execute("UPDATE users SET role = 'editor' WHERE username = ?", (target_user,))
                print("Action Completed: User successfully granted Editor privileges.")
        else:
            print("Error: Invalid selection.")
            
        conn.commit()
        conn.close()

Explaination:

  • SELECT id, role, status: We fetch the current state of the target user first, allowing us to display it directly and make logical conditional decisions based on their current standings.
  • new_status = 'active' if user[2] == 'archived' else 'archived': This is an inline if-statement known as a ternary operator. It flips the status like a light switch. If they are currently archived, they become active, and vice versa.
  • UPDATE users SET ...: Instead of aggressively executing DELETE FROM, we merely update specific cells in the existing row. This intelligently preserves all of their linked data (which is vital if you are tracking document histories or edits) but fundamentally alters the control flags that dictate what they can do on the platform.

To run this complete system seamlessly, you can set up a simple interactive while loop at the bottom of your Python file to act as your terminal-based application.

def main():
    # Ensure the database tables are physically created before starting
    initialize_database()
    app = AuthManager()
    
    while True:
        print("\n=== Main Control Menu ===")
        print("1. Sign Up")
        print("2. Log In")
        print("3. Admin: Manage Users & Editor Status")
        print("4. Exit System")
        
        choice = input("Select an option: ")
        
        if choice == '1':
            app.signup()
        elif choice == '2':
            app.login()
        elif choice == '3':
            # In a deployed app, you would mandate that the currently logged-in user is an admin first!
            app.manage_user()
        elif choice == '4':
            print("Safely exiting system. Goodbye!")
            break
        else:
            print("Invalid choice. Please enter 1, 2, 3, or 4.")

if __name__ == "__main__":
    main()

That’s it. Hope this was helpful. Now if you want to move to a new project then see how you can create an e-commerce app in Python here.

Please note: the code above may not organize well on mobile devices so please use a laptop and code along to learn faster.

Support

Buy author a coffee

Support
Tags: Python ProjectsPython Tutorial
SummarizeSendShareTweetScan
Next Post

19 Basic Machine Learning Questions

Neuraldemy

Neuraldemy

This is Neuraldemy support. Subscribe to our YouTube channel for more.

Related Posts

pickle module in python

Pickle Module In Python: A Comprehensive Guide for Beginners

Python Os Module

Python OS Module: A Comprehensive Guide for Beginners

Install Miniconda on Windows (The EASIEST Way! )

Install Miniconda on Windows (The EASIEST Way! )

TensorFlow Simplified Guide For Beginners

Create A To-Do-List App In Python: Complete Tutorial

Notes App In Python: Complete Tutorial

Next Post
19 Basic Machine Learning Questions

19 Basic Machine Learning Questions

E-commerce App In Python – User Facing

E-commerce App In Python - User Facing

Notes App In Python: Complete Tutorial

Notes App In Python: Complete Tutorial

Support

Buy author a coffee

Support

Support Neuraldemy

Newsletter

Top rated products

  • Probability and Statistics for Machine Learning and Data Science Probability and Statistics for Machine Learning and Data Science
    Rated 5.00 out of 5
    30.00$ Original price was: 30.00$.12.99$Current price is: 12.99$.
  • SVM Notes: Optimization & Implementation SVM Notes: Optimization & Implementation
    Rated 5.00 out of 5
    9.99$ Original price was: 9.99$.4.99$Current price is: 4.99$.
  • spidy mail hunter software Spidy Mail Hunter: Powerful And Intelligent Website & PDF Email Extractor Software (Windows App)
    Rated 4.78 out of 5
    149.00$ Original price was: 149.00$.49.00$Current price is: 49.00$.
  • Linear Algebra For Machine Learning And Data Science Linear Algebra For Machine Learning And Data Science
    Rated 4.71 out of 5
    40.00$ Original price was: 40.00$.24.99$Current price is: 24.99$.
  • Clustering and Outlier Detection A Comprehensive Tutorial Clustering and Outlier Detection 20.97$ Original price was: 20.97$.13.47$Current price is: 13.47$.

Recent Posts

Git Tutorial: A Beginners Guide To Git And GitHub

Why RAM Prices Will Continue To Rise?

100 CSS Interview Questions

100 CSS Interview Questions

July 2026
M T W T F S S
 12345
6789101112
13141516171819
20212223242526
2728293031  
« Mar    

Neuraldemy

Neuraldemy

Neuraldemy

Software Development

Neuraldemy helps you learn ML, AI, Web Dev and data science from scratch. Addtionally, we also provide web development and hosting services for businesses, and individuals

  • Get Started
  • Contact
  • Book Services
  • Privacy Policy
  • Terms Of Use
  • Support Portal
  • Managed Hosting Terms
  • Web Development Terms
  • Refund Policy
Neuraldemy

© 2026 - A learning platform by Odist Magazine

Welcome Back!

Login to your account below

Forgotten Password? Sign Up

Create New Account!

Fill the forms below to register

*By registering into our website, you agree to the Terms & Conditions and Privacy Policy.
All fields are required. Log In

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
Join Our WhatsApp Channel
  • Home
  • Tutorials
    • Machine Learning
    • Python
    • Web Development
    • Javascript
    • Mathematics
    • Deep Learning
    • Artificial Intelligence
  • Store
  • Our Services
    • Managed Hosting Services
    • Web Development Services
  • Our Softwares
    • JaggoRe AI
    • Email Extractor
    • TimeWell App
  • Login
  • Sign Up
  • Cart
Order Details

© 2026 - A learning platform by Odist Magazine

This website uses cookies. By continuing to use this website you are giving consent to cookies being used.
0