Dynamic python/flask route function naming - python

first off, a disclaimer: I'm not well versed in python or flask, so bear with me.
I'm trying to put together a minimal API using flask, i was planning to dynamically generate routes and their associated procs from the contents of a subdirectory.
The code looks something like this:
from flask import Flask
import os
app = Flask(__name__)
configs = os.getcwd() + "/configs"
for i in os.listdir(configs):
if i.endswith(".json"):
call = "/" + os.path.splitext(i)[0]
#app.route(call, methods=['POST'])
def call():
return jsonify({"status": call + "Success"}), 200
The plan being to iterate over a bunch of config files and use their naes to define the routes. Now, this works for a single config file, but wont work for multiple files as I end up trying to overwrite the function call that is used by each route.
I can factor out most of the code to a separate function as long as i can pass in the call name. However it seems that however i go about this i need to dynamically name the function generated and mapped to the route.
So, my question is: how can use the contents of a variable, such as 'call' to be the function name?
i.e. something like
call = "getinfo"
def call(): # Effectively being evaled as def getinfo():
Everything i've tried hasn't worked, and i'm not confident enough in my python syntax to know if it's because i'm just doing something silly.
Alternatively is there another way to do what i'm trying to achieve?
Thanks for all and any feedback!

Thanks for the help. I've moved to one route and one handler and building up the file list, and handling of the request paths, etc separately.
This is a sanitized version of the model i now have:
from flask import Flask
import os
calls = []
cfgs = {}
app = Flask(__name__)
configs = os.getcwd() + "/configs"
for i in os.listdir(configs):
if i.endswith(".json"):
cfgs[call] = os.path.splitext(i)[0]
calls.extend([call])
#app.route('/<call>', methods=['POST'])
def do(call):
if call not in calls:
abort(400, "invalid call")
# Do stuff
return jsonify({"status": call + "Success"}), 200
if __name__ == '__main__':
app.run(debug=True)
So, thanks to the above comments this is doing what i'm after. Still curious to know if there is any way to use variables in function names?

Related

Best way to create / return xlsx file to Flask?

I stuck on the problem of how to organize code / proper way to get xlsx file as output in flask app.
I have a function.py file where for now the xlsx file generates.
The sense is that flask app gets some settings in json format, these settings are processed by function that must return xlsx(?) to app.
The function do some calculations depending on the settings.
The file has the next structure:
def function (settings):
settings=settings
df = pd.read_csv(settings['df'])
from pandas import ExcelWriter
writer = ExcelWriter('file.xlsx')
if settings[somefeature1]==1:
f1=dosmth.to_excel(writer, "feature 1")
if settings[somefeature2]==1:
f2=dosmth.to_excel(writer, "feature 2")
...
writer.save()
But if the file is already generated in function, what should I pass to flask? How the flask app function must look like then (especially in case if I want to return xlsx as json)?
#app.route('/Function', methods = ['POST'])
def Function():
settings = request.get_json(force = True)
return(function(settings)) #???
You should never forget that flask is a framework for creating web applications, a web application is a piece of software that receives a web request and generates a web response.
To make it super simple: your flask function should return something that a common web browser will be able to handle.
In this case your response should return the file but also some metadata to tell to the potential receiver what is inside the response and how to handle it.
I think that something like this could work:
return send_file(filename, mimetype='application/vnd.ms-excel')

how to send data to html worksheet using flask framework

I have a function calculate_full_eva_web(input:dict) it receives input dictionary several function applied on this input to create calculations dict, after calculations i want to send this data to html dashboard and after send data to html file i can play there with jinja stuff. i am unable to do so, i tried several ways but flask throws error. and also i don't know much about ajax ,may be ajax will do my work, let me know. that is why i am tagging ajax people on this post. Traceback is also attached..Thank you
In simple words, i want to send data to html in flask ! Please check my code. Let me know if i am doing anything wrong.
imports ...
from other file import other_functions
from other file import other_functions_2
from other file import other_functions_3
app = Flask(__name__, template_folder='templates/')
#app.route("/dashboard")
def calculate_full_eva_web(input:dict):
calculate_gap = other_functions(input)
calculate_matrix = other_functions_2(input)
average = other_functions_3(input)
data = dict{'calculate_gap':calculate_gap, 'calculate_matrix':calculate_matrix,'average':average}
return render_template('pages/dashboard.html', data = data)
if __name__ == "__main__":
app.run(debug=True)
The route receive a dict as input so you must change #app.route("/dashboard") to #app.route("/dashboard/<input>") and pass input to the route in the link of the route.
For example, I have a route as below.
#app.route('/user/<name>')
def user(name):
return render_template('home.html', name=name)
To pass name to the route, I access the link http://localhost:5000/user/myname.

