How to use flask context with concurrent.futures.ThreadPoolExecutor - python

I'm trying to make multiple requests async and get response back, I'm using concurrent.futures to do this, but inside my function using current_app which from flask and I always got this error:
RuntimeError: Working outside of application context.
I don't know how to resolve this. Can anyone please help?
Below are my code:
run.py:
import concurrent.futures
from flask import current_app
from http_calls import get_price, get_items
def init():
with current_app._get_current_object().test_request_context():
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
futs = []
futs.append(executor.submit(get_price))
futs.append(executor.submit(get_items))
print([fut.result() for fut in concurrent.futures.as_completed(futs)])
init()
http_calls.py
from flask import current_app
def get_price():
url = current_app.config['get_price_url']
return requests.get(url).json()
def get_items():
url = current_app.config['get_items_url']
return requests.get(url).json()

I was running into similar issues around using concurrent.futures with Flask. I wrote Flask-Executor as a Flask-friendly wrapper for concurrent.futures to solve this problem. It may be an easier way for you to work with these two together.

You should import your Flask instance in your script. Use current_app under the app context.
import concurrent.futures
from your_application import your_app # or create_app function to return a Flask instance
from flask import current_app
from http_calls import get_price, get_items
def init():
with your_app.app_context():
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
...

Related

Python, fastAPI, uvicorn - Error loading ASGI app. Could not import module "main"

I am having trouble with getting uvicorn to start. I am very new to python and fastapi so I am assuming I have doing something very silly.
I have isolated the problem to being in my api_router.py file
from fastapi import APIRouter
from API.endpoints import user_endpoints
api_router = APIRouter()
api_router.include_router(user_endpoints, prefix="/user", tags=["User"])
When I comment out from API.endpoints import user_endpoints and
api_router.include_router(user_endpoints, prefix="/user", tags=["User"]), the error does not occur. Am I trying to import my user_endpoints.py file incorrectly? I have attached an image of the directory structure.
user_endpoints.py looks like this:
from fastapi.routing import APIRouter
from typing import Optional, List
from API.schema.user import User
from models.user import Users
from main import db
router = APIRouter
#router.get('/users', response_model=List[User], status_code=200)
def get_all_users():
users=db.query(Users).all()
return users
#router.get('/users/{user_id}')
def get_user(user_id):
pass
#router.post('/users')
def create_user():
pass
#router.put('/users/{user_id}')
def update_user(user_id):
pass
#router.delete('/users/{user_id}')
def delete_user(user_id):
pass
Any help with this would be greatly appreciated.
Thanks,
Greg
I think it's talking about the current working directory of your terminal, when you feed it uvicorn main:app ... not being able to find main. Make your terminal's working directory same as main.py

Python Return multiple variables after pause in function

I have found a piece of flask: https://github.com/pratik55/Python-Flask-dynamic-update- code that dynamically updates the HTML, but it requires a function like time.time() - it outputs, pauses, and outputs again. I would like a custom function to do just this but not with a time value.
I tried something similar to this https://www.geeksforgeeks.org/g-fact-41-multiple-return-values-in-python/ but I could not put a pause in between each output.
The flask code looks like this:
from flask import Flask, jsonify, render_template, request
import webbrowser
import time
app = Flask(__name__)
#app.route('/_stuff', methods = ['GET'])
def stuff():
return jsonify(result=time.time())
#app.route('/')
def index():
return render_template('dy1.html')
if __name__ == '__main__':
app.run()
The result is just a question mark when I replace result=time.time() with something else unless its very explicit like result="hello"
Thanks

Running Flask from an imported module

