I am creating an API for a version control system. This is my first time creating an API (and a web project in general) and I wanted to get some feedback. I plan to connect this API to a frontend to create website. I choose to share this part of the code because the rest of the code follows this structure. For reference: Users have repositories ; repositories have commits, files and branches; branches point to a specific commit; commits and files have a many to many relationship.
router = APIRouter(prefix= "/{user_name}", tags=["repository"])
@router.post("/", response_model= schemas.RepositoryResponseSchema ,status_code=status.HTTP_201_CREATED)
def create_repo(user_name: str, repo_name : str,
db: Session = Depends(database.get_db), current_user = Depends(oauth2.get_current_user)):
if current_user.name != user_name:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="User does not have permission to create a repository for another user")
user = crud.get_one_or_error(db, models.User, name= user_name)
repo = crud.create_unique_or_error(db, models.Repository, name= repo_name, creator= user)
master_branch = crud.create_unique_or_error(db, models.Branch, name= "master", head_commit_oid = None, repository_id= repo.id)
repo.branches.append(master_branch)
repo.current_branch_id = master_branch.id
db.commit()
return repo
@router.put("/{repository_name}/change-branch", response_model=schemas.ChangeBranchResponse, status_code=status.HTTP_200_OK)
def change_branch(user_name: str, repository_name: str, branch_name: str,
db: Session = Depends(database.get_db), current_user = Depends(oauth2.get_current_user)):
if current_user.name != user_name:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="User does not have permission to change a branch for another user")
user = crud.get_one_or_error(db, models.User, name= user_name)
repo = crud.get_one_or_error(db, models.Repository, name= repository_name, creator= user)
branch = crud.get_one_or_error(db, models.Branch, name= branch_name, repository_id= repo.id)
repo.current_branch = branch
db.commit()
return schemas.ChangeBranchResponse(repo.name, branch_name=branch.name)
@router.get("/{repository_name}/tree", status_code=status.HTTP_200_OK)
def get_tree_for_repo(user_name: str, repository_name: str, db: Session = Depends(database.get_db)):
"""Return the graph formed by commits and branches
o → o → o → o → o → o
↓ ↑
o ← dev_branch master_branch
"""
user = crud.get_one_or_error(db, models.User, name= user_name)
repo = crud.get_one_or_error(db, models.Repository, name= repository_name, creator_id= user.id)
# Create an empty directed graph
graph = nx.DiGraph()
for branch in repo.branches:
head = branch.head_commit_oid
commit = crud.get_one_or_error(db, models.Commit, oid=head, repository_id= repo.id)
while commit:
graph.add_node(commit.oid, label=f"Commit: {commit.commit_message}")
if commit.parent_oid:
graph.add_edge(commit.parent_oid, commit.oid)
else:
root = commit.oid # Returnning this could be good for drawing better graphs
commit = crud.get_one_or_none(db, models.Commit, oid=commit.parent_oid, repository_id= repo.id)
return json_graph.node_link_data(graph)
I am unsure with some of my design choices and I am looking for some feedback.
crud? \$\endgroup\$