Flask With Swagger Log input and output - python

I am using Flask with swagger to create an apis system. Which has json as entry and exit points.
from flask import Flask
app = Flask(__name__)
Swagger(app)
#app.route('/some_url', methods=['POST'])
def get_output():
return json.dumps({"status":"Success"})
The Input for above is e.g.
{"username":username,"password":password,}
Like Above I have several other methods either GET or POST.
Is it possible to log the entry exit points E.g. as in Above Example I should be able to log following
{"username":username,"password":password,} as entry point
{"status":success} as exit point.
As well if some error should be able to log it. Looking forward for right way of doing same.

There are some decorators can help you to achieve that.
You can log request.path, request.head, request.args, request.form, request.data in #app.before_request.
You can log response.data in #app.after_request.

Related

How can i run a function based on the status code on a flask app

I have been messing around with flask on my raspberry pi and i've noticed every time i open the webpage i have as a template on it there are a bunch of status codes displayed (mostly 200 thankfully) and i'd like to display them on a seven segment led display.
I have the electronics side of things sorted out and even made a library to control my seven segment display (the main feature being a function that takes an array of 3 digits and displays them). I did all this assuming the easy part would be just inputing the status code but i can't figure out how to do that.
I've looked into it and thought i could use error handling but that would only work for status codes that correspond to an error and not the ones such as 200.
Any pointers ?
You can use #app.after_request
I use this in many of my projects for posting log messages or metrics about calls made to my server. Combining before_request and after_request is also a common solution that many libraries use to implement features such as authentication in the flask framework.
Example:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
print(f"Running from hello_world")
return 'Hello, World!'
#app.after_request
def print_status_code(response):
print(f"Status code is {response.status_code}")
app.run()
After making a GET call to http://127.0.0.1:5000/ You will see:
Running from hello_world
Status code is 200

How to call a Python Bottle API from within that application

I have created an API using the Bottle Library in Python. It endpoints look like this
#app.get('/api/users/<id>', name='user')
def get_user(model, id):
user = model.get_user(id)
if not user:
return HTTPError(404, 'User not found')
else:
response.content_type = "application/json"
return json.dumps(user)
I want to call the API in other functions within the same app
#app.route('/users/<id>')
def users (id=1):
user = request.get("http://localhost:8001/api/user/1")
return template('user', user=user)
However, this is showing no results. The request get timed out each time
So my question is, how to call a bottle API from within that app using Requests library or through any other means.
Are you running Bottle in single-threaded mode (the default)? If so, then your internal get request will hang forever. This is because your server can serve only one request at a time, and you are asking it to handle two at once: the first call to /users/<id>, and then the second call to /api/users/<id>.
A band-aid fix would be to run the server in asynchronous mode. Try this method and see if your timeouts go away:
run(host='0.0.0.0', port=YOUR_PORT_NUMBER, server='gevent')
However: You shouldn't be designing your application this way in the first place. Instead, refactor your code so that both methods can call a function that returns the JSON representation of a user. Then one api call can return that raw json object, while the other api call can present it as HTML. NOTE: that's not how I would design this API, but it's the answer that's the shortest distance from how you've structured your application so far.

Suggestion on documenting endpoints for a Python Bottle web service

I have a portion of my API that i am exposing using Bottle (http://bottlepy.org/docs/dev/index.html).
I am now looking to document these endpoints for the end user clients and am looking for a good solution. I am looking for something that is tightly integrated with my"routes" defined in the Bottle app so that any changes in the future keep in sync. The key areas i want to document are the HTTP method types that are accepted and the necessary query parameters.
I have included an example route below which queries whether an instance defined in the underlying API is online. As you can see the route only accepts GET requests, and the "check_valid_instance" function expects to find a query parameter. Looking at this route definition there is no indication that a query param is needed and that is what i am trying to add here! Both to the source code, and also externally to some type of help page
#app.route("/application/app_instance/is_instance_online", method="GET")
def is_instance_online():
_check_valid_instance()
function = eval("app_instance.is_instance_online")
return _process_request_for_function(function)
The above route would be called as following
http://IP:Port/applicaton/app_instance/is_instance_online?instance=instance_name
Any suggestions welcome!
Thanks!
For additional params you can create a structure similar to this:
COMMANDS = {'is_instance_online': {'mandatory_params': 'instance_name',
'description': 'command description'}}
self.bottle.route('/<command>', method='GET', commands=COMMANDS)(self.command_execute)
Then you should be able to generate JSON description of the whole API as shown below:
Automatic Generation of REST API description with json

WebApp needs to do something first time only, where to put that logic? Flask or django

The web app I am working on needs to perform a first-time setup or initialization,
where is a good place to put that logic? I dont want to perform the check if a configuration/setup exists on each request to / or before any request as thats kind of not performant.
I was thinking of performing a check if there is a sane configuration when the app starts up, then change the default route of / to a settings/setup page, and change it back. But thats like self-changing code a bit.
This is required since the web app needs settings and then to index stuff based on those settings which take a bit of time. So after the settings have been made, I still need to wait a while until the indexing is done. So even after the settings/setup has been made, any requests following, will need to see a "wait indexing" message.
Im using flask, but this is relevant for django as well I think.
EDIT: Im thinking like this now;
When starting up, check the appconfig.py for MY_SETTINGS, if it is not there
add a default from config.py and put a status=firstrun object on the app.config, also
change the / route to setup view function.
The setup view function will then check for the app.config.status object and perform
The setup of settings as necessary after user input, when the settings are okay,
remove app.config.status or change it to "indexing", then I can have a before_request function to check for the app.config.status just to flash a message of it.
Or I could use the flask.g instead of app.config to store the status?
The proper way is creating a CLI script, preferably via Flask-Script if you use Flask (in Django it would be the default manage.py where you can easily add custom commands, too) and defining a function such as init or install:
from flaskext.script import Manager
from ... import app
manager = Manager(app)
#manager.command
def init():
"""Initialize the application"""
# your code here
Then you mention it in your documentation and can easily assume that it has been run when the web application itself is accessed.

How do I stop 'print' from outputting to the browser with Google App Engine?

I'm new to GAE, and have not been able to figure out how to configure 'print' statements to the logging console rather than the browser. For example:
class Feed(webapp.RequestHandler):
def post(self):
feeditem = Feeditem()
feeditem.author = self.request.get('from')
feeditem.content = self.request.get('content')
feeditem.put()
notify_friends(feeditem)
self.redirect('/')
def notify_friends(feeditem):
"""Alerts friends of a new feeditem"""
print 'Feeditem = ', feeditem
When I do something like the above, the print in notify_friends outputs to the browser and somehow prevents the self.redirect('/') in the post method that called it. Commenting it out corrects the issue.
Is there a way to change this behavior?
EDIT: Google App Engine tag removed as this is general.
You should instead use the logging module, like so:
import logging
def notify_friends(feeditem):
"""Alerts friends of a new feeditem"""
logging.info('Feeditem = %s', feeditem)
There are a variety of logging levels you can use, from debug to critical. By default, though, the App Engine SDK only shows you log messages at level info and above, so that's what I've suggested here. You can ask it to show you debug messages if you want, but you'll probably be overwhelmed with useless (to you) logging information, at least when running in the SDK.
See the logging module docs for more info.
Oh, and the nice thing about using the logging module is that you'll have access to your log messages in production, under the "Logs" section of your app's the App Engine dashboard.
This is not just a problem with GAE. It is a general issue. You can't print out HTML and then try to have a redirect header. The answer to your question is no, you can't change the behavior. What exactly are you trying to achieve? You might be able to get what you want a different way.

Categories

Resources