I'm trying to run Flask from an imported module (creating a wrapper using decorators).
Basically I have:
app.py:
import mywrapper
#mywrapper.entrypoint
def test():
print("HEYO!")
mywrapper.py
from flask import Flask
ENTRYPOINT = None
app = Flask(__name__)
#app.route("/")
def listen():
"""Start the model API service"""
ENTRYPOINT()
def entrypoint(f):
global ENTRYPOINT
ENTRYPOINT = f
return f
FLASK_APP=app
Running python -m flask, however, results in:
flask.cli.NoAppException: Failed to find Flask application or factory in module "app". Use "FLASK_APP=app:name to specify one.
Is there any trick to getting Flask to run like this? Or is it just not possible? The purpose of this is to abstract Flask away in this situation.
In my head flask should try to import mywrapper.py, which imports app.py which should generate the app and route, yet this doesn't seem to be what occurs.
Any help would be appreciated.
So I've since learnt that Flask searches only in the chosen module's namespace for a variable containing a Flask object.
There may be a smart way to avoid this limitation, but I instead decided that it was more sensible to instead just wrap the Flask class itself. If people want direct Flask functionality, I don't really care in this situation, so the only real limitation I have from this is some function names are off limits.
Basically:
wrapper.py:
class Wrapper(Flask):
def __init__(self, name):
super().__init__(name)
self.entrypoint_func = None
#self.route("/")
def listen():
return self.entrypoint_func()
def entrypoint(self, f):
assert self.entrypoint_func is None, "Entrypoint can only be set once"
self.entrypoint_func = f
return f
and app.py:
from mywrapper import Wrapper
app = Wrapper(__name__)
#app.entrypoint
def test():
print("HEYO!")
return "SUCCESS"
This is still abstracted enough that I am happy with the results.

Flask socket.io message events in different files

socketservice.py:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from backend.database import db
app = Flask(__name__)
socketio = SocketIO(app, engineio_logger=True)
#socketio.on('connect')
def handle_connection():
from backend.electionAdministration import syncElections
syncElections()
if __name__ == '__main__':
socketio.run(app)
electionAdministration.py:
from flask_socketio import SocketIO, emit
from bson.json_util import dumps
from backend.socketservice import socketio
from backend.database import db
def syncElections():
elections = db.elections.find()
emit('syncElections',dumps(res) , broadcast=True)
#socketio.on('createElection')
def createElection(data):
db.elections.insert({'title': data["title"]})
syncElections()
The problem is, that the createElection event is never being called, when it is within the file electionAdministration.py. When I move it into socketservice.py, it suddenly works.
But I mean, I cannot put everything into one file, as it will get very messy as the application grows.
What you need to do is import your secondary module in the main module, but you need to do it after the socketio variable is created, because if not you will run into circular dependency errors.
Example:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from backend.database import db
app = Flask(__name__)
socketio = SocketIO(app, engineio_logger=True)
#socketio.on('connect')
def handle_connection():
from backend.electionAdministration import syncElections
syncElections()
import electionAdministration # <--- import your events here!
if __name__ == '__main__':
socketio.run(app)
In addition, you need to consider that your main Python script is not going to be called socketservice, because Python always names the top-level script __main__. So, if you start the above script as your main script, the second file should import socketio as follows:
from __main__ import socketio
This is a small annoyance with Python, which is made worse when you want to have a script that you sometimes run as a main script, but other times you also want it to be imported by another script. To make the import work in such case, I use the following trick:
try:
from __main__ import socketio
except ImportError:
from socketservice import socketio

saving data to mongodb using pymongo

I am having an issue trying to save data to MongoDB.
I first run this python program:
import pymongo
import sys
def main():
connection = pymongo.Connection("mongodb://localhost", safe = True)
db = connection.m101
people = db.people
person = {'name':'Barack Obama', 'role':'president'}
people.insert(person)
but then, when i try to retrieve the data from the mongoshell:
> use m101
switched to db m101
> db.people.find()
returns nothing! I'm not sure what is going on. Thanks for your help.
Your code is not working because main() is never called.
Adding
if __name__ == '__main__':
main()
will execute your defined main function when executed.
You are not executing your main() function so nothing was ever executed.
Simple solution
from flask import Flask
from flask_pymongo import PyMongo
import json
import datetime
import urllib, json
from flask import jsonify
from bson.json_util import dumps
#app.route("/saveBookings", methods=['POST'])
def saveBookings():
posts = mongo.db.bookings
post = {"meetingRoom_name": "kriti_jio",
"personName": "honey",
"meetingRoom_location": "kannauj",
"book_start_time": datetime.datetime.utcnow()}
post_id = posts.insert_one(post).inserted_id
return jsonify(status="done",id=dumps(post_id),action="Data saved Succesfully",error="false");

Categories