<commit_before>"""
Public interface for the submissions app.

"""
import copy
import itertools
import logging
import operator
import json

from django.conf import settings
from django.core.cache import cache
from django.db import IntegrityError, DatabaseError
from dogapi import dog_stats_api

from submissions.serializers import (
    SubmissionSerializer, StudentItemSerializer, ScoreSerializer, UnannotatedScoreSerializer
)
from submissions.models import Submission, StudentItem, Score, ScoreSummary, ScoreAnnotation, score_set, score_reset

logger = logging.getLogger("submissions.api")


# By default, limit the number of top submissions
# Anything above this limit will result in a request error
MAX_TOP_SUBMISSIONS = 100

# Set a relatively low cache timeout for top submissions.
TOP_SUBMISSIONS_CACHE_TIMEOUT = 300


class SubmissionError(Exception):
    """An error that occurs during submission actions.

    This error is raised when the submission API cannot perform a requested
    action.

    """
    pass


class SubmissionInternalError(SubmissionError):
    """An error internal to the Submission API has occurred.

    This error is raised when an error occurs that is not caused by incorrect
    use of the API, but rather internal implementation of the underlying
    services.

    """
    pass


class SubmissionNotFoundError(SubmissionError):
    """This error is raised when no submission is found for the request.

    If a state is specified in a call to the API that results in no matching
    Submissions, this error may be raised.

    """
    pass


class SubmissionRequestError(SubmissionError):
    """This error is raised when there was a request-specific error

    This error is reserved for problems specific to the use of the API.

    """
    def __init__(self, msg="", field_errors=None):
        """
        Configure the submission request error.

        Keyword Args:
            msg (unicode): The error message.
            field_errors (dict): A dictionary of errors (list of unicode)
                specific to a fields provided in the request.

        Example usage:

        >>> raise SubmissionRequestError(
        >>>     "An unexpected error occurred"
        >>>     {"answer": ["Maximum answer length exceeded."]}
        >>> )

        """
        super(SubmissionRequestError, self).__init__(msg)
        self.field_errors = (
            copy.deepcopy(field_errors)
            if field_errors is not None
            else {}
        )


def create_submission(student_item_dict, answer, submitted_at=None, attempt_number=None):<commit_msg>Print the validator errors when SubmissionRequestError is thrown.<commit_after>"""
Public interface for the submissions app.

"""
import copy
import itertools
import logging
import operator
import json

from django.conf import settings
from django.core.cache import cache
from django.db import IntegrityError, DatabaseError
from dogapi import dog_stats_api

from submissions.serializers import (
    SubmissionSerializer, StudentItemSerializer, ScoreSerializer, UnannotatedScoreSerializer
)
from submissions.models import Submission, StudentItem, Score, ScoreSummary, ScoreAnnotation, score_set, score_reset

logger = logging.getLogger("submissions.api")


# By default, limit the number of top submissions
# Anything above this limit will result in a request error
MAX_TOP_SUBMISSIONS = 100

# Set a relatively low cache timeout for top submissions.
TOP_SUBMISSIONS_CACHE_TIMEOUT = 300


class SubmissionError(Exception):
    """An error that occurs during submission actions.

    This error is raised when the submission API cannot perform a requested
    action.

    """
    pass


class SubmissionInternalError(SubmissionError):
    """An error internal to the Submission API has occurred.

    This error is raised when an error occurs that is not caused by incorrect
    use of the API, but rather internal implementation of the underlying
    services.

    """
    pass


class SubmissionNotFoundError(SubmissionError):
    """This error is raised when no submission is found for the request.

    If a state is specified in a call to the API that results in no matching
    Submissions, this error may be raised.

    """
    pass


class SubmissionRequestError(SubmissionError):
    """This error is raised when there was a request-specific error

    This error is reserved for problems specific to the use of the API.

    """
    def __init__(self, msg="", field_errors=None):
        """
        Configure the submission request error.

        Keyword Args:
            msg (unicode): The error message.
            field_errors (dict): A dictionary of errors (list of unicode)
                specific to a fields provided in the request.

        Example usage:

        >>> raise SubmissionRequestError(
        >>>     "An unexpected error occurred"
        >>>     {"answer": ["Maximum answer length exceeded."]}
        >>> )

        """
        super(SubmissionRequestError, self).__init__(msg)
        self.field_errors = (
            copy.deepcopy(field_errors)
            if field_errors is not None
            else {}
        )

    def __repr__(self):
        """
        Show the field errors upon output.
        """
        return '{}(msg="{}", field_errors={})'.format(
            self.__class__.__name__, self.message, self.field_errors
        )


def create_submission(student_item_dict, answer, submitted_at=None, attempt_number=None):
{'fraction_non_alphanumeric': 0.066654492330168, 'fraction_numerical': 0.002191380569758948, 'mean_word_length': 3.1905126243305277, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3697847', 'n_tokens_mistral': 1393, 'n_tokens_neox': 1325, 'n_words': 558}