Message!
This is an old work, for updated version please visit Updated FastAPI Course
Now, we have a record in the user table so we have the owner_id field for creating a new job. Let's create a new job using a post request. It would be very similar to the previous post, Wanna give it a try? Feel free to try it on your own.
We need 3 new files:
backend/
├─.env
├─apis/
│ ├─base.py
│ └─version1/
│ ├─route_general_pages.py
│ ├─route_jobs.py #new
│ └─route_users.py
├─db/
│ ├─base.py
│ ├─base_class.py
│ ├─models/
│ │ ├─jobs.py
│ │ └─users.py
│ ├─repository/
│ │ ├─jobs.py #new
│ │ └─users.py
│ └─session.py
├─main.py
├─schemas/
│ ├─jobs.py
│ └─users.py
├─tests/
│ ├─conftest.py
│ └─test_routes/
│ ├─test_jobs.py #new
│ └─test_users.py
└─test_db.db
Type the following code in route_jobs.py:
from fastapi import APIRouter
from sqlalchemy.orm import Session
from fastapi import Depends,HTTPException,status
from db.session import get_db
from db.models.jobs import Job
from schemas.jobs import JobCreate,ShowJob
from db.repository.jobs import create_new_job
router = APIRouter()
@router.post("/create-job/",response_model=ShowJob)
def create_job(job: JobCreate,db: Session = Depends(get_db)):
current_user = 1
job = create_new_job(job=job,db=db,owner_id=current_user)
return job
We are doing the same thing, we are creating a route that will receive data for job creation by POST method. It will validate the data received used a schema named JobCreate. So, let's create the schemas required. Type the following in schemas > jobs.py.
from typing import Optional
from pydantic import BaseModel
from datetime import date,datetime
#shared properties
class JobBase(BaseModel):
title : Optional[str] = None
company : Optional[str] = None
company_url : Optional[str] = None
location : Optional[str] = "Remote"
description : Optional[str] = None
date_posted : Optional[date] = datetime.now().date()
#this will be used to validate data while creating a Job
class JobCreate(JobBase):
title : str
company : str
location : str
description : str
#this will be used to format the response to not to have id,owner_id etc
class ShowJob(JobBase):
title : str
company: str
company_url : Optional[str]
location : str
date_posted : date
description : Optional[str]
class Config(): #to convert non dict obj to json
orm_mode = True
Since we are using repository pattern and we want to keep the database orm logic completely separated from that of fastapi routes we need to create a make a new function named 'create_new_job' for creation logic. Lets create this file db > repository > jobs.py
from sqlalchemy.orm import Session
from schemas.jobs import JobCreate
from db.models.jobs import Job
def create_new_job(job: JobCreate,db: Session,owner_id:int):
job_object = Job(**job.dict(),owner_id=owner_id)
db.add(job_object)
db.commit()
db.refresh(job_object)
return job_object
This is yet another example of sqlalchemy orm. We are creating a new record in the database using orm. Still, our fastapi app does not know about this new feature. So, we need to import create_user route in apis > base.py
from apis.version1 import route_general_pages
from apis.version1 import route_users
from apis.version1 import route_jobs
api_router = APIRouter()
api_router.include_router(route_general_pages.general_pages_router,prefix="",tags=["general_pages"])
api_router.include_router(route_users.router,prefix="/users",tags=["users"])
api_router.include_router(route_users.router,prefix="/users",tags=["users"])
api_router.include_router(route_jobs.router,prefix="/jobs",tags=["jobs"])
Time to test our functionality, By the end of this course I would try to follow real TDD. I would make the test fail and then write sufficient code to make it pass and then the test should pass. For now, we are just documenting our work.
Type this code in tests > test_routes > test_jobs.py
import json
def test_create_job(client):
data = {
"title": "SDE super",
"company": "doogle",
"company_url": "www.doogle.com",
"location": "USA,NY",
"description": "python",
"date_posted": "2022-03-20"
}
response = client.post("/jobs/create-job/",json.dumps(data))
assert response.status_code == 200
assert response.json()["company"] == "doogle"
assert response.json()["description"] == "python"
and now we will run our test by typing pytest in the terminal.
All Done, over and out !
Final git commit : create job using post request · nofoobar/JobBoard-Fastapi@c2e1eb9 (github.com)
Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.
We know, we might make it hard for you but definitely worth the efforts.
© Copyright 2022-23 Team FastAPITutorial