Python OOP - Web App (Flask) - User registration class? I am working on a simple CRUD app as a personal project using Flask. I am currently working on the user blueprint and trying to use as less as libraries as I could and no ORM (for learning purposes). On my blueprints, I have multiple folders including a user folder. I wrote 2 classes in blueprints/user/models.py:
User: represent a User entity
UserService : register and login (login is not present yet)

Does it make sense to have2 separate classes? I am actually thinking to move all of my User methods to the UserService class and just have a UserService class with setters and getters.

I am confused about is where and when to interact with the database. Should I do it directly on my route.py vs create a new class?


For instance, to add a new User to the database, my SQL should look more or less like this:
sql = &quot;INSERT INTO users (email, password) VALUES (%s, %s)&quot;
cursor = conn.cursor()
cursor.execute(sql, (email, password))
cursor.fetchall()
conn.commit()

blueprints/user/models.py
class UserService():
    def register_user(self, 
                      email, 
                      password, 
                      registration_date, 
                      active, 
                      sign_in_count, 
                      current_sign_in_on,  
                      last_sign_in_on):
        new_user = User(email, password, registration_date, active, sign_in_count, current_sign_in_on, last_sign_in_on)
        return new_user.__str__()
    

    
class User():
    def __init__(self, email, password, registration_date, active, sign_in_count, current_sign_in_on, last_sign_in_on ):
        self.email = email
        self.password = password
        self.registration_date = registration_date
        self.active = active

        # Activity tracking
        self.sign_in_count = sign_in_count
        self.current_sign_in_on = current_sign_in_on
        self.last_sign_in_on = last_sign_in_on

    def desactivate_user(self):
        if self.active == False:
            print(f&quot;User {self.email} is already inactive&quot;)
        self.active = False

    def reactive_user(self):
        if self.active == True:
            print(f&quot;User {self.email} is already active&quot;)
        self.active = True

    def is_active(self):
        return self.active

    def update_activity_tracking(self, ip_address):
        self.sign_in_count += 1
        self.last_sign_in_on = self.current_sign_in_on
        self.current_sign_in_on = datetime.datetime.now()


    def update_password(self, new_password):
        self.password = get_hashed_password(new_password)

    def __str__(self):
        user_attributes = vars(self)
        return (', '.join(&quot;%s: %s&quot; % item for item in user_attributes.items()))

blueprints/user/views.py
from flask import Blueprint, render_template, request, jsonify
from prepsmarter.extensions import conn #database connection variable 

user = Blueprint('user', __name__, template_folder='templates')

@user.route('/register')
def login():
    return render_template('register.html')

@user.route('/new-user',methods = ['POST'])
def register_user():
   # where I am going to register a new user 

extensions/Database.py
import pymysql

class Database:
    instance = None 
    
    def __init__(self, host, user, password, db):
        self.host = host
        self.user = user
        self. password = password
        self.db = db 


    def connect(self):
        try: 
            conn = pymysql.connect(
                host = self.host,
                user = self.user,
                passwd = self.password,
                db = self.db
            )
            return conn
        except Exception as e:
            print(e)
In general, your code seems to be in pretty good shape if you're hoping to move towards domain driven design, notably seen from your &quot;entity-like&quot; User object and the UserService.

Does it make sense to have2 separate classes? I am actually thinking to move all of my User methods to the UserService class and just have a UserService class with setters and getters.

First off, if you're anticipating your application to grow, a clear separation of concerns is what you'd want to achieve and to further achieve this, the two objects you have are fine. That is, one to represent a definition of what a user is and another to determine what you can do with a user object or related objects which in this case is the UserService. This naturally means that the methods on the User class should now be part of the UserService, considering them business logic of the application. I would use the words model to describe the User class and service to describe the UserService to define the types of components for the application.

I am confused about is where and when to interact with the database. Should I do it directly on my route.py vs create a new class?

One thing that you can also consider from domain driven design is also to include a repository object when your application becomes large enough. Repositories typically carry operations that might interact with a database, replacing what may be seen like an ORM that you have mentioned. Otherwise, if you're still small and nimble and don't have too many complex relationships in your database, you can keep it simple and keep the database queries in your model for simplicity for the time being. Both allows the user to be created from anywhere if needed and enables code re-use more than including them in the route. Designing from an interface perspective consider the following.
user_repository = UserRepository(db_conn)
user_service = UserService()
foo_user = user_service.register_user(...)

// using the repository
repository.save(foo_user)

// using the model
foo_user.save()

I'll end this with, it depends how large your application is growing, the larger it is, the more you want to re-evaluate your design so to better organize groups of functionality to better extend from and if possible re-use code. That said, what you may have could be good in the long run if your application doesn't really grow beyond those needs.