1

Very new to FastAPI and I'm stumped. I am attempting to register a new user through my api but am receiving this error from my request:

{
    "detail": [
        {
            "loc": [
                "body",
                "id"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "username"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "password"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "email"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "phone_number"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}

I am not sure what I am doing wrong or if its a frontend or backend issue. I assume there's something wrong with how I am trying to receive this request with my pydantic model because I can't seem to see an issue on the frontend. My post method on the frontend looks like:

api.js

import axios from 'axios';

const api = axios.create({
    withCredentials: true,
    baseURL: 'http://localhost:8000'
});

api.interceptors.request.use((config) => {
    config.headers = {
        Accept: 'application/json',
        ContentType: "application/json"
    };

    return config;
});

api.interceptors.response.use(
    (response) => response,
    (error) => {
        return Promise.reject(error);
    },
);

export default api;

and my service on the frontend looks like:

function register(user) {
    return api.post('auth/register', user, { withCredentials: true, 'Access-Control-Allow-Origin': '*' })
        .then((response) => response)
        .catch((error) => Promise.reject(error));
}

and then my actual method call:

const handleRegistration = () => {
        setLoading(true);

        let new_user = {
            username: inputs.username,
            password: inputs.password,
            email: inputs.password,
            phone_number: inputs.phone
        }

        AuthService.register(new_user).then(() => {
                setLoading(false);
                navigation.navigate('LoginScreen');
                toast('success', 'Successfully created new account', null);
            },
            (e) => {
                setLoading(false);
                console.log(e.toString());
                toast('error', 'Error creating new account', null);
            })
    }

and last my python user BaseModel and api call look like:

user.py

from pydantic import BaseModel, Field
from .document import DocumentBase


class UserBase(BaseModel):
    id: int
    username: str
    password: str
    email: str
    phone_number: str
    documents: list[DocumentBase] = []

    class Config:
        arbitrary_types_allowed = True
        orm_mode = True

auth.py

@router.post("/register")
def register(data: UserBase, _db: Session = Depends(get_db)):
    # querying database to check if user already exist
    user = _db.query(User).filter(User.email == data.email).first()
    if user is not None:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="User with this email already exist"
        )
    new_user = User()
    new_user.username = data.username
    new_user.password = get_hashed_password(data.password)
    new_user.email = data.email
    new_user.phone_number = data.phone_number

    _db.add(new_user)
    _db.commit()
    return new_user

Any insight to this issue would be greatly appreciated

1

1 Answer 1

1
  • The API accepts data of the from BaseUser, so it expects all the fields that you're declaring there, unless they have a default value. If you don't pass the id field in your request, it will never work
  • Have you checked that the register method actually sends data in the JSON format?

The solution to the first point is to create two models: one for data input, the other for returning data, so that the user cannot set/change internal values. In this case, one may play with the inheritance of models, something like

class userBase(BaseModel):
    # shared fields

class UserInput(userBase):
    # fields dedicated to the input of a user

class UserOutput(userBase):
    # fields dedicated to the output of a user
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.