Python3 <sqlite3.Row object at 0x10fcbb4b0> is not JSON serializable - python-3.x

Python3.7
I have the following GET endpoint to return the data in the database, but keeps getting
{
"code": 400,
"message": "Exception in _query: <sqlite3.Row object at 0x10fcbb4b0> is not JSON serializable"
}
Here is the code. I have been trying many different solutions but none of them works. Any thoughts?
Any way I can printout the sqlite3 data? When I do
print(entries)
I will return
as well. Any thoughts? Thank you!
# all the imports
import os
import sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash
from .response import Response
app = Flask(__name__) # create the application instance :)
app.config.from_object(__name__) # load config from this file , flaskr.py
import json
import requests
#app.route('/table_result', methods=['GET'])
def table_result():
try:
db = get_db()
cur = db.execute("SELECT name FROM mouse_tracking; ")
entries = cur.fetchall()
# return Response(200, json.dumps(entries)).payload()
return json.dumps(entries)
except sqlite3.Error as e:
return Response(400, "Database error: %s" % e).payload()
except Exception as e:
return Response(400, "Exception in _query: %s" % e).payload()

(i cant comment yet) did you use cursor?
def table():
try:
db = sqlite3.connect('db.db')
cursor = db.cursor()
cursor.execute("SELECT name FROM db")
entries = cursor.fetchall()
return jsonify(json.dumps(entries))
except Exception as e:
return Response(400, "Exception: %s" % e).payload()
you should use db.cursor() to execute commands on the database

Related

Dictionary returned in Flask displays empty curly braces

I'm trying to make a flask pipeline which receives data from a python file and sends the data to react which display them.
I currently am stuck trying to receive the data in flask after sending them via post to the URL: localhost:5000/weather-data
The data is being posted with this Code:
dummy_data = {'data': str(msg.payload.decode('iso-8859-1')),
'timestamp': datetime.datetime.now().isoformat()}
response = requests.post(url, data=dummy_data)
print(response.text)
The print result is:
{"data": "{\"region\": \"Jokkmokk\", \"temp_now\": 8.91, \"weather_now\": \"bewölkt\", \"humidity\": 50, \"wind\": 24}",
"timestamp": "2021-02-24T17:23:15.347058"}
Which is all right but then i try to receive the data and return it on the flask side with this code:
from flask import Flask, request
app = Flask(__name__)
#app.route('/')
def test():
return 'HelloWorld'
#app.route('/weather-data', methods=['POST', 'GET'])
def weather_data():
try:
data = request.form.to_dict()
print(data)
return data
except Exception as e:
print(e)
if __name__ == '__main__':
app.run(host='127.0.0.1', debug=True, port=5000)
This runs normally through and my print(data) gives the exact same dictionary back but if i take a look at localhost:5000/weather-data i only see empty curly braces {}
As a Test i tried to return the data without receivng them first with this code:
#app.route('/weather-data', methods=['POST', 'GET'])
def weather_data():
return {"data": "{\"region\": \"Fishermans City\", \"temp_now\": 6.87, \"weather_now\": \"st\\u00fcrmisch\", "humidity\": 52, \"wind\": 58}",
"timestamp": "2021-02-23T18:32:49.120861"}
Like this it perfectly worked and showed the Data on the website.
Edit:
I think this is a stupid question for some of you but because i am kinda new to this i wanted to ask if it is possible that the Data is on the Page but when i reload the Page it overwrites the data with empty curly braces?
If yes is there a way that i can keep them on the Page until i make another Post with new data?
You need to use jsonify
from flask import Flask, request
from flask import jsonify
app = Flask(__name__)
data = dict()
#app.route('/')
def test():
return 'HelloWorld'
#app.route('/weather-data', methods=['POST', 'GET'])
def weather_data():
if request.method == 'POST':
global data
data = request.form.to_dict()
return jsonify(data), 200
else:
return jsonify(data), 200
if __name__ == '__main__':
app.run(host='127.0.0.1', debug=True, port=5000)
Have you tried using json?
response = requests.post(url, json=dummy_data)
and
data = request.json

I am having error invalid syntax in my python code

I am trying to add multiple inner function in my code. But I am not able to add it properly and also it is giving me a syntax error. Here I am trying to run my python script when I click a button and it will take input from a textfield and then run my script which has multiple functions. Is this the right way to add inner functions or is there another way to do this?
ERROR
File "server.py", line 17``
pass = request.form['typed']here
^
SyntaxError: invalid syntax
[1]: https://i.stack.imgur.com/H6Mg2.png
from flask import Flask, render_template, url_for, request, redirect
app= Flask(__name__)
#app.route('/')`enter code here`
def my_home():
return render_template('index.html')
#app.route('/<string:page_name>')
def html_page(page_name):
return render_template(page_name)
import hashlib
import sys
import requests
#app.route('/send',methods =['POST'])
def send():
if request.method == 'POST':
pass = request.form['typed']
def request_api_data(query_char)
res = requests.get(url)
if res.status_code != 200:
raise RuntimeError(f'Error fetching: {res.status_code}, check the api and try again')
return res
pass is a statement and cannot be used as a variable name.
https://docs.python.org/3/tutorial/controlflow.html#pass-statements
from flask import Flask, render_template, url_for, request, redirect
app= Flask(__name__)
#app.route('/')`enter code here`
def my_home():
return render_template('index.html')
#app.route('/<string:page_name>')
def html_page(page_name):
return render_template(page_name)
import hashlib
import sys
import requests
#app.route('/send',methods =['POST'])
def send():
if request.method == 'POST':
# pass = request.form['typed']
my_pass = request.form['typed'] # <- this should work.
def request_api_data(query_char)
res = requests.get(url)
if res.status_code != 200:
raise RuntimeError(f'Error fetching: {res.status_code}, check the api and try again')
return res

