Python POST api giving error. Logs not found - python

I am new with python. I have a POST api in python deployed on AWS using steps from the below mentioned link.
https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-16-04
The api is giving internal server error and the logs are not getting printed. Is there a directory which I'm missing or can I print the logs somehow?
Also if someone can help with what could be the possible issue with the API :
#!/usr/bin/env python2.7
#!flask/bin/python
#!/usr/bin/python
import numpy
import sys,os
import codecs
import json
import phonetics
import transliteration
import jellyfish
import traceback
from pyjarowinkler import distance
from flask import Flask, jsonify, request
import panphon.distance
from datetime import datetime
from flask_cors import CORS
def obj_dict(obj):
return obj.__dict__
# logFile = open('log.txt','a')
app = Flask(__name__)
cors = CORS(app, resources={r"/todo/api/*": {"origins": "*"}})
#app.route('/todo/api/v1.0/tasks', methods=['GET''POST'])
def get_tasks():
if request.method == 'GET':
return "done with get request"
elif request.method == 'POST':
try :
content = request.get_json()
with codecs.open('words.txt', 'a') as file:
for line in content['words']:
file.write("\n"+line.encode('utf-8'))
except Exception:
with open('log.txt','a') as logger:
logger.write("At "+str(datetime.now())+" "+traceback.format_exc())
logger.write("\n\n")
return "done"
if __name__ == '__main__':
import logging
logging.basicConfig(filename='log.txt',level=logging.DEBUG)
app.run(host='0.0.0.0', debug = False)
NOTE: The other imports are for some other purpose. I need the POST API to work.

Try setting debug = True
For example
if __name__ == '__main__':
import logging
logging.basicConfig(filename='log.txt',level=logging.DEBUG)
app.run(host='0.0.0.0', debug = True)
Also you don't need to import logging as you can use flask's logger which should be accessible using app.logger
If this is production then debug=True is not recommended.
Flask considers ERROR as the default logging level if you do not set up log level
So you might try setting the log level using app.logger.setLevel(logging.DEBUG)
#app.route('/todo/api/v1.0/tasks', methods=['GET', 'POST'])
def get_tasks():
if request.method == 'GET':
return "done with get request"
elif request.method == 'POST':
try :
content = json.loads(request.get_data())
with codecs.open('words.txt', 'a') as file:
for line in content['words']:
file.write("\n"+line.encode('utf-8'))
except Exception:
with open('log.txt','a') as logger:
logger.write("At "+str(datetime.now())+" "+traceback.format_exc())
logger.write("\n\n")
return "done"

Related

Possible to shut down a Flask app without starting/stopping a server, calling os.kill, or using command line?

I need to start and stop a simple Python app on a Flask server after the app runs and modifies files in the home directory. The app is housed on G Cloud. I've researched similar questions that involve using the command line, os, and http.server to stop the app. None of these approaches will work in my case. The best option seems to be to make a request to an app route that contains a request.environment.get function, which I've tried to do here. But the script triggers the following tracebacks: TypeError: The view function did not return a valid response. The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a Response. And TypeError: shutdown_server() takes 0 positional arguments but 2 were given. Can I shut down the app using a script and without starting/stopping a server (i.e., using http.server)? If so, what am I doing wrong?
from flask import Flask, render_template, request, jsonify
import urllib.request, urllib.parse, urllib.error
from urllib.request import urlopen
from bs4 import BeautifulSoup
import textwrap
from hidden import consumer_key, consumer_secret, access_token, access_token_secret
import tweepy
from tweepy import TweepError
import requests
app = Flask(__name__, template_folder = 'templates')
app.config.update(
SERVER_NAME = "127.0.0.1:8080"
)
#app.route('/')
def check_status():
with open('app_status.txt') as f:
status = f.read()
status = status.rstrip()
status = int(status)
if status == 1:
with open('app_status.txt', 'w+') as f:
f.write(F'0')
print('exiting')
return requests.get('http://127.0.0.1:8080/shutdown')
if status == 0:
return get_chunk()
def get_chunk():
...
# Create the app's weboutput by rendering an html template
if tweet:
with open('app_status.txt', 'w+') as f:
f.write(F'1')
with app.app_context():
return render_template('index.html', excrpt = chunk_wrp), requests.get('http://127.0.0.1:8080/shutdown')
#app.route("/shutdown", methods=['GET'])
def shutdown():
shutdown_func = request.environ.get('werkzeug.server.shutdown')
if shutdown_func is None:
raise RuntimeError('Not running werkzeug')
shutdown_func()
return "Shutting down..."
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080, debug=True, use_reloader=True)
A look at the mod_wsgi documentation yielded code for killing a daemon process. For the moment, this appears to be working:
import signal
import os
#...#
def shutdown():
return os.kill(os.getpid(), signal.SIGINT)

