Featured image of post Pseudo-decorators for my Python Flask app

Pseudo-decorators for my Python Flask app

Secured Python Flask app on Code Engine

Recently, I migrated an existing Python app from a Cloud Foundry to an IBM Cloud Code Engine deployment. The Flask app uses decorators for the routes and for OIDC-based authentication. For usability, the app should start up even without anything configured yet and the OIDC decorators being invalid. It required to some IMHO tricky coding.

Python decorators

When working with Python, most of you have probably run into decorators. They are some form of metaprogramming where the decorating function is invoked with the decorated function as payload. Hence, the decorator adds its features to the other function. In frameworks like Flask, the routes are specified with decorators.

@app.route('/')
def index():
    return 'This is my index page'

@app.route('/hello')
def hello():
    return 'Hello and welcome to my world'
```When working with authentication like OpenID connect and the Python module [flask-pyoidc](https://flask-pyoidc.readthedocs.io/en/stable/index.html), routes can be protected by adding another decorator.

@app.route(’/secure’) @auth.oidc_auth(‘default’) def secure(): return ‘This route is protected’


#### Pseudo decorator

For my app, I have the Flask app either fully configured and initialized (typical situation) or not. The latter is the case when in a tutorial a user is in the process of binding other services and going through configuration steps. Typically, an app without a full configuration would error out during startup. So what to do? Some form of pseudo decorators to the rescue. Either have some simple pass-through decorator when the app is not ready yet or call the actual decorator when everything is in place.

@app.route(’/secure’) @security_decorator_auth def secure(): return ‘This route is protected’







| ```     def security_decorator_auth(f):         @wraps(f)         def decorated_function(*args, **kwargs):             return f(*args, **kwargs)         return decorated_function ``````     def security_decorator_auth(f):                 @wraps(f)         @auth.oidc_auth('default')         def decorated_function(*args, **kwargs):             return f(*args, **kwargs)         return decorated_function ``` |
| --- |
|

The first version just passes the decorated function without modifying it, the second version adds the OIDC decorator to the passed function.

For more context, see the file [ghstats.py](https://github.com/IBM-Cloud/github-traffic-stats/blob/master/backend/ghstats.py) relating to this IBM Cloud Solution Tutorial on [Serverless web app and eventing for data retrieval and analytics](https://cloud.ibm.com/docs/solution-tutorials?topic=solution-tutorials-serverless-github-traffic-analytics).

If you have feedback, suggestions, or questions about this post, please reach out to me on Twitter ([@data_henrik](https://twitter.com/data_henrik)) or [LinkedIn](http://de.linkedin.com/in/henrikloeser).