25

Probably not the accurate title since i am new to flask/python. I am working on an internal tool which will be used by different teams. Each team has different stages of their deployments e.g., alpha, beta|test, prod and they also have multiple regions e.g., NA, EU, AP etc ...

Right now i when i am using redirect_template i am sending stage and region as variable which are then used in templates. However, doing for every redirect_template is kind of cumbersome. Is there any better approach to this?

2 Answers 2

52

I assume your Flaskobject's name is app (i.e., app = Flask(__name__)).

Place the below code right after the app is initialized.

@app.context_processor def inject_stage_and_region(): return dict(stage="alpha", region="NA") 

In your Jinja templates, "alpha"and "NA" can be referenced by {{ stage }} and {{ region }}.

Flask docs: http://flask.pocoo.org/docs/0.12/templating/#context-processors

Flask Docs Update Feb - 2024 V2.3.x https://flask.palletsprojects.com/en/2.3.x/templating/#context-processors

To inject new variables automatically into the context of a template, context processors exist in Flask. Context processors run before the template is rendered and have the ability to inject new values into the template context. A context processor is a function that returns a dictionary. The keys and values of this dictionary are then merged with the template context, for all templates in the app

Sign up to request clarification or add additional context in comments.

3 Comments

and what if i have to change this value based on a user's action. let's say user clicks on stage name and want to change it to beta . how can i update new stage for context_processor?
(1) save a user's configuration in a database / session / cookie... based on the user's action. (I suppose this is already done.) (2) inside the context processor, fetch the information accordingly. Note that you can access Flask global variables like session or g. (e.g., stage = session["stage"]) (3) return the result (e.g., return dict(stage=stage)).
how do i get/set global variable within python code? like jinja.globals['counter'] = jinja.globals['counter']+1
2

Piggybacking off the other answer, the below solution can let you access your data from within your JavaScript/TypeScript to allow more dynamism, though it's kind of hacky.

There's 3 parts to this:

  1. Get the dictionary information in Python
  2. Embed the data into your webpage
  3. Access that data from your JavaScript/TypeScript code

Step 1

Setup the Python dictionary for external use

Somewhere in your Flask code in either the __init__.py file, the routes.py file, or some other similarly accessible file, have the following setup:

stage = "alpha" region = "North America" # can even grab environment variables pretty easily: deployment = os.environ.get("STAGE", "testing") version = "6.9" @server.context_processor def inject_data() -> dict: # .context_processor information: https://stackoverflow.com/a/43336023/8705841 flask_data = {'stage', 'region', 'deployment', 'version', 'etc'} # Create a dictionary from a list of variables: https://stackoverflow.com/a/9496018/8705841 return {'flask_data': dict(((k, eval(k)) for k in flask_data))} 

The @server part should match the name of your Flask app variable (instantiated with server = Flask(__name__)) and does not particularly matter (usually it's called app). The flask_data dict/list should have all the Python variables you want ported over to the front end, but with quotes around them- the eval part of the return will grab the Python variable that matches the input string k.

Step 2

Make the data available on the webpage

In your index.html page, inside the <head> tag (next to your other <script> tags, have this tag as well:

<head> <!-- a whole bunch of stuff --> <!-- get all the Flask variables from Python -> TypeScript --> <script id=flask_data type="text/json">{{ flask_data|tojson }}</script> <!-- possibly a whole bunch more stuff --> </head> 

Basically every single StackOverflow post even mentioning Flask has the above copy-pasted.

Step 3

Access the data from any of your JavaScript files

This is the part that no one else talked about- actually using your data from within your JavaScript (or TypeScript) code, regardless of your directory setup. It's a little hacky, but basically you access the HTML element that has your embedded data and then parse it for use in your program however you want. This is technically TypeScript code, but should work for both JavaScript and TypeScript (it took a ton of trial and error to finally get it to work on my TypeScript build).

foo() { const flask_data = JSON.parse((document.querySelector('#flask_data') as HTMLElement).textContent || ""); this.version = flask_data.version const stage = flask_data.stage; console.log("Data: " + flask_data); // just for debugging, not actually necessary console.log("Stage: " + stage); console.log("Running verison '" + this.version + "'"); if (stage === "beta") { do_something(); else { do_something_else(); return input_from_python; } } // the rest of your program, using any part of the flask_data dictionary however you need // . // . // . 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.