I have a FastAPI application running on my local machine under the URL: http://localhost:8000
, using the following Python code:
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"*"
'''
"http://localhost:8000/add_points/",
"http://localhost:8000/check_points/",
"http://localhost:8000/check_item_points/",
"http://localhost:8000/redeem_points/"
'''
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
users = {"matt": 0}
items = {"ticket": 7}
class User(BaseModel):
name: str
points: float
item: str
class AddTransaction(BaseModel):
name: str
points: float
class UserPoints(BaseModel): # anything that extnds this base model is a pyantic model
name: str
points: float
class Item(BaseModel):
name: str
points: float
# -----Post Requests-----
@app.post("/add_points/")
def add_points(add_transaction: AddTransaction):
global users
user_id = add_transaction.name
points = add_transaction.points
users[user_id] = users.get(user_id, 0) + points
return users[user_id]
@app.post("/check_points/")
def check_points(user_points: UserPoints):
global users
user_id = user_points.name
points = user_points.points
return users[user_id], points
@app.post("/check_item_points/")
def check_item_points(item: Item):
global items
item_id = item.name
points = item.points
return item[item_id], points
@app.post("/redeem_points/") # user spends points (they lose points) gain an item
def redeem_points(add_transaction: AddTransaction, user_points: UserPoints, item: Item, user: User):
global users
global items
user_id = add_transaction.name
user_points = user_points.points
item_points = item.points
item_pre = item.name
item_post = user.item
if user_points >= item_points:
user_points == user_points - item_points
item_post == item_pre
return users[user_id], users[user_points], users[item_post]
else:
return "insufficient funds"
# -----Get Requests-----
@app.get("/")
def read_root():
return {"Hello": "World"}
# -----Put Requests-----
""""
@app.put("/items/{item_id}")
def update_item(item_id: int, item:Item):
return {"item_name": item.name, "item_id": item_id}
"""
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
I also have an HTML file with JS script inside that simply sends a POST
request to http://localhost:8000/add_points/
upon the click of a button. Here is the code for that:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<body>
<br><br><br><span style="text-align: center;"><button id="send">Send Request</button></span>
</body>
<script>
$("#send").on("click", evt => {
$.post("http://localhost:8000/add_points/",
{
name: "string",
points: 5.0
},
function(data, status){
alert("Data: " + data + "\nStatus: " + status);
});
});
</script>
</html>
However, when I try to send the POST
request I get the following errors in PyCharm:
INFO: 127.0.0.1:49413 - "OPTIONS /add_points/ HTTP/1.1" 400 Bad Request
INFO: 127.0.0.1:49413 - "POST /add_points/ HTTP/1.1" 422 Unprocessable Entity
I understand that at least one of these errors originates from the CORS policy restrictions, however, this project is aimed towards mobile phone users who should not have to install any browser extensions for overriding the policy. Any advice as to how to fix these errors would be greatly appreciated!
EDIT UPDATE:
const url = new URL('localhost:8000/add_points/');
$("#send").on("click", evt => { fetch(url,
{
method: 'POST',
headers: {'Accept': 'application/json', 'Content-Type': 'application/json'},
body: JSON.stringify({"name":"John", "points":50.0})
}).then().catch((error) => { console.log(error.message); }); });
I'm still getting a 400 Bad Request
error.