Skip to content

Commit

Permalink
Update Partners API and fix errors
Browse files Browse the repository at this point in the history
- Get all partners
- Get partner by ID
- Create partner
  • Loading branch information
DMalone87 committed Sep 29, 2024
1 parent 300f1d4 commit ae64220
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 30 deletions.
54 changes: 24 additions & 30 deletions backend/routes/partners.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from backend.auth.jwt import min_role_required
from backend.mixpanel.mix import track_to_mp
from backend.database.models.user import User, UserRole
from ..schemas import validate_request, paginate_results, ordered_jsonify
from .tmp.pydantic.partners import CreatePartner
from flask import Blueprint, abort, current_app, request, jsonify
from flask_jwt_extended import get_jwt
from flask_jwt_extended.view_decorators import jwt_required
from flask_sqlalchemy import Pagination
from sqlalchemy.orm import joinedload

from ..database import (
Expand All @@ -25,7 +26,7 @@
bp = Blueprint("partner_routes", __name__, url_prefix="/api/v1/partners")


@bp.route("/<int:partner_id>", methods=["GET"])
@bp.route("/<partner_id>", methods=["GET"])
@jwt_required()
@min_role_required(UserRole.PUBLIC)
# @validate()
Expand All @@ -37,15 +38,17 @@ def get_partners(partner_id: str):
return p.to_json()


@bp.route("/create", methods=["POST"])
@bp.route("/", methods=["POST"])
@jwt_required()
@min_role_required(UserRole.PUBLIC)
# @validate(json=CreatePartnerSchema)
@validate_request(CreatePartner)
def create_partner():
logger = logging.getLogger("create_partner")
"""Create a contributing partner."""
logger = logging.getLogger("create_partner")
body: CreatePartner = request.validated_body
jwt_decoded = get_jwt()
current_user = User.get(jwt_decoded["sub"])

body = request.context.json
if (
body.name is not None
and body.url is not None
Expand All @@ -54,26 +57,25 @@ def create_partner():
and body.url != ""
and body.contact_email != ""
):

# Creates a new instance of the Partner and saves it to the DB
try:
# Creates a new instance of the Partner and saves it to the DB
new_p = Partner.from_dict(body)
except Exception:
abort(400)
"""
add to database if all fields are present
and instance not already in db.
"""
new_p = Partner.from_dict(body.dict())
except Exception as e:
abort(
400,
description=f"Failed to create partner: {e}")
# Connects the current user to the new partner as an admin
new_p.members.connect(
# Return the User object for the currently logged in user
User.get(uid=get_jwt()["sub"]),
current_user,
{
"role": MemberRole.ADMIN
"role": MemberRole.ADMIN.value
}
)
# update to UserRole contributor status
user_id = get_jwt()["sub"]
user = User.nodes.get(uid=user_id)
user.role = UserRole.CONTRIBUTOR
current_user.role = UserRole.CONTRIBUTOR.value
current_user.save()
logger.info(f"User {current_user.uid} created partner {new_p.name}")

track_to_mp(request, "create_partner", {
"partner_name": new_p.name,
Expand All @@ -91,7 +93,6 @@ def create_partner():
@bp.route("/", methods=["GET"])
@jwt_required()
@min_role_required(UserRole.PUBLIC)
# @validate()
def get_all_partners():
"""Get all partners.
Accepts Query Parameters for pagination:
Expand All @@ -103,16 +104,9 @@ def get_all_partners():
q_per_page = args.get("per_page", 20, type=int)

all_partners = Partner.nodes.all()
results = all_partners.paginate(
page=q_page, per_page=q_per_page, max_per_page=100
)
results = paginate_results(all_partners, q_page, q_per_page)

return {
"results": [partner.to_json() for partner in results.items],
"page": results.page,
"totalPages": results.pages,
"totalResults": results.total,
}
return ordered_jsonify(results), 200


@bp.route("/<int:partner_id>/members/", methods=["GET"])
Expand Down
8 changes: 8 additions & 0 deletions backend/routes/tmp/pydantic/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from pydantic import BaseModel, Field
from typing import List, Optional, Dict, Any, Union


class PaginatedResponse(BaseModel):
page: Optional[int] = Field(None, description="The current page number.")
per_page: Optional[int] = Field(None, description="The number of items per page.")
total: Optional[int] = Field(None, description="The total number of items.")
61 changes: 61 additions & 0 deletions backend/routes/tmp/pydantic/partners.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from pydantic import BaseModel, Field
from typing import List, Optional, Dict, Any, Union
from .common import PaginatedResponse


class BasePartner(BaseModel):
name: Optional[str] = Field(None, description="Name of the partner organization.")
url: Optional[str] = Field(None, description="Website URL of the partner.")
contact_email: Optional[str] = Field(None, description="Contact email for the partner organization.")


class CreatePartner(BasePartner, BaseModel):
name: Optional[str] = Field(None, description="Name of the partner organization.")
url: Optional[str] = Field(None, description="Website URL of the partner.")
contact_email: Optional[str] = Field(None, description="Contact email for the partner organization.")


class UpdatePartner(BasePartner, BaseModel):
name: Optional[str] = Field(None, description="Name of the partner organization.")
url: Optional[str] = Field(None, description="Website URL of the partner.")
contact_email: Optional[str] = Field(None, description="Contact email for the partner organization.")


class Partner(BasePartner, BaseModel):
name: Optional[str] = Field(None, description="Name of the partner organization.")
url: Optional[str] = Field(None, description="Website URL of the partner.")
contact_email: Optional[str] = Field(None, description="Contact email for the partner organization.")
uid: Optional[str] = Field(None, description="Unique identifier for the partner.")
members: Optional[str] = Field(None, description="Url to get all members of the partner.")
reported_incidents: Optional[str] = Field(None, description="Url to get all incidents reported by the partner.")


class PartnerList(PaginatedResponse, BaseModel):
results: Optional[List[Partner]] = None


class MemberBase(BaseModel):
partner_uid: Optional[str] = Field(None, description="Unique identifier for the partner.")
user_uid: Optional[str] = Field(None, description="Unique identifier for the user.")
role: Optional[str] = Field(None, description="Role of the user.")
is_active: Optional[bool] = Field(None, description="Whether the user is active.")


class Member(MemberBase, BaseModel):
partner_uid: Optional[str] = Field(None, description="Unique identifier for the partner.")
user_uid: Optional[str] = Field(None, description="Unique identifier for the user.")
role: Optional[str] = Field(None, description="Role of the user.")
is_active: Optional[bool] = Field(None, description="Whether the user is active.")
uid: Optional[str] = Field(None, description="Unique identifier for the user.")
date_joined: Optional[str] = Field(None, description="Date the user joined the partner organizaation.")


class AddMember(MemberBase, BaseModel):
partner_uid: Optional[str] = Field(None, description="Unique identifier for the partner.")
user_uid: Optional[str] = Field(None, description="Unique identifier for the user.")
role: Optional[str] = Field(None, description="Role of the user.")
is_active: Optional[bool] = Field(None, description="Whether the user is active.")


class MemberList(PaginatedResponse, BaseModel):
results: Optional[List[Member]] = None

0 comments on commit ae64220

Please sign in to comment.