1 분 소요


What is a Decorator?

A decorator is a feature that allows functions to have reusable functionality and behavior. It’s used when you want to add or modify functionality without changing the internal logic of a function.

Generally, decorators are used when there’s a need for pre-processing or post-processing of functions.

Using Decorators

Of course, there are many pre-built features available, but I want to customize the authentication part.

(For authentication, decorators like Django’s @login_required() already exist)

Declaring a Decorator

from flask import request
from functools import wraps

def api_decorator():
    def api_auth_decorator(f):
        @wraps(f)
        def _api_auth_decorator(*args, **kwargs):
            result = f(*args, **kwargs)
            token = request.headers.get("Authorization")
            if token is None:
                return {"message": "Unauthorized access.", }, 401

            if datetime.datetime.now() >= time_checker(token)
                # time_checker is an arbitrary function that checks the token's expiration time
                return {"message": "Invalid token.", }, 401
            return result

        return _api_auth_decorator

    return api_auth_decorator
  • First, define the function that will be made into a decorator using wraps
  • Receive the function as an argument and execute before the corresponding function runs
  • Extract request information from the received *args, **kwargs arguments
  • (In this example) Extract “Authorization” from the header to check the token

Applying the Decorator

Here’s a simple example of an API for writing comments that requires login:

@app.route("/post/comment", methods=["POST"])
@api_decorator()
def post_comment():
    params = json.loads(request.get_data())
    context = params.get("context",None)
    user_id = params.get("userId",None)
    post_id = params.get("postId",None)

    CommentModel.create(
        context = context,
        user_id = user_id,
        post_id = post_id,
    )
    return {"message":"Comment has been successfully created"}

If we hadn’t used the api_decorator() written above, we would need to add service logic to every router to check if the user is logged in and verify the token each time.

Similar Built-in Functions

Flask is a framework, so it already provides features similar to the decorators we create.

before_first_request

  • Logic used before the very first request after the Flask server starts ```python from flask import Flask, jsonify

app = Flask(name)

@app.route(“/”) def before_first_request(): log.info(“Used only for the first request after Flask starts”) return jsonify({“msg”:”before_first_request”})


### before_request

- Used before every request after the Flask server starts

```python
from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/")
def before_request():
    log.info("Used before each request after Flask starts")
    return jsonify({"msg":"before_request"})

after_request

  • Used after every request once the Flask server starts
from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/")
def after_request():
    log.info("Used after each request once Flask starts")
    return jsonify({"msg":"after_request"})

There are also teardown_request, teardown_appcontext, and more!

댓글남기기