Running a simple python flask application using .cfg config files. I can't seem to return the config values, getting a keying error with them

The aim of this program is just to return the values that are passed from a .cfg configuration file called 'defaults.cfg'.
I totally understand what should be getting passed here and to be honest the code for all intents and purposes is copied from an exercise, but it fails with a 'Keying error: (value)' (all values give the keying error, it's just whatever is first) and I don't know why. I've been unable to find a solution online and the code is the same in principle as a friend's more complicated program running a proper web application and his works just fine.
Apparently using capitals for the config keys is a thing and I've done that and I'm sure I have all the necessary libraries/binaries installed.
I'm doing this on Bash on Windows on Ubuntu.
Thanks in advance for any consideration.
default.cfg
[config]
DEBUG = True
IP_ADDRESS = 0.0.0.0
PORT = 5000
configuration.py
import ConfigParser
from flask import Flask
app = Flask(__name__)
#app.route('/')
def root():
return "Sup! Hollerin' at ya from the configuration testing app"
#app.route('/WTF/')
def tellMeh():
return app.config['PORT']
#app.route('/config/')
def config():
str = []
str.append(app.config['DEBUG'])
str.append('port:'+app.config['PORT'])
str.append('ip_address:'+app.config['IP'])
return '\t'.join(str)
def init(app):
config = ConfigParser.ConfigParser()
try:
config_location = "etc/defaults.cfg"
config.read(config_location)
app.config['DEBUG'] = config.get("config", "DEBUG")
app.config['IP'] = config.get("config", "IP_ADDRESS")
app.config['PORT'] = config.get("config", "PORT")
print "Succesfully read configs from: ", config_location
except:
print "Couldn't read configs from: ", config_location
if __name__ == '__main__':
init(app)
app.run(
host=app.config['IP'],
port=int(app.config['PORT']))
You'll get different behavior from that code depending on how you invoke it.
FLASK_APP=configuration.py flask run will skip the section at the bottom where init(app) is called
python configuration.py will run that section, calling init(app).
You might wish to move the call to init() to right below app = Flask(...).

Why is the function from one file returns 'none' value when calling in another file in Flask Python

Good evening, everyone!
I have a problem with returning the value while running my programming code below:
# -*- coding: utf-8 -*-
from flask import Flask, jsonify
from aldd import *
app = Flask(__name__)
names1=""
#app.route('/hashtags/'+b'<name>'.decode('utf-8'), methods=['GET'])
def hash(name):
name1 = "#" + name
d=startet(name1)
print(d)
app.config['JSON_AS_ASCII'] = False
return jsonify({'Segmentation hashtags': d})
if __name__ == '__main__':
app.run(port=9876)
In my file I call another file named "aldd.py" with it's internal function "def startet(nam)", which has one argument inside. However, when calling this function in my current file with the argument "name1", there's no error and all I get is a "None" value as output.
Basically, I run the program in Chrome browser and it looks like following:
My project structure looks like this:
I guess the error might be caused by transferring the argument "name1" of this function to the same function in "aldd.py". But I might be mistaken.
Help me, please!
Thanks in advance!
Your startet function in aldd.py is not returning anything.
Try adding this line at the end of the startet function
return 'testing testing .. 123'

web.py / pythonpath confusion

Im playing around with web.py as a lightweight web framework. Im having problems when i attempt to move the actual implementation of my page into a separate file instead of the root file. As a demonstration, My core.py file looks like this:
import web, sys, os
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
urls = (
'/', 'index'
)
app = web.application(urls, globals())
render = web.template.render('templates/')
if __name__ == "__main__":
app.run()
ive moved my implementation into a file called index.py at the same level as core.py. My implementation looks like this:
class index:
def GET(self):
return "Hello world"
however, whenever i run my application, i get an error:
<type 'exceptions.KeyError'> at /
can anybody tell me what is going on?
According to http://webpy.org/tutorial3.en#urlhandling, web.py does a lookup for the classes you specified in your urls in the global namespace.
In your core.py there is no class named index (after you moved it), that's what causes this keyerror. In my test I could fix that by importing the index class in core.py.
from index import index
(I haven't used web.py before, so please correct me if I'm wrong)
You can add dots to crawl into modules. So say you have a folder controllers with a file named file.py and you wanted to access the controller named index:
from controllers import *
urls = (
'/', 'controllers.file.index'
)
I'm guessing the bug is in your template. I hit this error when if forgot a ':' on an if statement in my template.

Categories