I have am writing a project with the Chalice framework. I need to interact with DynamoDB so I wanted to use library to simplify the code. I am attempting to use pynamodb and I cannot figure out what I am missing.
app.py
from chalice import Chalice
from chalicelib import AgentSkill
app = Chalice(app_name='helloworld2')
# this works
#app.route('/')
def index():
return {'hello': 'world'}
# this throws error
#app.route('/skill')
def addSkill():
f not AgentSkill.exists():
AgentSkill.create_table(read_capacity_units=1,
write_capacity_units=1, wait=True)
agsk = AgentSkill()
agsk.agentID = 1
agsk.save()
return {'success': 'true'}
chalicelib/init.py
from .AgentSkill import AgentSkill
chalicelib/AgentSkill.py
from pynamodb.models import Model
from pynamodb.attributes import (UnicodeAttribute, NumberAttribute)
class AgentSkill(Model):
class Meta:
table_name = 'agent_skill'
region = 'us-west-2'
agentID = NumberAttribute(hash_key=True)
requirements.txt
pynamodb
Is there something I am missing, or do I need to add something to the requirements.text file?
Without having pynamodb in the requirements.txt file I would get an internal server error for every call. With it added, I can now at least get the hello world to respond. /Skill then gives :
{
"Code": "InternalServerError",
"Message": "An internal server error occurred."
}
I am not sure where to go from here?
Related
Background:I'm building a basic flask app, that will allow me to return a Collection from a Atlas Compass Cluster and then use the Collection data to create an HTML container to display the data and create some D3 charts.
Issue:I've created two #app.route, to allow me to visualize how both json.dump and flask.jsonify return data, before I decide which to use Unfortunately whilst my json.dump route returns the data (via an index.html page), my jsonify doesn't seem to work.. I get the following error returned in my Terminal
Error:TypeError: jsonify() behavior undefined when passed both args and kwargs
Code:Here is my code, which shows both #app.route
import flask
from flask import Flask, jsonify
import pymongo
from pymongo import MongoClient
from bson import ObjectId, json_util
import json
cluster = pymongo.MongoClient("mongodb+srv://group2:<PASSWORD>#cluster0.mpjcg.mongodb.net/<dbname>?retryWrites=true&w=majority")
db = cluster["simply_recipe"]
collection = db["recipes_collection"]
app = Flask(__name__)
#app.route("/recipes", methods=["GET"])
def get_recipes():
all_recipes = list(collection.find({}))
return json.dumps(all_recipes, default=json_util.default)
#app.route("/recipes_jsonify", methods=["GET"])
def get_recipes_jsonify():
all_recipes = list(collection.find({}))
return flask.jsonify(all_recipes, default=json_util.default)
I'm a complete beginner with Flask, so no doubt I have missed something obvious, can anyone help?
here have a look at this example, which explaines how jsonify can handle your data:
from flask import jsonify
#app.route('/_get_current_user')
def get_current_user():
return jsonify(username=g.user.username,
email=g.user.email,
id=g.user.id)
Output:
{
"username": "admin",
"email": "admin#localhost",
"id": 42
}
Source: https://www.kite.com/python/docs/flask.jsonify
I am trying to build a skeleton-code setup for a new project.
In that case I need to use jsonify() which is imported from "flask", in order to make a str -> json.
However when I try to do this, I get a RunTimeError: "Working outside of application context".
When I google, I see a lot of people actually creating an app instance with Flask, but I do not need a app instance. I have seen people get this to work without making the app initialization (app = Flask(name)).
Anybody can explain what I am doing wrong?
This is my Controller:
# Standard library imports
import requests
import json
import logging
# Third party imports
from flask import Flask, request, jsonify
# Internal codebase
from testing import TestObjects as testObj
from core import RequestHandler as rh
from intent import Heartbeat as hb
from intent import CenterCapacity as cc
class Controller():
def __init__(self):
# Key is the naming for action internally, value is the actual syntax for the action, mathcing the DialogFlow configuration.
# If any actions change in DialogFlow, they should be corrected in the dictionary aswell.
self.actionValues = {
'getCenterCapacity': 'get.center.capacity', 'heartbeat': 'heartbeat'}
def main(self, request):
self.action = rh.getActionFromRequest(request)
print(self.action)
if self.action == self.actionValues.get('getCenterCapacity'):
print(cc.getCenterCapacity())
elif self.action == self.actionValues.get('heartbeat'):
print(hb.emptyHeartbeat())
if __name__ == '__main__':
c = Controller()
c.main(testObj.getCapacityObj())
c.main(testObj.getHeartbeatObj())
This is my intent "heartbeat" which causes the issue.
# Third party imports
from flask import jsonify
def emptyHeartbeat():
print("You entered the heartbeat method!")
msg = {
"fulfillmentMessages": [
{
"text": {
"text": [""]
}
}
]
}
return jsonify(msg)
Try replacing the jsonify function with json.dumps https://docs.python.org/3/library/json.html
I am trying to make a request for session info, and I could print out session info on python console, but can't return session info on server endpoint. The error said the object is not JSON serializable. Here is the error message:
TypeError: Object of type ListVector is not JSON serializable
I found this post relevant to my post, I tried its solution, but it didn't work for me. how can I convert rpy2.ListVector to the dictionary that can be JSON serializable? any solution?
my attempt:
from flask import Flask, jsonify, request
from flask_restplus import Api, Resource
import json
##
import os
os.environ['PYTHONHOME'] = r"C:\Users\me\AppData\Local\Programs\Python\Python37"
os.environ['PYTHONPATH'] = r"C:\Users\me\AppData\Local\Programs\Python\Python37\Lib\site-packages"
os.environ['R_HOME'] = r"C:\Program Files\R\R-3.3.2"
os.environ['R_USER'] = r"C:\Users\me\AppData\Local\Programs\Python\Python37\Lib\site-packages\rpy2"
##
app = Flask(__name__)
api = Api(app)
ns = api.namespace('ns')
## load R function
import rpy2
import rpy2.robjects as robjects
#api.route('/')
class AResource(Resource):
def post(self):
sess = robjects.r("sessionInfo()")
return jsonify({'sessioninfo': sess})
if __name__ == '__main__':
api.add_namespace(ns)
app.run(debug=True)
here I just simply make a request to the server endpoint, I can print out session info on console but not able to return it on server endpoint. how can I make this work? any quick thought? thanks
Is there any possible solution to fix this error? any idea?
follow up your above attempt, I fixed your problem as follow:
class AResource(Resource):
def post(self):
sess = robjects.r("sessionInfo()")
new_sess= { key : sess.rx2(key)[0] for key in sess.names }
return jsonify({'sessioninfo': str(new_sess)})
now you can see json output on your server endpoint.
I am using flask to create simple api. The api simply returns values from mongoDB. Everything works great if i do the connection within same function. I am not doing connection simply at start of file because i am using uwsgi and nginx server on ubuntu. If i do that then there will be a problem of fork.
However, I have to use this connection with other api so thought to make a seperate class for connection and each api will simply call it . I m using this functionality to make codes manageable. However when i try the these codes it always shows internal server error. I tried making this function static too , still the error exists.
Note - I have replaced mongodb address with xxx as i am using mongodbatlas account here
from flask import Flask
from flask import request, jsonify
from flask_pymongo import pymongo
from pymongo import MongoClient
from flask_restful import Resource, Api, reqparse
app = Flask(__name__)
api = Api(app)
#client = MongoClient("xxx")
#db = client.get_database('restdb')
#records = db.stars
class dbConnect():
def connect(self):
client = MongoClient("xxx")
db = client.get_database('restdb')
records = db.stars
return records
class Order(Resource):
def get(self):
#client = MongoClient("xxx")
#db = client.get_database('restdb')
#records = db.stars
#star = records
star = dbConnect.connect
output = []
for s in star.find():
output.append({'name' : s['name'], 'distance' : s['distance']})
return jsonify({'result' : output})
api.add_resource(Order, '/')
if __name__ == "__main__":
app.run(host='0.0.0.0')
ERROR {"message": "Internal Server Error"}
Preliminary investigation suggests that you haven't instantiated your dbConnect class. Also, you haven't called the method connect properly.
class Order(Resource):
def get(self):
db = dbConnect() # This was missing
star = db.connect() # This is how you make method call properly.
output = []
for s in star.find():
output.append({'name' : s['name'], 'distance' : s['distance']})
return jsonify({'result' : output})
Also class dbConnect() should be declared as class dbConnect:.
Bottle.py ships with an import to handle throwing HTTPErrors and route to a function.
Firstly, the documentation claims I can (and so do several examples):
from bottle import error
#error(500)
def custom500(error):
return 'my custom message'
however, when importing this statement error is unresolved but on running the application ignores this and just directs me to the generic error page.
I found a way to get around this by:
from bottle import Bottle
main = Bottle()
#Bottle.error(main, 500)
def custom500(error):
return 'my custom message'
But this code prevents me from embedding my errors all in a separate module to control the nastiness that would ensue if I kept them in my main.py module because the first argument has to be a bottle instance.
So my questions:
Has anyone else experienced this?
why doesn't error seem to resolve in only my case (I installed from pip install bottle)?
Is there a seamless way to import my error routing from a separate python module into the main application?
If you want to embed your errors in another module, you could do something like this:
error.py
def custom500(error):
return 'my custom message'
handler = {
500: custom500,
}
app.py
from bottle import *
import error
app = Bottle()
app.error_handler = error.handler
#app.route('/')
def divzero():
return 1/0
run(app)
This works for me:
from bottle import error, run, route, abort
#error(500)
def custom500(error):
return 'my custom message'
#route("/")
def index():
abort("Boo!")
run()
In some cases I find it's better to subclass Bottle. Here's an example of doing that and adding a custom error handler.
#!/usr/bin/env python3
from bottle import Bottle, response, Route
class MyBottle(Bottle):
def __init__(self, *args, **kwargs):
Bottle.__init__(self, *args, **kwargs)
self.error_handler[404] = self.four04
self.add_route(Route(self, "/helloworld", "GET", self.helloworld))
def helloworld(self):
response.content_type = "text/plain"
yield "Hello, world."
def four04(self, httperror):
response.content_type = "text/plain"
yield "You're 404."
if __name__ == '__main__':
mybottle = MyBottle()
mybottle.run(host='localhost', port=8080, quiet=True, debug=True)