简体   繁体   中英

Boto3 shows ConnectionReset Error

I added a db.session.close() to every function that does a query. Looking up the error also showed me that others had this issue because of the lost connection to S3. Locally it works pretty well. However running the same on a Ubuntu server with mod_wsgi and Apache2 shows the following error:

185.27.213.237 - - [17/Sep/2017 16:31:34] "GET / HTTP/1.1" 200 -
185.27.213.237 - - [17/Sep/2017 16:31:39] "POST / HTTP/1.1" 302 -
('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
185.27.213.237 - - [17/Sep/2017 16:31:50] "GET /space/user HTTP/1.1" 200 -

From the Apache logs:

[wsgi:error] [pid 1456:tid 139792612300544] ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

The first line was me opening the login route. After logging in with the correct credentials it shows the 302 error. In the following I post my login route and the site that is redirected to after a successful login. I'm using sqlite3 since I only have a couple of user.

#Login
@app.route('/', methods=['GET', 'POST'])
def index():
    form = LoginForm()

    try:
        if form.validate_on_submit():
            user = User.query.filter_by(username=form.username.data).first()
            if user:
                if bcrypt.check_password_hash(user.password, form.password.data):
                    login_user(user, remember=False)
                    return redirect(url_for('showspace', spacename=user.username))
            return render_template('login.html', form=form, ermsg="Invalid credentials")
        return render_template('login.html', form=form)
    except Exception as ermsg:
        db.session.rollback()
        print(ermsg)
        return redirect(url_for('index'))
    finally:
        db.session.close()

#Dashboard new
@app.route('/space/<spacename>', methods=['GET', 'POST'])
@login_required
def showspace(spacename):
    try:
        selectedspace=spacename
        spacelist = Space.query.filter(Space.owner.any(id=current_user.id)).all()
        hasaccess = User.query.join(User.spaces).filter(User.username==current_user.username, Space.name==selectedspace).first()
        if hasaccess != None:
            conn = boto3.resource('s3')
            mybucket = conn.Bucket(selectedspace)
            return render_template('dashboard.html', spaces=spacelist, filelist=mybucket.objects.all(), name=current_user.username, selectedspace=selectedspace)
        else:
            return "You don't have permission to view this space!"
    except:
        db.session.rollback()
        return 'Something went wrong'
    finally:
        db.session.close()

It would be so much cleaner if you write a decorator and execute your methods inside a database session. Like so

def db_session():
    def wrapper(func):
        def wrapped(*args, **kwargs):
            # Executing the handler inside a db context
            with Session as session:
                try:
                    return func(session, *args, **kwargs)
                except:
                    session.rollback()

@app.route('/space/<spacename>', methods=['GET', 'POST'])
@login_required
@db_session()
def showspace(session, spacename):
    # your code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM