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");
Related
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
I have a file called redis_db.py which has code to connect to redis
import os
import redis
import sys
class Database:
def __init__(self, zset_name):
redis_host = os.environ.get('REDIS_HOST', '127.0.0.1')
redis_port = os.environ.get('REDIS_PORT', 6379)
self.db = redis.StrictRedis(host=redis_host, port=redis_port)
self.zset_name = zset_name
def add(self, key):
try:
self.db.zadd(self.zset_name, {key: 0})
except redis.exceptions.ConnectionError:
print("Unable to connect to redis host.")
sys.exit(0)
I have another file called app.py which is like this
from flask import Flask
from redis_db import Database
app = Flask(__name__)
db = Database('zset')
#app.route('/add_word/word=<word>')
def add_word(word):
db.add(word)
return ("{} added".format(word))
if __name__ == '__main__':
app.run(host='0.0.0.0', port='8080')
Now I am writing unit test for add_word function like this
import unittest
import sys
import os
from unittest import mock
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../api/")
from api import app # noqa: E402
class Testing(unittest.TestCase):
def test_add_word(self):
with mock.patch('app.Database') as mockdb:
mockdb.return_value.add.return_value = ""
result = app.add_word('shivam')
self.assertEqual(result, 'shivam word added.')
Issue I am facing is that even though I am mocking the db method call it is still calling the actual method in the class instead of returning mocked values and during testing I am getting error with message Unable to connect to redis host..
Can someone please help me in figuring out how can I mock the redis database calls.
I am using unittest module
The issue is that db is defined on module import, so the mock.patch does not affect the db variable. Either you move the instantiation of
db in the add_word(word) function or you patch db instead of Database, e.g.
def test_add_word():
with mock.patch('api.app.db') as mockdb:
mockdb.add = mock.MagicMock(return_value="your desired return value")
result = app.add_word('shivam')
print(result)
Note that the call of add_word has to be in the with block, otherwise the unmocked version is used.
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:
...
I would like to upload multiple files using a thread. This way the files can upload in the background and not make the user wait.
Here is my simplified code:
In app.py:
from file_upload import upload_process
from flask import request
#app.route('/complete', methods=['POST'])
def complete():
id = 5 #for simplified example
upload_process(id) #My thread
...
return render_template('complete.html')
In file_upload.py
from threading import Thread
from flask import request
def upload_process(id):
thr = Thread(target = upload_files, args = [id])
thr.start()
def upload_files(id):
file_1= request.files['file_1']
file_2= request.files['file_2']
file_3= request.files['file_3']
newFiles = FileStorage(id= id, file_1 = file_1.read(), file_2 =
file_2.read(), file_3 = file_3.read())
db.session.add(newFiles)
db.session.commit()
I get the 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.
How would I get the request to work within the upload_files function.
(Without threading the files upload correctly.)
The following code is used to fetch logs from app engine for further processing. However I do not know how to use the result of logservice.fetch to access log messages now??
import cgi
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from google.appengine.api.logservice import logservice
logservice.AUTOFLUSH_ENABLED = False
class MainPage(webapp.RequestHandler):
def get(self):
requestlogs = logservice.fetch(start_time=1332200000, end_time=1332249954, offset=None, minimum_log_level=logservice.LOG_LEVEL_INFO, include_incomplete=False, include_app_logs=True, version_ids=None, batch_size=None)
self.response.out.write(requestlogs)
c=0
for iter in requestlogs:
c=c+1
print c
application = webapp.WSGIApplication([('/logs', MainPage)], debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
In your case, the code would look something like this:
from google.appengine.api import logservice
MAX_LOGS_TO_READ = 10
class MainPage(webapp.RequestHandler):
def get(self):
request_logs = logservice.fetch()
current_log = 0
for log in request_logs:
if current_log > MAX_LOGS_TO_READ:
break
self.response.out.write(log.combined)
A couple of comments..
Use self.response.out.write() to write data to the response output stream.
fetch() returns an iterator of RequestLog objects. You can use this iterator then in a for loop to go over the set of logs the iterator knows about.
RequestLog objects return a number of attributes, which are mostly documented here: http://code.google.com/appengine/docs/python/logservice/requestlogclass.html