Is there any way that I can create a login system using prisma-client-py, flask-login & flask?

Question:

I am attempting to create a control panel only using prisma-client-python, flask-login & flask as the primary webserver. I have successfully managed to create the routes, as well as built the registration screen & have also granted prisma access to the database. When I try to use the route,

Here is my code for the login route:

`

from flask import Blueprint, request, render_template
from prisma.models import User
from flask_login import login_user

login_blueprint = Blueprint('login', __name__ , template_folder='../pages/')

@login_blueprint.route('/', methods=['GET','POST'])
def list_create():
  if request.method == 'GET':
    return render_template('login.html')

  if request.method == 'POST':
    data = request.form

    if data is None:
      return

    email = data.get('email')
    password = data.get('password')
    if email is None or password is None:
      return {"error": "You need to provide email and password"}
    user = User.prisma().find_many(where={'email': email, 'password': password},)
    print(user)
    return login_user(user)

`

Here is my code for the registration route:

`

from flask import Blueprint, request, render_template
from prisma.models import User

user_blueprint = Blueprint('register', __name__ , template_folder='../pages/')

@user_blueprint.route('/', methods=['GET','POST'])
def list_create():
  if request.method == 'POST':
    data = request.form

    if data is None:
      return

    name = data.get('username')
    email = data.get('email')
    password = data.get('password')
    if name is None or email is None:
      return {"error": "You need to provide name and email"}

    user = User.prisma().create(data={'email': email, 'username': name, 'password': password})

    return dict(user)
  return render_template('register.html')

`

here is my prisma schema:

`

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator db {
  provider  = "prisma-client-py"
  interface = "sync"
}

model User {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  email     String   @unique
  password  String
  username  String?
  admin     Boolean  @default(false)
  is_active Boolean  @default(false)
  }

`

& here is my main app.py route.

`

from flask import Flask
from prisma import Prisma, register
from routes.register import user_blueprint
from prisma.models import User
from routes.login import login_blueprint
# from routes.post import post_blueprint

db = Prisma()
db.connect()
register(db)

app = Flask(__name__)

@app.route('/', methods=['GET'])
def index():
  return {
    "ping": "pong"
  }

app.register_blueprint(user_blueprint, url_prefix='/register')
app.register_blueprint(login_blueprint, url_prefix='/login')

if __name__ == "__main__":

  app.run(debug=True, port=5000, threaded=True)

`

I had tried using login_user(user) as stated in code examples using it. But I keep getting the following error:

AttributeError: 'list' object has no attribute 'is_active'

Does anyone have any idea for what I should to resolve this problem & allow the user to login?

Asked By: Ruler

||

Answers:

The login route (for which the function is also oddly called list_create) queries the database using find_many – which will return a list of items, not a single item. Flask’s login() expects a single user, not a list. The exception makes sense, as the login function is provided with a list of user(s), not a user object.

A simple fix can be:

@login_blueprint.route('/', methods=['GET','POST'])
def list_create():
    ...

    user = User.prisma().find_many(where={'email': email, 'password': password},)
    if user and len(user) == 1:
        return login_user(user[0])
    return {"error": "Authentication error, or user does not exist"}

Alternatively, you can try using find_unique as per Prisma’s documentation.

Answered By: micromoses
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.