Custom exceptions in python starlette

I am trying to raise the custom exception using the starlette framework in python. I have the API call which checks some condtions depends on the result, it should raise exception.
I have two files app.py and error.py
#app.py
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
from error import EmptyParamError
async def homepage(request):
a=1
b=0
if a == 1:
raise EmptyParamError(400, "status_code")
return JSONResponse({'hello': 'world'})
routes = [
Route("/", endpoint=homepage)
]
app = Starlette(routes=routes,debug=True)`
#error.py ```
from starlette.responses import JSONResponse
class BaseError(Exception):
def __init__(self, status_code: int, detail: str = None) -> None:
if detail is None:
detail = "http.HTTPStatus(status_code).phrase"
self.status_code = status_code
self.detail = detail
async def not_found(self):
return JSONResponse(content=self.title, status_code=self.status_code)
class EmptyParamError(BaseError):
""" Error is raised when group name is not provided. """
status_code = 400
title = "Missing Group Name"
When the condition is true, i want to raise the exception but its not returning the jsonrespnse but its returning the stacktrace on the console.
Please let me know if anything is wrong here
adding try block resolved the issue
try:
if a==1:
raise InvalidUsage(100,"invalid this one")
if b == 0:
raise EmptyParamError("this is empty paramuvi")
except InvalidUsage as e:
return JSONResponse({'hello': str(e.message)})
except EmptyParamError as e:
return JSONResponse({'hello': str(e.message)})

Mock exception raised in function using Pytest

I have the following function and it is a generic function which will make API call based on the input hostname and data. It will construct http request to make API and will return the response. This function will throw four types of exception(invalid URL, timeout, auth error and status check). How can I Mcok and Test the exception raised in API call using pytest? Which will be the best method to test the exceptions raised from API call?
import ssl
import urllib
import urllib.request
import urllib.error
import xml
import xml.etree.ElementTree as ET
def call_api(hostname, data):
'''Function to make API call
'''
# Todo:
# Context to separate function?
# check response for status codes and return reponse.read() if success
# Else throw exception and catch it in calling function
error_codes = {
"1": "Unknown command",
"6": "Bad Xpath",
"7": "Object not present",
"8": "Object not unique"
}
url = "http://" + hostname + "/api"
encoded_data = urllib.parse.urlencode(data).encode('utf-8')
try:
response = urllib.request.urlopen(url, data=encoded_data,
timeout=10).read()
root = ET.fromstring(response)
if root.attrib.get('status') != "success":
Errorcode = root.attrib.get('code')
raise Exception(pan_error_codes.get(Errorcode, "UnknownError"),
response)
else:
return response
except urllib.error.HTTPError as e:
raise Exception(f"HttpError: {e.code} {e.reason} at {e.url}", None)
except urllib.error.URLError as e:
raise Exception(f"Urlerror: {e.reason}", None)
If i call this function
def create_key(hostname, username, password):
hostname = 'myhost ip'
data = {
'type': 'keygen',
'username': username,
'password': password
}
username = 'myuser'
password = 'password'
response = call_api(hostname, data)
return response
i will get a response like following
b"<response status = 'success'><result><key>mykey</key></result></response>"
You can mock error raising via side_effect parameter:
Alternatively side_effect can be an exception class or instance. In this case the exception will be raised when the mock is called.
In your case, this can be used like this (assuming call_api is defined in module foo):
import pytest
from unittest.mock import patch
def test_api():
with patch('foo.call_api', side_effect=Exception('mocked error')):
with pytest.raises(Exception) as excinfo:
create_key('localhost:8080', 'spam', 'eggs')
assert excinfo.value.message == 'mocked error'

How to capture API failure while using oauthlib.oauth2 fetch_token

The Python3 fetch_token method in this library does not check the response status before consuming the response. If the API call it makes fails, then the response will be invalid and the script crashes. Is there something I can set so that an exception will be raised on a non-success response before the library can read the response?
import requests
from requests.auth import HTTPBasicAuth
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import BackendApplicationClient
from oauthlib.oauth2 import OAuth2Error
AUTH_TOKEN_URL = "https://httpstat.us/500" # For testing
AUTH = HTTPBasicAuth("anID", "aSecret")
CLIENT = BackendApplicationClient(client_id="anID")
SCOPES = "retailer.orders.write"
MAX_API_RETRIES = 4
class MyApp:
def __init__(self):
"""Initialize ... and obtain initial auth token for request"""
self.client = OAuth2Session(client=CLIENT)
self.client.headers.update(
{
"Content-Type": "application/json"
}
)
self.__authenticate()
def __authenticate(self):
"""Obtain auth token."""
server_errors = 0
# This needs more work. fetch_token is not raising errors but failing
# instead.
while True:
try:
self.token = self.client.fetch_token(
token_url=AUTH_TOKEN_URL, auth=AUTH, scope=SCOPES
)
break
except (OAuth2Error, requests.exceptions.RequestException) as e:
server_errors = MyApp.__process_retry(
server_errors, e, None, MAX_API_RETRIES
)
#staticmethod
def __process_retry(errors, exception, resp, max_retries):
# Log and process retries
# ...
return errors + 1
MyApp() # Try it out
You can add a "compliance hook" that will be passed the Response object from requests before the library attempts to parse it, like so:
def raise_on_error(response):
response.raise_for_status()
return response
self.client.register_compliance_hook('access_token_response', raise_on_error)
Depending on exactly when you may get errors, you might want to do this with 'refresh_token_response' and/or 'protected_request' as well. See the docstring for the register_compliance_hook method for more info.

Resources