diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 5e4486a10..cc736f753 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -31,8 +31,8 @@ jobs: sudo apt-get install python3-dev libpq-dev python -m pip install --upgrade pip python -m pip install -r requirements/dev_unix.txt - # - name: Check style - # run: flake8 backend/ + - name: Check style + run: flake8 backend/ - name: Run tests run: python -m pytest env: diff --git a/backend/api.py b/backend/api.py index 99b3919f5..d0331edc4 100644 --- a/backend/api.py +++ b/backend/api.py @@ -4,9 +4,7 @@ from flask import Flask from flask_mail import Mail from flask_cors import CORS -from flask_jwt_extended import JWTManager from backend.config import get_config_from_env -from backend.database import db_cli from backend.auth import jwt, refresh_token from backend.schemas import spec from backend.routes.partners import bp as partners_bp @@ -88,7 +86,6 @@ def register_commands(app: Flask): # Neomodel commands @app.cli.command("neoload") - @app.cli.command( "seed", context_settings=dict( diff --git a/backend/database/core.py b/backend/database/core.py index 018aaddf9..e108d1c5a 100644 --- a/backend/database/core.py +++ b/backend/database/core.py @@ -5,9 +5,7 @@ from `backend.database`. """ import os -import json -from typing import Any, Optional, TypeVar, Type, List -from enum import Enum +from typing import Optional import click import pandas as pd @@ -17,7 +15,6 @@ from neomodel import install_all_labels from neo4j import Driver -from ..config import TestingConfig from ..utils import dev_only diff --git a/backend/database/models/officer.py b/backend/database/models/officer.py index e7e87bd2f..0a5f92d2e 100644 --- a/backend/database/models/officer.py +++ b/backend/database/models/officer.py @@ -27,7 +27,7 @@ def __repr__(self): class Officer(StructuredNode, JsonSerializable): __property_order__ = [ "uid", "first_name", "middle_name", - "last_name", "suffix", "ethnicity", + "last_name", "suffix", "ethnicity", "gender", "date_of_birth" ] diff --git a/backend/database/models/user.py b/backend/database/models/user.py index 9f2cf2838..ce5adf3ec 100644 --- a/backend/database/models/user.py +++ b/backend/database/models/user.py @@ -1,6 +1,5 @@ """Define the SQL classes for Users.""" -import bcrypt from werkzeug.security import generate_password_hash, check_password_hash from backend.schemas import JsonSerializable, PropertyEnum from neomodel import ( @@ -120,7 +119,6 @@ def hash_password(cls, pw: str) -> str: Returns: str: The hashed password. """ - # return bcrypt.hashpw(pw.encode("utf8"), bcrypt.gensalt()).decode("utf8") return generate_password_hash(pw) @classmethod diff --git a/backend/routes/agencies.py b/backend/routes/agencies.py index 7f1d4941a..cd076edd8 100644 --- a/backend/routes/agencies.py +++ b/backend/routes/agencies.py @@ -1,6 +1,5 @@ import logging -from operator import and_ from typing import Optional, List from backend.auth.jwt import min_role_required from backend.schemas import ( @@ -71,7 +70,7 @@ def create_agency(): def get_agency(agency_id: str): """Get an agency profile. """ - logger = logging.getLogger("get_agency") + # logger = logging.getLogger("get_agency") agency = Agency.nodes.get_or_none(uid=agency_id) if agency is None: abort(404, description="Agency not found") @@ -89,7 +88,7 @@ def get_agency(agency_id: str): def update_agency(agency_uid: str): """Update an agency profile. """ - logger = logging.getLogger("update_agency") + # logger = logging.getLogger("update_agency") body: UpdateAgency = request.validated_body agency = Agency.nodes.get_or_none(uid=agency_uid) if agency is None: @@ -194,7 +193,8 @@ def get_all_agencies(): # ) # if employments is not None: # # If the officer already has a records for this agency, -# # we need to update the earliest and latest employment dates +# # we need to update the earliest and +# # latest employment dates # employment = employment_to_orm(record) # employment.agency_id = agency_id # employment = merge_employment_records( diff --git a/backend/routes/healthcheck.py b/backend/routes/healthcheck.py index 1b458db98..25c836c16 100644 --- a/backend/routes/healthcheck.py +++ b/backend/routes/healthcheck.py @@ -1,6 +1,5 @@ from flask import Blueprint from pydantic import BaseModel -from spectree import Response from ..schemas import spec diff --git a/backend/routes/officers.py b/backend/routes/officers.py index 69ff90611..9d53ddba3 100644 --- a/backend/routes/officers.py +++ b/backend/routes/officers.py @@ -1,13 +1,10 @@ import logging -from operator import or_, and_ from typing import Optional, List from backend.auth.jwt import min_role_required from backend.mixpanel.mix import track_to_mp -from mixpanel import MixpanelException from backend.schemas import validate_request, ordered_jsonify, paginate_results from backend.database.models.user import UserRole, User -from backend.database.models.agency import Agency from backend.database.models.officer import Officer from .tmp.pydantic.officers import CreateOfficer, UpdateOfficer from flask import Blueprint, abort, request @@ -212,7 +209,7 @@ def update_officer(officer_uid: str): request, "update_officer", { - "officer_id": officer.id + "officer_id": o.uid }, ) return o.to_json() @@ -282,7 +279,8 @@ def delete_officer(officer_uid: str): # ) # if employments is not None: # # If the officer already has a records for this agency, -# # we need to update the earliest and latest employment dates +# # we need to update the earliest and +# # latest employment dates # employment = employment_to_orm(record) # employment.officer_id = officer_id # employment = merge_employment_records( diff --git a/backend/routes/partners.py b/backend/routes/partners.py index b4ad1ac3a..de0bdb1a1 100644 --- a/backend/routes/partners.py +++ b/backend/routes/partners.py @@ -1,6 +1,5 @@ import logging -from datetime import datetime from backend.auth.jwt import min_role_required from backend.mixpanel.mix import track_to_mp from backend.database.models.user import User, UserRole @@ -14,7 +13,6 @@ from ..database import ( Partner, - PartnerMember, MemberRole, Invitation, StagedInvitation, @@ -75,7 +73,8 @@ def create_partner(): } ) # update to UserRole contributor status - if current_user.role_enum.get_value() < UserRole.CONTRIBUTOR.get_value(): + if (current_user.role_enum.get_value() + < UserRole.CONTRIBUTOR.get_value()): current_user.role = UserRole.CONTRIBUTOR.value current_user.save() logger.info(f"User {current_user.uid} created partner {new_p.name}") @@ -225,9 +224,9 @@ def add_member_to_partner(): msg = Message("Invitation to join NPDC partner organization!", sender=TestingConfig.MAIL_USERNAME, recipients=[body.email]) - msg.body = """You have been invited - to a join a partner organization. Please log on to accept or decline - the invitation at https://dev.nationalpolicedata.org/.""" + msg.body = "You have been invited to a join a partner" + \ + " organization. Please log on to accept or decline" + \ + " the invitation at https://dev.nationalpolicedata.org/." mail.send(msg) return { "status": "ok", @@ -285,8 +284,10 @@ def add_member_to_partner(): @bp.route("/join", methods=["POST"]) @jwt_required() @min_role_required(UserRole.PUBLIC) +@validate_request(CreatePartner) def join_organization(): logger = logging.getLogger("join_organization") + body: CreatePartner = request.validated_body jwt_decoded = get_jwt() current_user = User.get(jwt_decoded["sub"]) partner = Partner.nodes.get_or_none(uid=body["partner_id"]) @@ -296,7 +297,7 @@ def join_organization(): "message": "Partner not found!" }, 404 - invitations = current_user.invitations.all() + # invitations = current_user.invitations.all() # TODO: Confirm that the user has a valid invitation to this organization. # If not, return a 403 error. # Note: currently inivtations are implemented as a Node... Perhaps a diff --git a/backend/schemas.py b/backend/schemas.py index ab7fdd759..2fcfede99 100644 --- a/backend/schemas.py +++ b/backend/schemas.py @@ -342,11 +342,17 @@ def from_dict(cls: Type[T], data: dict, uid=None) -> T: uid=value) rel_manager.connect(related_instance) except DoesNotExist: - raise ValueError(f"Related {related_node_class.__name__} with UID {value} not found.") + raise ValueError( + "Related {} with UID {} not found.".format( + related_node_class.__name__, + value + )) # Handle relationship properties if key.endswith("_details"): rel_name = key[:-8] - if isinstance(getattr(cls, rel_name, None), RelationshipManager): + if isinstance( + getattr(cls, rel_name, None), RelationshipManager + ): rel_manager = getattr(instance, rel_name) if rel_manager.exists(): relationship = rel_manager.relationship( @@ -367,9 +373,12 @@ def __all_properties__(cls) -> List[str]: def __all_relationships__(cls) -> dict: """Get all relationships defined in the class.""" return { - rel_name: rel_manager for rel_name, rel_manager in cls.__dict__.items() + rel_name: rel_manager + for rel_name, rel_manager in cls.__dict__.items() if isinstance( - rel_manager, (RelationshipTo, RelationshipFrom, Relationship)) + rel_manager, + (RelationshipTo, RelationshipFrom, Relationship) + ) } @classmethod diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index b3d946581..160f1842d 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -6,7 +6,6 @@ from backend.database import User, UserRole from backend.database import ( Partner, - PartnerMember, MemberRole, Jurisdiction, Agency, diff --git a/backend/tests/test_agencies.py b/backend/tests/test_agencies.py index a612391f5..caa9f5cce 100644 --- a/backend/tests/test_agencies.py +++ b/backend/tests/test_agencies.py @@ -1,6 +1,6 @@ import pytest import math -from backend.database import Agency, Officer, Jurisdiction, Unit +from backend.database import Agency mock_officers = { @@ -58,6 +58,7 @@ "jurisdiction": "MUNICIPAL" } + @pytest.fixture def example_agencies(db_session): agencies = {} diff --git a/backend/tests/test_employment.py b/backend/tests/test_employment.py index 47fa6d2ed..b05d7dea0 100644 --- a/backend/tests/test_employment.py +++ b/backend/tests/test_employment.py @@ -1,5 +1,3 @@ -import pytest -from backend.database import Agency, Officer mock_officers = { diff --git a/backend/tests/test_partners.py b/backend/tests/test_partners.py index 289587211..fed445acc 100644 --- a/backend/tests/test_partners.py +++ b/backend/tests/test_partners.py @@ -1,9 +1,8 @@ import pytest import math from flask_jwt_extended import decode_token -from backend.database import Partner, PartnerMember, MemberRole, Invitation +from backend.database import Partner, MemberRole from backend.database.models.user import User, UserRole -from datetime import datetime publisher_email = "pub@partner.com" @@ -300,7 +299,8 @@ def test_get_partner_members( # partner_id=example_partner.id # ).first() -# assert partner_member_obj.user_id == example_members["publisher"]["user_id"] +# assert partner_member_obj.user_id == +# example_members["publisher"]["user_id"] # assert partner_member_obj.partner_id == example_partner.id # """ diff --git a/init-user-db.sh b/init-user-db.sh deleted file mode 100644 index 13b33162b..000000000 --- a/init-user-db.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -e - -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL - CREATE DATABASE police_data; - GRANT ALL PRIVILEGES ON DATABASE police_data TO $POSTGRES_USER; -EOSQL \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 433e3d82f..02fa49b23 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,7 @@ [flake8] max-line-length = 80 extend-ignore = E203 +exclude = backend/routes/tmp/pydantic [tool:pytest] env =