fedspendingtransparency/usaspending-api

View on GitHub

Showing 164 of 226 total issues

Cyclomatic complexity is too high in class SpendingOverTimeFederalAccountsViewSet. (36)
Open

class SpendingOverTimeFederalAccountsViewSet(APIView):
    """
    This route takes a federal_account DB ID and returns the data required to visualized the spending over time graphic.
    """

Cyclomatic Complexity

Cyclomatic Complexity corresponds to the number of decisions a block of code contains plus 1. This number (also called McCabe number) is equal to the number of linearly independent paths through the code. This number can be used as a guide when testing conditional logic in blocks.

Radon analyzes the AST tree of a Python program to compute Cyclomatic Complexity. Statements have the following effects on Cyclomatic Complexity:

Construct Effect on CC Reasoning
if +1 An if statement is a single decision.
elif +1 The elif statement adds another decision.
else +0 The else statement does not cause a new decision. The decision is at the if.
for +1 There is a decision at the start of the loop.
while +1 There is a decision at the while statement.
except +1 Each except branch adds a new conditional path of execution.
finally +0 The finally block is unconditionally executed.
with +1 The with statement roughly corresponds to a try/except block (see PEP 343 for details).
assert +1 The assert statement internally roughly equals a conditional statement.
Comprehension +1 A list/set/dict comprehension of generator expression is equivalent to a for loop.
Boolean Operator +1 Every boolean operator (and, or) adds a decision point.

Source: http://radon.readthedocs.org/en/latest/intro.html

File api_request_utils.py has 346 lines of code (exceeds 250 allowed). Consider refactoring.
Open

