<commit_before>import uuid
import jsonschema

from rest_framework import serializers

from .models import (
    Api,
    Consumer,
    ConsumerKey,
    Plugin,
)
from .schemas import plugins


class ApiSerializer(serializers.ModelSerializer):
    class Meta:
        model = Api
        fields = '__all__'


class ConsumerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Consumer
        fields = '__all__'


class ConsumerKeySerializer(serializers.ModelSerializer):
    class Meta:
        model = ConsumerKey
        fields = '__all__'
        extra_kwargs = {
            'key': {
                'required': False,
                'allow_null': True,
                'allow_blank': True,
            },
        }

    def validate_key(self, value):
        """Verify if no key is given and generate one"""
        if not value:
            value = str(uuid.uuid4()).replace('-', '')
        return value


class PluginSerializer(serializers.ModelSerializer):
    class Meta:
        model = Plugin
        fields = '__all__'
        extra_kwargs = {
            'config': {
                'default': {},
            }
        }

    def validate(self, data):
        name = data.get('name')
        if not name or name not in plugins:
            raise serializers.ValidationError('Invalid plugin name')

        plugin_schema = plugins[name]

        try:
            jsonschema.validate(data['config'], plugin_schema)
        except jsonschema.ValidationError as e:
            raise serializers.ValidationError({'config': e})

        return data
<commit_msg>Use SlugRelatedField for foreign keys for better readability<commit_after>import uuid
import jsonschema

from rest_framework import serializers

from .models import (
    Api,
    Consumer,
    ConsumerKey,
    Plugin,
)
from .schemas import plugins


class ConsumerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Consumer
        fields = '__all__'


class ConsumerKeySerializer(serializers.ModelSerializer):
    consumer = serializers.SlugRelatedField(
        many=False,
        read_only=False,
        slug_field='username',
        queryset=Consumer.objects.all()
    )

    class Meta:
        model = ConsumerKey
        fields = '__all__'
        extra_kwargs = {
            'key': {
                'required': False,
                'allow_null': True,
                'allow_blank': True,
            },
        }

    def validate_key(self, value):
        """Verify if no key is given and generate one"""
        if not value:
            value = str(uuid.uuid4()).replace('-', '')
        return value


class PluginSerializer(serializers.ModelSerializer):
    api = serializers.SlugRelatedField(
        many=False,
        read_only=True,
        slug_field='name'
    )

    class Meta:
        model = Plugin
        fields = '__all__'
        extra_kwargs = {
            'config': {
                'default': {},
            }
        }

    def validate(self, data):
        name = data.get('name')
        if not name or name not in plugins:
            raise serializers.ValidationError('Invalid plugin name')

        plugin_schema = plugins[name]

        try:
            jsonschema.validate(data['config'], plugin_schema)
        except jsonschema.ValidationError as e:
            raise serializers.ValidationError({'config': e})

        return data


class ApiSerializer(serializers.ModelSerializer):
    plugins = PluginSerializer(
        many=True,
        read_only=False,
    )

    class Meta:
        model = Api
        fields = '__all__'

{'fraction_non_alphanumeric': 0.09090909090909091, 'fraction_numerical': 0.0005560189046427579, 'mean_word_length': 1.9983333333333333, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '2819824', 'n_tokens_mistral': 986, 'n_tokens_neox': 948, 'n_words': 246}