How to solve Flask/Heroku Error: “Method Not Allowed The method is not allowed for the requested URL”

I'm working with flask, heroku and flutter but when I call the the url I got the following error. This is my code for the app.py:
from flask import Flask, jsonify, request
import pandas as pd
import numpy as np
import joblib
import traceback
from flask_restful import reqparse
app = Flask(__name__)
"""#app.route("/", methods=['GET'])
def hello():
return "hey"""
#app.route('/', methods=['POST'])
def predict():
lr = joblib.load("model.pkl")
if lr:
try:
json = request.get_json()
model_columns = joblib.load("model_cols.pkl")
temp=list(json[0].values())
vals=np.array(temp)
prediction = lr.predict(temp)
print("here:",prediction)
return jsonify({'prediction': str(prediction[0])})
except:
return jsonify({'trace': traceback.format_exc()})
else:
return ('No model here to use')
if __name__ == '__main__':
app.run(debug=True)
It is already on the Heroku app. The link for the heroku is the following: https://myappflutterflask.herokuapp.com/
Looks like you're exposing the POST method in your program but accessing it using GET (perhaps via the web browser).
You may need to use a different client to test it: browser plugin, Postman, curl for example.

Python: How to print from flask to console

I am working on a facebook chatbot. I know there are some post for the similar question, but I cannot get it works.
Below is my code:
from __future__ import print_function
import sys
from flask import Flask, request, app
API_ROOT = '/webhook'
app = Flask(__name__)
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
#app.route(API_ROOT, methods=['POST'])
def fb_receive_message():
eprint('message received')
if __name__ == '__main__':
eprint('Hello world!')
app.run(host='XXX.XXX.XXX.XXX',debug=True,port=XXX)
Outcome:
Hello world!
* Restarting with stat
when I try with "post" then it does not print anything

Unable to log messages while running a Flask app

I am trying to tie Flask's logger to a FileHandler, so I can save custom log messages to a file. Anytime I try to log a message when a POST requests hits foo, nothing happens, at all. How can I work around this?
import logging
from logging import FileHandler
from time import strftime
from flask import Flask, Response
app = Flask(__name__)
#app.route('/foo', methods=['POST'])
def bar():
app.logger.info('post request')
...
return Response(), 200
if __name__ == "__main__":
file_date = strftime('%d_%m_%Y')
handler = FileHandler(f'./log/{file_date}.log')
handler.setLevel(logging.INFO)
app.logger.setLevel(logging.INFO)
app.logger.addHandler(handler)
app.run()

How to log to socket in Flask

I have the rest of my program using a socketHandler to log which is being consumed using http://code.activestate.com/recipes/577025-loggingwebmonitor-a-central-logging-server-and-mon/.
How do I setup my flask app to log this?
I tried the following based on their docs (http://flask.pocoo.org/docs/errorhandling/#logging-to-a-file):
class HelloWorld(Resource):
def get(self):
resp = "HELLO!"
app.logger.info("GET HelloWorld %s", resp)
return resp
if __name__ == '__main__':
import logging
import logging.handlers # you NEED this line
socketHandler = logging.handlers.SocketHandler('localhost',
logging.handlers.DEFAULT_TCP_LOGGING_PORT)
socketHandler.setLevel(logging.INFO)
app.logger.addHandler(socketHandler)
app.run('0.0.0.0')

Categories