from datetime import date, time, datetime
from django.contrib.postgres.search import SearchVector
from django.db.models import Q
from django.utils import timezone
from usaspending_api.common.exceptions import InvalidParameterException
Severity: Minor
Found in usaspending_api/common/api_request_utils.py - About 4 hrs to fix

    File elasticsearch_indexer.py has 344 lines of code (exceeds 250 allowed). Consider refactoring.
    Open

    import logging
    from abc import ABC, abstractmethod
    from datetime import datetime, timezone
    from time import perf_counter
    
    
    Severity: Minor
    Found in usaspending_api/etl/management/commands/elasticsearch_indexer.py - About 4 hrs to fix

      File source_procurement_transaction.py has 331 lines of code (exceeds 250 allowed). Consider refactoring.
      Open

      from django.db import models
      from django.contrib.postgres.fields import ArrayField
      
      from usaspending_api.common.custom_django_fields import NumericField, NaiveTimestampField
      
      
      Severity: Minor
      Found in usaspending_api/transactions/models/source_procurement_transaction.py - About 3 hrs to fix

        Function spending_filter has a Cognitive Complexity of 37 (exceeds 15 allowed). Consider refactoring.
        Open

        def spending_filter(alt_set, queryset, filters, _type):
            for key, value in filters.items():
                # check for valid key
                if value is None:
                    raise InvalidParameterException("Invalid filter: " + key + " has null as its value.")
        Severity: Minor
        Found in usaspending_api/spending_explorer/v2/filters/spending_filter.py - About 3 hrs to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Cyclomatic complexity is too high in function test_load_source_assistance_by_ids. (32)
        Open

        @pytest.mark.django_db
        @pytest.mark.skip(reason="Test based on pre-databricks loader code. Remove when fully cut over.")
        def test_load_source_assistance_by_ids():
            """
            Simple end-to-end integration test to exercise the FABS loader given 3 records in an actual broker database

        Cyclomatic Complexity

        Cyclomatic Complexity corresponds to the number of decisions a block of code contains plus 1. This number (also called McCabe number) is equal to the number of linearly independent paths through the code. This number can be used as a guide when testing conditional logic in blocks.

        Radon analyzes the AST tree of a Python program to compute Cyclomatic Complexity. Statements have the following effects on Cyclomatic Complexity:

        Construct Effect on CC Reasoning
        if +1 An if statement is a single decision.
        elif +1 The elif statement adds another decision.
        else +0 The else statement does not cause a new decision. The decision is at the if.
        for +1 There is a decision at the start of the loop.
        while +1 There is a decision at the while statement.
        except +1 Each except branch adds a new conditional path of execution.
        finally +0 The finally block is unconditionally executed.
        with +1 The with statement roughly corresponds to a try/except block (see PEP 343 for details).
        assert +1 The assert statement internally roughly equals a conditional statement.
        Comprehension +1 A list/set/dict comprehension of generator expression is equivalent to a for loop.
        Boolean Operator +1 Every boolean operator (and, or) adds a decision point.

        Source: http://radon.readthedocs.org/en/latest/intro.html

        File detached_award_procurement.py has 316 lines of code (exceeds 250 allowed). Consider refactoring.
        Open

        DETACHED_AWARD_PROCUREMENT_COLUMNS = {
            "detached_award_procurement_id": {"delta": "INTEGER", "postgres": "INTEGER"},
            "detached_award_proc_unique": {"delta": "STRING", "postgres": "TEXT"},
            "a_76_fair_act_action": {"delta": "STRING", "postgres": "TEXT"},
            "a_76_fair_act_action_desc": {"delta": "STRING", "postgres": "TEXT"},

          Function _handle_exit_signal has a Cognitive Complexity of 35 (exceeds 15 allowed). Consider refactoring.
          Open

              def _handle_exit_signal(self, signum, frame, parent_dispatcher_signaled=True, is_retry=False):
                  """Attempt to gracefully handle the exiting of the job as a result of receiving an exit signal.
          
                  NOTE: This handler is only expected to be run from the parent dispatcher process. It is an error
                  condition if it is invoked from the child worker process. Signals received in the child worker
          Severity: Minor
          Found in usaspending_api/common/sqs/sqs_work_dispatcher.py - About 3 hrs to fix

          Cognitive Complexity

          Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

          A method's cognitive complexity is based on a few simple rules:

          • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
          • Code is considered more complex for each "break in the linear flow of the code"
          • Code is considered more complex when "flow breaking structures are nested"

          Further reading

          File autocomplete.py has 312 lines of code (exceeds 250 allowed). Consider refactoring.
          Open

          from django.db.models import Case, F, IntegerField, Q, When
          from django.db.models.functions import Upper
          from rest_framework.response import Response
          from rest_framework.views import APIView
          
          
          Severity: Minor
          Found in usaspending_api/references/v2/views/autocomplete.py - About 3 hrs to fix

            File search_elasticsearch.py has 311 lines of code (exceeds 250 allowed). Consider refactoring.
            Open

            import copy
            import logging
            
            from django.conf import settings
            from rest_framework.response import Response
            Severity: Minor
            Found in usaspending_api/search/v2/views/search_elasticsearch.py - About 3 hrs to fix

              File financial_accounts_by_awards.py has 310 lines of code (exceeds 250 allowed). Consider refactoring.
              Open

              FINANCIAL_ACCOUNTS_BY_AWARDS_COLUMNS = {
                  "data_source": "STRING",
                  "financial_accounts_by_awards_id": "INTEGER NOT NULL",
                  "piid": "STRING",
                  "parent_award_id": "STRING",
              Severity: Minor
              Found in usaspending_api/awards/delta_models/financial_accounts_by_awards.py - About 3 hrs to fix

                Function source_subquery_sql has a Cognitive Complexity of 34 (exceeds 15 allowed). Consider refactoring.
                Open

                    def source_subquery_sql(self, transaction_type=None):
                        def build_date_format_sql(col: TransactionColumn, is_casted_to_date: bool = True) -> str:
                            """Builder function to wrap a column in date-parsing logic.
                
                            It will either parse it in mmddYYYY format with - or / as a required separator, or in YYYYmmdd format
                Severity: Minor
                Found in usaspending_api/etl/management/commands/load_transactions_in_delta.py - About 3 hrs to fix

                Cognitive Complexity

                Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

                A method's cognitive complexity is based on a few simple rules:

                • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
                • Code is considered more complex for each "break in the linear flow of the code"
                • Code is considered more complex when "flow breaking structures are nested"

                Further reading

                Cyclomatic complexity is too high in method validate_post_request. (30)
                Open

                    def validate_post_request(self, request):
                        if "filters" in request:
                            for filt in request["filters"]:
                                if "combine_method" in filt:
                                    try:

                Cyclomatic Complexity

                Cyclomatic Complexity corresponds to the number of decisions a block of code contains plus 1. This number (also called McCabe number) is equal to the number of linearly independent paths through the code. This number can be used as a guide when testing conditional logic in blocks.

                Radon analyzes the AST tree of a Python program to compute Cyclomatic Complexity. Statements have the following effects on Cyclomatic Complexity:

                Construct Effect on CC Reasoning
                if +1 An if statement is a single decision.
                elif +1 The elif statement adds another decision.
                else +0 The else statement does not cause a new decision. The decision is at the if.
                for +1 There is a decision at the start of the loop.
                while +1 There is a decision at the while statement.
                except +1 Each except branch adds a new conditional path of execution.
                finally +0 The finally block is unconditionally executed.
                with +1 The with statement roughly corresponds to a try/except block (see PEP 343 for details).
                assert +1 The assert statement internally roughly equals a conditional statement.
                Comprehension +1 A list/set/dict comprehension of generator expression is equivalent to a for loop.
                Boolean Operator +1 Every boolean operator (and, or) adds a decision point.

                Source: http://radon.readthedocs.org/en/latest/intro.html

                File update_transactions.py has 303 lines of code (exceeds 250 allowed). Consider refactoring.
                Open

                import logging
                
                from datetime import datetime
                from usaspending_api.common.helpers.date_helper import fy
                from django.core.management.base import BaseCommand
                Severity: Minor
                Found in usaspending_api/broker/management/commands/update_transactions.py - About 3 hrs to fix

                  File spending.py has 296 lines of code (exceeds 250 allowed). Consider refactoring.
                  Open

                  import logging
                  from decimal import Decimal
                  from typing import List
                  
                  from django.contrib.postgres.fields import ArrayField
                  Severity: Minor
                  Found in usaspending_api/disaster/v2/views/agency/spending.py - About 3 hrs to fix

                    Function __init__ has a Cognitive Complexity of 31 (exceeds 15 allowed). Consider refactoring.
                    Open

                        def __init__(self, *args, **kwargs):
                            # Grab any kwargs include and exclude fields, these are typically
                            # passed in by a parent serializer to the child serializer
                            kwargs_has_include = "fields" in kwargs
                            kwargs_has_exclude = "exclude" in kwargs
                    Severity: Minor
                    Found in usaspending_api/common/serializers.py - About 2 hrs to fix

                    Cognitive Complexity

                    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

                    A method's cognitive complexity is based on a few simple rules:

                    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
                    • Code is considered more complex for each "break in the linear flow of the code"
                    • Code is considered more complex when "flow breaking structures are nested"

                    Further reading

                    File spending_by_geography.py has 285 lines of code (exceeds 250 allowed). Consider refactoring.
                    Open

                    from decimal import Decimal
                    from enum import Enum
                    from typing import Optional, List, Dict
                    
                    from rest_framework.request import Request
                    Severity: Minor
                    Found in usaspending_api/disaster/v2/views/spending_by_geography.py - About 2 hrs to fix

                      Function _select_columns has a Cognitive Complexity of 30 (exceeds 15 allowed). Consider refactoring.
                      Open

                      def _select_columns(sql: str) -> Tuple[str, List[str]]:
                          in_quotes = False
                          in_cte = False
                          parens_depth = 0
                          last_processed_index = 0
                      Severity: Minor
                      Found in usaspending_api/download/filestreaming/download_generation.py - About 2 hrs to fix

                      Cognitive Complexity

                      Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

                      A method's cognitive complexity is based on a few simple rules:

                      • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
                      • Code is considered more complex for each "break in the linear flow of the code"
                      • Code is considered more complex when "flow breaking structures are nested"

                      Further reading

                      Cyclomatic complexity is too high in function test_load_source_procurement_by_ids. (26)
                      Open

                      @pytest.mark.django_db

                      Cyclomatic Complexity

                      Cyclomatic Complexity corresponds to the number of decisions a block of code contains plus 1. This number (also called McCabe number) is equal to the number of linearly independent paths through the code. This number can be used as a guide when testing conditional logic in blocks.

                      Radon analyzes the AST tree of a Python program to compute Cyclomatic Complexity. Statements have the following effects on Cyclomatic Complexity:

                      Construct Effect on CC Reasoning
                      if +1 An if statement is a single decision.
                      elif +1 The elif statement adds another decision.
                      else +0 The else statement does not cause a new decision. The decision is at the if.
                      for +1 There is a decision at the start of the loop.
                      while +1 There is a decision at the while statement.
                      except +1 Each except branch adds a new conditional path of execution.
                      finally +0 The finally block is unconditionally executed.
                      with +1 The with statement roughly corresponds to a try/except block (see PEP 343 for details).
                      assert +1 The assert statement internally roughly equals a conditional statement.
                      Comprehension +1 A list/set/dict comprehension of generator expression is equivalent to a for loop.
                      Boolean Operator +1 Every boolean operator (and, or) adds a decision point.

                      Source: http://radon.readthedocs.org/en/latest/intro.html

                      File disaster_covid19_file_f_contracts.py has 275 lines of code (exceeds 250 allowed). Consider refactoring.
                      Open

                      f_contracts_sql_string = """
                      SELECT
                          subaward_search.unique_award_key AS prime_award_unique_key,
                          subaward_search.award_id AS prime_award_piid,
                          subaward_search.parent_award_id AS prime_award_parent_piid,
                        Severity
                        Category
                        Status
                        Source
                        Language