Flask-pymongo RuntimeError: Working outside of application context - python

I'm writing a program to read mongodb document based on id field using flask-pymongo. But I'm getting error, can anybody tell me where am I going wrong?
code:
from flask import Flask, make_response, jsonify
from flask_pymongo import PyMongo
from collections import OrderedDict
from bson import json_util
import json
app = Flask('__name__')
app.config['MONGO_DBNAME'] = 'db_name'
app.config['MONGO_URI'] = 'mongodb://192.168.55.24:27017/db_name'
mongo_connection = PyMongo(app)
#app.route('/')
def index(inp_id):
collection = mongo_connection.db.table_name
one_record = collection.find_one({'id': inp_id})
obj_str = json_util.dumps(one_record)
obj_dict = json.loads(obj_str, object_hook=OrderedDict)
return make_response(jsonify(obj_dict), 200)
if __name__ == '__main__':
index('5cd00a468b36db516b6d2f16') # I think this is where I'm going wrong
giving me the below error:
RuntimeError: Working outside of application context.
If I pass id value directly in the place of inp_id I get the result but I'm trying to write a generic one.

Flask has an application context, You might need to use app.app_context() to make it work.
The application context keeps track of the application-level data
during a request, CLI command, or other activity. Rather than passing
the application around to each function, the current_app and g proxies
are accessed instead.
Try this :
def index(inp_id):
with app.app_context():
collection = mongo_connection.db.table_name
one_record = collection.find_one({'id': inp_id})
obj_str = json_util.dumps(one_record)
obj_dict = json.loads(obj_str, object_hook=OrderedDict)
return make_response(jsonify(obj_dict), 200)
For more information, read Flask Application context

Related

Issue with simple python API in flask. Trying to create a post method to add json data to a list

I am trying to build a simple flask api to post json data to a list (eventually with be redshift but this is just a simple test program).
I have attached the api code first followed by the code to send data.
I am getting internal server error issues when running the second script.
The code seems very simple though and I cannot figure out what is wrong.
from flask_restful import Api, Resource
from flask import request
app = Flask(__name__)
api = Api(app)
audit_log = []
class audit(Resource):
#def get (self):
#return {"data":"HelloWorld"}
def put (self):
new_item = request.get_json()
audit_log.append(new_item)
return new_item
api.add_resource(audit,"/")
app.run()
import requests
BASE = "HTTP://127.0.0.1:5000/"
response = requests.put(BASE, params = {'auditid' : 'xyz', 'jobname' : 'abc'})
print (response.json())
It seems that you haven't imported the Flask properly
instead of this
from flask import request
use this
from flask import Flask, request
This should work fine...

Fetching MongoDB data in Flask using pyMongo

I need help with fetching data from a MongoDB collection in a simple Flask webpage. I've been trying to figure out how to fetch it but it has been of no help. My JSON data is an array of documents with 3 nested fields and I have attached it with the question. I'm trying to fetch all the data of the JSON template at first but I've been unable to. Once I know, I'll fetch the individual array.
Here is my Flask code:
from flask import Flask
from pymongo import MongoClient
app = Flask(__name__)
client = MongoClient("mongodb://localhost:27017/")
db = client.Learning
todos = db.data
#app.route('/')
def lists():
for x in todos.find():
y = print(x)
return ""
if __name__ == '__main__':
app.run()
And this is my data structure for the MongoDB data:
Any help or hint will be really appreciated so I can know how to fetch the data. Do I have to use HTML? If so, how can I fetch the arrays within arrays with HTML?
You could try using Flask-PyMongo.
It works like this:
from flask import Flask
from flask_pymongo import PyMongo
from flask.json import jsonify
app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://localhost:27017/Learning"
mongo = PyMongo(app)
#app.route("/")
def lists():
print([i for x in mongo.db.data.find({})])
return jsonify([i for i in mongo.db.data.find({})])
if __name__ == '__main__':
app.run()

How to use Python 3 imports properly in Google Cloud Functions

I am making a simple function to check a URL status and redirect on 404. This app works fine in Flask localhost but when I move this to Google Cloud Functions, I keep getting "Error: could not handle the request". This is when my parameters on both the Cloud Function and the localhost are the exact same.
Am I doing something wrong with importing 'redirect' from Flask?
GCLOUD CODE: NOT WORKING
from flask import Flask, redirect
from flask import request
import requests
def urlincoming():
custID = request.args['custID']
token = request.args['token']
custEmail = request.args['custEmail']
storeDomain = request.args['domain']
adminEmail = request.args['adminEmail']
baseUrl = f"{storeDomain}/account/reset/{custID}/{token}"
baseUrlFailedAuth = f"{storeDomain}/account/invalid_token"
requestBaseUrl = requests.head(baseUrl)
if(requestBaseUrl.status_code == 200):
return redirect(baseUrl)
else:
return redirect(baseUrlFailedAuth)
LOCALHOST CODE: WORKING
from flask import Flask, redirect
from flask import request
import requests
app = Flask(__name__)
#app.route('/urlincoming')
def urlincoming():
custID = request.args['custID']
token = request.args['token']
custEmail = request.args['custEmail']
storeDomain = request.args['domain']
adminEmail = request.args['adminEmail']
baseUrl = f"{storeDomain}/account/reset/{custID}/{token}"
baseUrlFailedAuth = f"{storeDomain}/account/invalid_token"
requestBaseUrl = requests.head(baseUrl)
if(requestBaseUrl.status_code == 200):
return redirect(baseUrl)
else:
return redirect(baseUrlFailedAuth)
All Google Cloud Functions need to have one of the following two signatures:
HTTP Functions:
function_name(request):
...
Background functions:
function_name(data, context):
...
Depending on the type of function you're creating, you either need to add the request or data, context arguments.
from flask import redirect
import requests
def urlincoming(request):
I was able to fix things by adding the request as a argument but I'm not sure why it worked :/

