3
\$\begingroup\$

I have a Repl.it account that I use for my projects, and I don't really want to make a new api for storage every time, I've seen some like EasyDB and Jsonstore (I use Jsonstore in the background as storage here) but it doesn't have some of the features i want. It isn't done, but its working. I just wanted to see if there's any improvements I could make before I start working on the next few features.

from os import getenv as env
from flask import make_response
from flask import Flask, request
from flask_limiter import Limiter
from json_store_client import Client
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import check_password_hash
from werkzeug.security import generate_password_hash

app = Flask('app')
auth = HTTPBasicAuth()
db = Client(env("TOKEN"))

limiter = Limiter(
    app,
    key_func=lambda: auth.username(),
    default_limits=["100 per second"]
)

@auth.verify_password
def verify_password(username, password):
    user = db.retrieve(f"users/{username}")
    try:
        if check_password_hash(user["password"], password):
            return True
    except: return False
    return False

@app.route('/regester', methods = ['POST'])
def register():
    if request.is_json: user = request.get_json()['username']
    else: user = request.form['username']
    if db.retrieve(f"users/{user}"):
        return False
    if request.is_json: db.store(f"users/{user}", { "password": generate_password_hash(request.get_json()['password'])})
    else: db.store(f"users/{user}", { "password": generate_password_hash(request.form['password'])})
    return make_response(user, 201)

@app.route('/', methods = ['GET'], defaults={'fullurl': ''})
@app.route('/<path:fullurl>', methods = ['GET'])
@auth.login_required
def index_get(fullurl):
    data = db.retrieve(f"data/{auth.username()}/{fullurl}")
    if data: return make_response(data, 200)
    return make_response({}, 204)

@app.route('/', methods = ['POST'], defaults={'fullurl': ''})
@app.route('/<path:fullurl>', methods = ['POST'])
@auth.login_required
def index_post(fullurl):
    if request.id_json: db.store(f"data/{auth.username()/{fullurl}}", request.get_json())
    else: db.store(f"data/{auth.username()}", request.form)
    return make_response(db.retrieve(f"data/{auth.username()}"), 201)

app.run(host="0.0.0.0")


\$\endgroup\$
3
\$\begingroup\$

Few optimization tips

  • verify_password function

    • avoid bare except: clause - at least use except Exception: (though it's also broad, check which exception class is most appropriate in that context)
    • a set of statements:

      try:
          if check_password_hash(user["password"], password):
              return True
      except: return False
      return False
      

      is an overloaded and verbose version of a more explicit logic:

      @auth.verify_password
      def verify_password(username, password):
          user = db.retrieve(f"users/{username}")
          try:
              return check_password_hash(user["password"], password)
          except Exception:
              return False
      
  • don't overuse (or avoid entirely) multiple statements one-liners like if <condition>: <long statement>

  • avoid writing duplicated lengthy db statements like:

    if request.is_json: db.store(f"users/{user}", { "password": generate_password_hash(request.get_json()['password'])})
    else: db.store(f"users/{user}", { "password": generate_password_hash(request.form['password'])})
    

    To fix that determine request data source beforehand. Optimizing register function:

    @app.route('/regester', methods = ['POST'])
    def register():
        data = request.get_json() if request.is_json else request.form
        user = data['username']
        if db.retrieve(f"users/{user}"):
            return False
    
        db.store(f"users/{user}", {"password": generate_password_hash(data['password'])})
        return make_response(user, 201)
    

    Apply this optimization technique to all remaining functions with a similar issue.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you, I didn't know about the except thing before, always thought it was defaulted to except Exception \$\endgroup\$ – Haaruun I Feb 5 at 23:48
  • \$\begingroup\$ @HaaruunI, you're welcome \$\endgroup\$ – RomanPerekhrest Feb 6 at 7:57
  • \$\begingroup\$ @HaaruunI: It defaults to except BaseException, which also includes stuff like the user pressing Ctrl+C. \$\endgroup\$ – Graipher Feb 6 at 11:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.