Flask & React JS error 422 (UNPROCESSABLE ENTITY) - reactjs

Trying to read some data from the /profile route of my flask api. I keep getting error 422 unprocessable entity. This is on my Home.tsx file where I am already authenticated and am trying to read some more data from flask.
picture of error
I have no issues getting a response from the api when getting tokens via /tokens. I followed this guide here exactly to connect flask to react and I have no idea why it is not working.
I am pretty comfortable with React but very new to flask to please forgive me. Any help with this would really be appreciated.
It looks like if I get rid of #jwt_required() it does work but my understanding is this should be used.
base.py
api = Flask(__name__)
CORS(api)
api.config["JWT_SECRET_KEY"] = "please-remember-to-change-me"
api.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(hours=1)
jwt = JWTManager(api)
#api.after_request
def refresh_expiring_jwts(response):
try:
exp_timestamp = get_jwt()["exp"]
now = datetime.now(timezone.utc)
target_timestamp = datetime.timestamp(now + timedelta(minutes=30))
if target_timestamp > exp_timestamp:
access_token = create_access_token(identity=get_jwt_identity())
data = response.get_json()
if type(data) is dict:
data["access_token"] = access_token
response.data = json.dumps(data)
return response
except (RuntimeError, KeyError):
# Case where there is not a valid JWT. Just return the original response
return response
#api.route('/token', methods=["POST"])
def create_token():
email = request.json.get("email", None)
password = request.json.get("password", None)
if email != "test" or password != "test":
return {"msg": "Wrong email or password"}, 401
access_token = create_access_token(identity=email)
response = {"access_token":access_token}
return response
#api.route("/logout", methods=["POST"])
def logout():
response = jsonify({"msg": "logout successful"})
unset_jwt_cookies(response)
return response
#api.route("/profile", methods=["GET"])
#jwt_required()
def my_profile():
response_body = {
"name": "Michael",
"about" :"Admin"
}
return response_body
Home.tsx
import { useEffect, useState } from "react";
import { BsPersonFill, BsCalendarFill } from "react-icons/bs";
import { RiTeamFill } from "react-icons/ri";
import { BiLogOut } from "react-icons/bi";
import axios from "axios";
import Navbar from "../components/Navbar";
import Footer from "../components/Footer";
const Home = (props: any) => {
const [profileData, setProfileData] = useState<any>(null);
function getData() {
axios({
method: "GET",
url: "http://127.0.0.1:5000/profile",
headers: {
Authorization: "Bearer " + props.token,
},
})
.then((response) => {
const res = response.data;
res.access_token && props.setToken(res.access_token);
setProfileData({
profile_name: res.name,
about_me: res.about,
});
})
.catch((error) => {
if (error.response) {
console.log(error.response);
console.log(error.response.status);
console.log(error.response.headers);
}
});
}
useEffect(() => {
getData();
}, []);
Tried searching for this on other threads and nothing I tried worked such as messing with authorization header, did not make a difference. It works fine when sending the request with postman.

Related

React app can't find fastapi backend with specified ip and port after hosted in aws ec2 instance

I was trying to run a simple reactjs app with fastapi backend by hosting it on the aws ec2 instance. The react js an fastapi servers are running fine at 3000 and 8000 ports respectively but they are not communicating with each other to fetch any kind of response.
The specified react page that gets some request data from "GET" request at url http://ec2.ipv6.id:3000/predictor. The page runs fine but there is not data and the error is observed in the console as below.
Access to fetch at 'http://localhost:8000/predict'
from origin 'http://my-ec2-instance-public-ipv4:3000' has been blocked by
CORS policy: The request client is not a secure context and
the resource is in more-private address space `local`
The react file is given as below:
import "./predictor.css";
import React, {useEffect, useState, CSSProperties} from "react";
import axios from "axios";
import HashLoader from "react-spinners/HashLoader";
const override: CSSProperties = {
display: "block",
position : "relative",
top: "-100px",
margin: "0 auto",
borderColor: "red",
};
export function Predictor() {
const [cResponse, setcResponse] = useState([]);
const [getPCE, setGetPCE] = useState([]);
// const [getmessage, setgetmessage] = useState([]);
const [loading, setLoading] = useState(false);
let [color, setColor] = useState("red");
let [clicked, setClicked] = useState(false);
const getRes = async () =>{
const requestDict = {
method : "GET",
headers: {
"Content-Type": "application/json",
},
};
const response = await fetch("http://localhost:8000/predict",requestDict);
// http://127.0.0.1:8000/predict
const data = await response.json();
console.log(data);
if(!response.ok) {console.log("response not working properly");}
else{
setcResponse(data);
}
}
const form = document.getElementById("input_form");
const responseF = (e) =>{
e.preventDefault();
setLoading(true);
setClicked(true);
const formData = new FormData(form);
// console.log([...formData]);
axios({
method: "post",
url: "http://localhost:8000/predict",
data: [... formData]
})
.then((data) => {
setGetPCE(data.data);
// setgetmessage(data.message);
setLoading(false);
console.log(data.data);
})
.catch(function (err) {
console.log(err);
})
}
useEffect(() => {
getRes();},[]);
return(
<div id="main_body">.....
The main.py of the fastapi is as below
from fastapi import FastAPI, Form, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.encoders import jsonable_encoder
import joblib
import numpy as np
import os
from own.preprocess import Preprocess
import sklearn
col_data = joblib.load("col_bool_mod.z")
app = FastAPI()
origins = [
"http://127.0.0.1:3000","http://public-ipv4-of-ec2:3000/","http://private-ipv4-of-ec2:3000/"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
#app.get("/predict")
async def test():
return jsonable_encoder(col_data)
#app.post("/predict")
async def provide(data: list):
print(data)
output = main(data)
return output
def predict_main(df):
num_folds = len(os.listdir("./models/"))
result_li = []
for fold in range(num_folds):
print(f"predicting for fold {fold} / {num_folds}")
model = joblib.load(f"./models/tabnet/{fold}_tabnet_reg_adam/{fold}_model.z")
result = model.predict(df)
print(result)
result_li.append(result)
return np.mean(result_li)
def main(data):
df = Preprocess(data)
res = predict_main(df)
print(res)
return {"value": f"{np.float64(res).item():.3f}" if res >=0 else f"{np.float64(0).item()}"}
Just wanted to connect react app with fastapi backend served in same ec2 instance at different port.

Why does my Axios get request fail but works when I use a online REST test tool?

I am trying to do a Axios request but when I do. I get the error "[AxiosError: Request failed with status code 403]" This is strange as when I put that token and api_url into a online REST Get request it works and returns output. This was pulled from my friends Git and for him it works and returns a response and not a error. So I am wondering why Axios isn't working for me.
import { View, Text, Button } from "react-native";
import React, { useState, useEffect } from "react";
import axios from "axios";
import { getSpotifyToken } from "../../hooks/spotifyAuth";
import { setSpotifyToken } from "../../hooks/spotifyAuth";
const getTopArtists = async () => {
//Getting spotify token
const spotifyToken = getSpotifyToken();
console.log("Getting access Token for TopSongs:", spotifyToken);
const api_url =
"https://api.spotify.com/v1/me/top/artists?time_range=medium_term&limit=5";
try {
const response = await axios.get(api_url, {
headers: {
Authorization: `Bearer ${spotifyToken}`,
},
});
console.log(response.data);
return response.data.items;
} catch (error) {
setSpotifyToken("");
console.log(error);
}
};

Getting 400 Bad Request on sending request using axios (ReactJS) even though it works fine on Postman

I'm trying to GET a List of Patients from my BE using FormData with Bearer token. When I test on Postman, it resolves just fine, but when I try to send with axios, I constantly get the 400 Error Bad Request, can anyone know the problem ?? this is where I send request in Postman
Here is my code for React
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useParams, Link, useNavigate } from 'react-router-dom';
import ReactLoading from 'react-loading';
import { useQuery } from 'react-query';
import { API } from '../../../api/GeneralAPI';
import FetchingError from '../../../Authentication/Views/ErrorView/FetchingError';
import SearchPatientUnderGuide from './SearchPatientUnderGuide';
function FetchPatientUnderGuide() {
const {id} = useParams();
console.log(id)
const navigate = useNavigate();
const url = API + "getAllPatientsOfDoctor"
const token = localStorage.getItem('token');
const fetchPatients = async () => {
let formData = new FormData();
formData.append('id', id)
console.log("ID is: " + formData.get('id'));
console.log(`Bearer ${token}`)
const fetchData = await axios({
method: 'get',
url: url,
headers: {
Authorization: `Bearer ${token}`
},
data : formData})
return fetchData;
}
const query = useQuery('patients', fetchPatients)
return (
<div>
{query.isLoading
? <ReactLoading type="spin" color="#0000FF"
height={100} width={50}/>
: query.isError
? <FetchingError />
: query.data
? <div>
<SearchPatientUnderGuide details = {query.data.data.object} />
</div>
: null}
</div>
);
}
export default FetchPatientUnderGuide
This is the result I get when sending by React
I code my React code based on this on Postman

Fetch the image and display it with Authorization in react

I'm going to fetch an image from ASP.NET core 5 web API and display it in react (with Authorization)
But I get the following error
Error image
when I remove Authorize and open the photo in the browser, the photo is displayed correctly
This is my code in react :
import axios from "axios";
import React, { useEffect, useState } from "react";
import { Buffer } from "buffer";
const Test = () => {
const [source, setSource] = useState();
useEffect(async () => {
const API_URL =
process.env.REACT_APP_URL +
"/Images/testimg/94e51231-cab8-4c51-8ee5-15b0da3164a4.jpg";
const token = JSON.parse(localStorage.getItem("user")).token;
try {
const response = await axios.get(API_URL, {
headers: {
responseType: "arraybuffer",
Authorization: `Bearer ${token}`,
},
});
if (response) {
console.log(response);
var buffer = Buffer.from(response.data,"base64")
setSource(buffer);
}
} catch (error) {
console.log(error);
}
}, []);
console.log(source);
return (
<img
id="test-img"
src={`data:image/jpeg;charset=utf-8;base64,${source}`}
/>
);
};
export default Test;
And This is my code in ASP.NET core 5 web API:
[Route("testimg/{name}")]
[HttpGet]
[Authorize]
public IActionResult testimg(string name)
{
string curentPath = Directory.GetCurrentDirectory();
string fullPath = Path.Combine(curentPath, $"resources\\{name}");
var image = System.IO.File.OpenRead(fullPath);
return File(image, "image/jpeg");
}

How to do Basic Auth with Axios in react

React Code
import React, { useState, useEffect } from "react";
import axios from "axios";
const Table = () => {
useEffect(() => {
console.log("helllllllllllllllo");
callAPI();
}, []);
const callAPI = async () => {
const url = "some URL";
const password = "Secret" ;
const username = "Consumer Key";
const data = await axios.get(
url,
{},
{
auth: {
username: username,
password: password,
},
}
);
console.log("data", data);
};
return (
<div> Hello </div>
);
};
export default Table;
On Postman, I go to the Authorization Tab and input the Username and password in their respective input fields and get the result but with axios, I getting 401 error.
Exact Error being :-
createError.js:16 Uncaught (in promise) Error: Request failed with status code 401
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:62)
You are incorrectly passing the auth headers. In axios GET, first parameter is URL and second parameter is config object. In config object, you can provide auth property for sending basic auth headers.
const data = await axios.get(url, {
auth: {
username: username,
password: password,
},
})

Resources