Difficulty implementing server side session storage using redis and flask

I have a setup where a node.js app is making ajax requests to a flask based python server. Since ajax requests lack cookie data, I can't use the simple flask session object to persist data across requests. To remedy this, I'd like to implement a redis based server side implementation of a session storage system, but the solutions I've found so far do not work.
One solution I've tried is the following this snippet.
But this doesn't work. Is there more setup I need to do to configure redis beyond what is mentioned in the quickstart guide? Here is my attempt:
...
from flask import session
# Snippet code is copy pasted here verbatum
import session_interface
...
app = Flask(__name__)
app.session_interface = session_interface.RedisSessionInterface()
...
# Can't access this as session['key'] across requests
session['key'] = value
...
if __name__ == '__main__':
app.secret_key = '123456789012345678901234'
app.run(debug=True)
Another solution I've tried is importing the Flask-Session extention.
However, I can't get this to work either. The section I'm confused about is the following:
"We are not supplying something like SESSION_REDIS_HOST and SESSION_REDIS_PORT, if you want to use the RedisSessionInterface, you should configure SESSION_REDIS to your own redis.Redis instance. This gives you more flexibility, like maybe you want to use the same redis.Redis instance for cache purpose too, then you do not need to keep two redis.Redis instance in the same process."
What is meant by this section and how would I have figured this out? Here is my attempt to make this extension work:
...
from flask import session
from flask_session import Session
import redis
...
app = Flask(__name__)
SESSION_TYPE = 'redis'
app.config.from_object(__name__)
Session(app)
...
# Can't access this as session['key'] across requests
session['key'] = value
...
if __name__ == '__main__':
app.secret_key = '123456789012345678901234'
app.run(debug=True)
Has anyone successfully implemented manual session storage on a server running flask? Are there other options for getting this functionality?
Thanks for your input.
I think that's because you missed the URL configuration for your storage Redis, to check that, you can use Redis-CLI to see if there is anything being inserted into Redis.
I use this code and it worked:
from flask import Flask
from flask_session import Session
import redis
……
app = Flask(__name__)
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.from_url('127.0.0.1:6379')
sess = Session()
sess.init_app(app)
def getSession():
return session.get('key', 'not set')
def setSession():
session.set('key')=123
return 'ok'
……
The following works for me:
...
from flask_session import Session
import redis
...
app = Flask(__name__)
SECRET_KEY = '123456789012345678901234'
SESSION_TYPE = 'redis'
SESSION_REDIS = redis.from_url('localhost:6379')
app.config.from_object(__name__)
sess = Session()
sess.init_app(app)
...
# Should be available accross requests now
session['key'] = value
...
if __name__ == '__main__':
app.run(debug=True)
Using sess.init_app(app) instead of Session(app) did the trick.

flask context inside context , for jsonfy, all in a single page

I'm having a single test for retrieve documents in a single page, i know it's not correct to do in a single page; but it's just to understand all this work like pure script, not for an api restful.
My problem is when i use:
print (jsonify({'result' : output}))
i've get this error:
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.
when I replace this line by
print ( output)
have no erros and have the documents.
How i can to specify a context for jsonify ? inside another context ? because i'm already using
with app.app_context():
Here the code:
from flask import Flask
from flask import g
from flask import jsonify
from flask import request
from flask_pymongo import PyMongo
from flask import make_response
from bson.objectid import ObjectId
from flask import current_app
import sys
app = Flask(__name__)
app.config['MONGO_DBNAME'] = 'restdb'
app.config['MONGO_URI'] = 'mongodb://localhost:27017/crm1'
#app.errorhandler(404)
def not_found(error):
return make_response(jsonify({'error':'Notfound' }),404)
with app.app_context():
mongo = PyMongo(app)
star = mongo.db.accounts
output = []
for s in star.find():
output.append({'id': str(s['_id']) ,'firstname' : s['firstname'], 'lastname' : s['lastname']})
print (jsonify({'result' : output}))
#print ( output)
if __name__ == '__main__':
app.run(debug=True)
Jsonify Works with HttpResponse.
You can use python json module and print the output
Like:
import json
print(json.dumps(output))

Categories