internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: weni-ai/bothub-engine

Issue:
Disallow samples without intent or entities
Disallow samples creation without an intent or one entity at least.


Discussion:
Validate it in API level

https://github.com/push-flow/bothub/blob/master/bothub/api/serializers/example.py#L82

Resolving patch:
diff --git a/bothub/api/serializers/example.py b/bothub/api/serializers/example.py
--- a/bothub/api/serializers/example.py
+++ b/bothub/api/serializers/example.py
@@ -9,6 +9,7 @@
 from ..fields import EntityText
 from ..validators import CanContributeInRepositoryExampleValidator
 from ..validators import CanContributeInRepositoryValidator
+from ..validators import ExampleWithIntentOrEntityValidator
 from .translate import RepositoryTranslatedExampleSerializer
 
 
@@ -109,6 +110,10 @@ class Meta:
         many=True,
         style={'text_field': 'text'})
 
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.validators.append(ExampleWithIntentOrEntityValidator())
+
     def validate_repository(self, repository):
         return repository.current_update()
 
diff --git a/bothub/api/validators.py b/bothub/api/validators.py
--- a/bothub/api/validators.py
+++ b/bothub/api/validators.py
@@ -60,3 +60,12 @@ def __call__(self, attrs):
         if original_example.repository_update.language == language:
             raise ValidationError({'language': _(
                 'Can\'t translate to the same language')})
+
+
+class ExampleWithIntentOrEntityValidator(object):
+    def __call__(self, attrs):
+        intent = attrs.get('intent')
+        entities = attrs.get('entities')
+
+        if not intent and not entities:
+            raise ValidationError(_('Define a intent or one entity'))


Test patch:
diff --git a/bothub/api/tests/example.py b/bothub/api/tests/example.py
--- a/bothub/api/tests/example.py
+++ b/bothub/api/tests/example.py
@@ -141,6 +141,19 @@ def test_with_entities(self):
             len(content_data.get('entities')),
             1)
 
+    def test_intent_or_entity_required(self):
+        response, content_data = self.request(
+            self.owner_token,
+            {
+                'repository': str(self.repository.uuid),
+                'text': 'hi',
+                'intent': '',
+                'entities': [],
+            })
+        self.assertEqual(
+            response.status_code,
+            status.HTTP_400_BAD_REQUEST)
+
 
 class RepositoryExampleRetrieveTestCase(TestCase):
     def setUp(self):
Repository: weni-ai/bothub-engine

Issue:
Update invalid entities text on translation
Replace the `Invalid Entities` text to `Entities need to match from the original content` when translating a sample with entities.
Update invalid entities text on translation
Replace the `Invalid Entities` text to `Entities need to match from the original content` when translating a sample with entities.


Discussion:
Change here: https://github.com/push-flow/bothub/blob/master/bothub/api/validators.py#L53
Change here: https://github.com/push-flow/bothub/blob/master/bothub/api/validators.py#L53

Resolving patch:
diff --git a/bothub/api/validators.py b/bothub/api/validators.py
--- a/bothub/api/validators.py
+++ b/bothub/api/validators.py
@@ -46,11 +46,24 @@ def set_context(self, serializer):
 class TranslatedExampleEntitiesValidator(object):
     def __call__(self, attrs):
         original_example = attrs.get('original_example')
+        entities_list = list(map(lambda x: dict(x), attrs.get('entities')))
+        original_entities_list = list(map(
+            lambda x: x.to_dict,
+            original_example.entities.all()))
         entities_valid = RepositoryTranslatedExample.same_entities_validator(
-            list(map(lambda x: dict(x), attrs.get('entities'))),
-            list(map(lambda x: x.to_dict, original_example.entities.all())))
+            entities_list,
+            original_entities_list)
         if not entities_valid:
-            raise ValidationError({'entities': _('Invalid entities')})
+            raise ValidationError({'entities': _(
+                'Entities need to match from the original content. ' +
+                'Entities: {0}. Original entities: {1}.').format(
+                    RepositoryTranslatedExample.count_entities(
+                        entities_list,
+                        to_str=True),
+                    RepositoryTranslatedExample.count_entities(
+                        original_entities_list,
+                        to_str=True),
+                )})
 
 
 class TranslatedExampleLanguageValidator(object):
diff --git a/bothub/common/models.py b/bothub/common/models.py
--- a/bothub/common/models.py
+++ b/bothub/common/models.py
@@ -2,6 +2,8 @@
 import base64
 import requests
 
+from functools import reduce
+
 from django.db import models
 from django.utils.translation import gettext as _
 from django.utils import timezone
@@ -466,6 +468,21 @@ def same_entities_validator(cls, a, b):
                 return False
         return True
 
+    @classmethod
+    def count_entities(cls, entities_list, to_str=False):
+        r = {}
+        reduce(
+            lambda current, next: current.update({
+                next.get('entity'): current.get('entity', 0) + 1,
+            }),
+            entities_list,
+            r)
+        if to_str:
+            r = ', '.join(map(
+                lambda x: '{} {}'.format(x[1], x[0]),
+                r.items())) if entities_list else 'no entities'
+        return r
+
     @property
     def has_valid_entities(self):
         original_entities = self.original_example.entities.all()


Test patch:
Repository: weni-ai/bothub-engine

Issue:
Repository edit options error
RepositoryViewSet raised this exception:
```
'RepositoryViewSet' object has no attribute 'metadata'
```


Discussion:

Resolving patch:
diff --git a/bothub/api/views.py b/bothub/api/views.py
--- a/bothub/api/views.py
+++ b/bothub/api/views.py
@@ -418,13 +418,26 @@ def get_serializer_class(self):
                 return self.edit_serializer_class
         return self.serializer_class
 
-    def get_permissions(self):
-        fn = getattr(self, self.action)
+    def get_action_permissions_classes(self):
+        if not self.action:
+            return None
+        fn = getattr(self, self.action, None)
+        if not fn:
+            return None
         fn_kwargs = getattr(fn, 'kwargs', None)
-        if fn_kwargs:
-            permission_classes = fn_kwargs.get('permission_classes')
-            if permission_classes:
-                return [permission() for permission in permission_classes]
+        if not fn_kwargs:
+            return None
+        permission_classes = fn_kwargs.get('permission_classes')
+        if not permission_classes:
+            return None
+        return permission_classes
+
+    def get_permissions(self):
+        action_permissions_classes = self.get_action_permissions_classes()
+        if action_permissions_classes:
+            return [permission()
+                    for permission
+                    in action_permissions_classes]
         return super().get_permissions()
 
 


Test patch:
Repository: weni-ai/bothub-engine

Issue:
Repository edit options error
RepositoryViewSet raised this exception:
```
'RepositoryViewSet' object has no attribute 'metadata'
```


Discussion:

Resolving patch:
diff --git a/bothub/api/views.py b/bothub/api/views.py
--- a/bothub/api/views.py
+++ b/bothub/api/views.py
@@ -418,13 +418,26 @@ def get_serializer_class(self):
                 return self.edit_serializer_class
         return self.serializer_class
 
-    def get_permissions(self):
-        fn = getattr(self, self.action)
+    def get_action_permissions_classes(self):
+        if not self.action:
+            return None
+        fn = getattr(self, self.action, None)
+        if not fn:
+            return None
         fn_kwargs = getattr(fn, 'kwargs', None)
-        if fn_kwargs:
-            permission_classes = fn_kwargs.get('permission_classes')
-            if permission_classes:
-                return [permission() for permission in permission_classes]
+        if not fn_kwargs:
+            return None
+        permission_classes = fn_kwargs.get('permission_classes')
+        if not permission_classes:
+            return None
+        return permission_classes
+
+    def get_permissions(self):
+        action_permissions_classes = self.get_action_permissions_classes()
+        if action_permissions_classes:
+            return [permission()
+                    for permission
+                    in action_permissions_classes]
         return super().get_permissions()
 
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@
 
 setup(
     name='bothub',
-    version='1.8.6',
+    version='1.8.7',
     description='bothub',
     packages=find_packages(),
     install_requires=install_requires,


Test patch:
Repository: weni-ai/bothub-engine

Issue:
Intents field in repository serializer return blank item



Discussion:

Resolving patch:
diff --git a/bothub/common/models.py b/bothub/common/models.py
--- a/bothub/common/models.py
+++ b/bothub/common/models.py
@@ -181,9 +181,10 @@ def votes_sum(self):
     @property
     def intents(self):
         return list(set(self.examples(
-            deleted=False).values_list(
-                'intent',
-                flat=True)))
+            deleted=False).exclude(
+                intent='').values_list(
+                    'intent',
+                    flat=True)))
 
     @property
     def entities(self):


Test patch:
diff --git a/bothub/common/tests.py b/bothub/common/tests.py
--- a/bothub/common/tests.py
+++ b/bothub/common/tests.py
@@ -312,6 +312,16 @@ def test_entities(self):
             'name',
             self.repository.entities)
 
+    def test_not_blank_value_in_intents(self):
+        RepositoryExample.objects.create(
+            repository_update=self.repository.current_update(
+                languages.LANGUAGE_EN),
+            text='hi')
+
+        self.assertNotIn(
+            '',
+            self.repository.intents)
+
 
 class RepositoryExampleTestCase(TestCase):
     def setUp(self):
Repository: weni-ai/bothub-engine

Issue:
Just email console backend in development mode
When EMAIL_HOST is setted and DEBUG is True email continue on console


Discussion:

Resolving patch:
diff --git a/bothub/settings.py b/bothub/settings.py
--- a/bothub/settings.py
+++ b/bothub/settings.py
@@ -169,7 +169,7 @@
     default='webmaster@localhost')
 SERVER_EMAIL = config('SERVER_EMAIL', default='root@localhost')
 
-if not DEBUG and envvar_EMAIL_HOST:
+if envvar_EMAIL_HOST:
     EMAIL_HOST = envvar_EMAIL_HOST
     EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
     EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='')


Test patch:
Repository: weni-ai/bothub-engine

Issue:
Relative STATIC_URL in production broken email images



Discussion:

Resolving patch:
diff --git a/bothub/settings.py b/bothub/settings.py
--- a/bothub/settings.py
+++ b/bothub/settings.py
@@ -122,7 +122,7 @@
 
 # Static files (CSS, JavaScript, Images)
 
-STATIC_URL = '/static/'
+STATIC_URL = config('STATIC_URL', default='/static/')
 
 STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
 


Test patch:
Repository: weni-ai/bothub-engine

Issue:
Relative STATIC_URL in production broken email images



Discussion:

Resolving patch:
diff --git a/bothub/settings.py b/bothub/settings.py
--- a/bothub/settings.py
+++ b/bothub/settings.py
@@ -122,7 +122,7 @@
 
 # Static files (CSS, JavaScript, Images)
 
-STATIC_URL = '/static/'
+STATIC_URL = config('STATIC_URL', default='/static/')
 
 STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 
 setup(
     name='bothub',
-    version='1.12.0',
+    version='1.12.1',
     description='bothub',
     packages=find_packages(),
     install_requires=[


Test patch:
Repository: weni-ai/bothub-engine

Issue:
check_accessible_api returns False in production



Discussion:

Resolving patch:
diff --git a/bothub/health/checks.py b/bothub/health/checks.py
--- a/bothub/health/checks.py
+++ b/bothub/health/checks.py
@@ -1,11 +1,14 @@
 import logging
 
+from decouple import config
 from rest_framework import status
 
 
 logger = logging.getLogger('bothub.health.checks')
 
-CHECK_ACCESSIBLE_API_URL = '/api/repositories/'
+CHECK_ACCESSIBLE_API_URL = config(
+    'CHECK_ACCESSIBLE_API_URL',
+    default='http://localhost/api/repositories/')
 
 
 def check_database_connection(**kwargs):
@@ -24,17 +27,13 @@ def check_database_connection(**kwargs):
     return True
 
 
-def check_accessible_api(request, **kwargs):
-    from django.test import Client
-    logger.info('making request to {}'.format(CHECK_ACCESSIBLE_API_URL))
-    client = Client()
-    response = client.get(CHECK_ACCESSIBLE_API_URL)
-    logger.info('{} status code: {}'.format(
+def check_accessible_api(**kwargs):
+    import requests
+    logger.info('requesting {}'.format(CHECK_ACCESSIBLE_API_URL))
+    response = requests.get(CHECK_ACCESSIBLE_API_URL)
+    logger.info('{} response status code {}'.format(
         CHECK_ACCESSIBLE_API_URL,
         response.status_code))
-    if response.status_code is not status.HTTP_200_OK:
-        logger.info('{} returns {}'.format(
-            CHECK_ACCESSIBLE_API_URL,
-            response.content))
-        return False
-    return True
+    if response.status_code is status.HTTP_200_OK:
+        return True
+    return False
diff --git a/docker/gunicorn.conf.py b/docker/gunicorn.conf.py
new file mode 100644
--- /dev/null
+++ b/docker/gunicorn.conf.py
@@ -0,0 +1,6 @@
+import multiprocessing
+
+bind = 'unix:/tmp/bothub.sock'
+workers = multiprocessing.cpu_count() * 2 + 1
+raw_env = ['DJANGO_SETTINGS_MODULE=bothub.settings']
+daemon = True


Test patch:
Repository: weni-ai/bothub-engine

Issue:
Rest API just generate HTTP urls
next links (List Views) and absolute urls are generated to HTTP protocol because the all requests are make in port 80.


Discussion:

Resolving patch:
diff --git a/bothub/settings.py b/bothub/settings.py
--- a/bothub/settings.py
+++ b/bothub/settings.py
@@ -239,3 +239,8 @@
     'SUPPORTED_LANGUAGES',
     default='en|pt',
     cast=cast_supported_languages)
+
+
+# SECURE PROXY SSL HEADER
+
+SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 
 setup(
     name='bothub',
-    version='1.15.0',
+    version='1.15.1',
     description='bothub',
     packages=find_packages(),
     install_requires=[


Test patch:
Repository: weni-ai/bothub-engine

Issue:
Ghost Intent
Reported by @IlhasoftPeter in https://github.com/Ilhasoft/bothub/issues/26


Discussion:

Resolving patch:
diff --git a/bothub/common/models.py b/bothub/common/models.py
--- a/bothub/common/models.py
+++ b/bothub/common/models.py
@@ -190,7 +190,7 @@ def votes_sum(self):
     @property
     def intents(self):
         return list(set(self.examples(
-            exclude_deleted=False).exclude(
+            exclude_deleted=True).exclude(
                 intent='').values_list(
                     'intent',
                     flat=True)))


Test patch:
diff --git a/bothub/common/tests.py b/bothub/common/tests.py
--- a/bothub/common/tests.py
+++ b/bothub/common/tests.py
@@ -292,7 +292,7 @@ def test_intents(self):
             'greet',
             self.repository.intents)
 
-        RepositoryExample.objects.create(
+        example = RepositoryExample.objects.create(
             repository_update=self.repository.current_update(
                 languages.LANGUAGE_PT),
             text='tchau',
@@ -305,6 +305,12 @@ def test_intents(self):
             'bye',
             self.repository.intents)
 
+        example.delete()
+
+        self.assertNotIn(
+            'bye',
+            self.repository.intents)
+
     def test_entities(self):
         example = RepositoryExample.objects.create(
             repository_update=self.repository.current_update(
Repository: weni-ai/bothub-engine

Issue:
Ghost Intent
Reported by @IlhasoftPeter in https://github.com/Ilhasoft/bothub/issues/26


Discussion:

Resolving patch:
diff --git a/bothub/common/models.py b/bothub/common/models.py
--- a/bothub/common/models.py
+++ b/bothub/common/models.py
@@ -190,7 +190,7 @@ def votes_sum(self):
     @property
     def intents(self):
         return list(set(self.examples(
-            exclude_deleted=False).exclude(
+            exclude_deleted=True).exclude(
                 intent='').values_list(
                     'intent',
                     flat=True)))
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 
 setup(
     name='bothub',
-    version='1.15.1',
+    version='1.15.2',
     description='bothub',
     packages=find_packages(),
     install_requires=[


Test patch:
diff --git a/bothub/common/tests.py b/bothub/common/tests.py
--- a/bothub/common/tests.py
+++ b/bothub/common/tests.py
@@ -292,7 +292,7 @@ def test_intents(self):
             'greet',
             self.repository.intents)
 
-        RepositoryExample.objects.create(
+        example = RepositoryExample.objects.create(
             repository_update=self.repository.current_update(
                 languages.LANGUAGE_PT),
             text='tchau',
@@ -305,6 +305,12 @@ def test_intents(self):
             'bye',
             self.repository.intents)
 
+        example.delete()
+
+        self.assertNotIn(
+            'bye',
+            self.repository.intents)
+
     def test_entities(self):
         example = RepositoryExample.objects.create(
             repository_update=self.repository.current_update(
Repository: weni-ai/bothub-engine

Issue:
Fix intent default value to all examples, migration intent required



Discussion:

Resolving patch:
diff --git a/bothub/common/migrations/0021_auto_20180921_1259.py b/bothub/common/migrations/0021_auto_20180921_1259.py
--- a/bothub/common/migrations/0021_auto_20180921_1259.py
+++ b/bothub/common/migrations/0021_auto_20180921_1259.py
@@ -5,6 +5,11 @@
 import re
 
 
+def populate_empty_intent(apps, *args):
+    RepositoryExample = apps.get_model('common', 'RepositoryExample')
+    RepositoryExample.objects.filter(intent='').update(intent='no_intent')
+
+
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -17,4 +22,5 @@ class Migration(migrations.Migration):
             name='intent',
             field=models.CharField(default='no_intent', help_text='Example intent reference', max_length=64, validators=[django.core.validators.RegexValidator(re.compile('^[-a-z0-9_]+\\Z'), 'Enter a valid value consisting of lowercase letters, numbers, underscores or hyphens.', 'invalid')], verbose_name='intent'),
         ),
+        migrations.RunPython(populate_empty_intent),
     ]


Test patch:
Repository: weni-ai/bothub-engine

Issue:
Training with no sentences
Reported by @johncordeiro in https://github.com/Ilhasoft/bothub/issues/36


Discussion:

Resolving patch:
diff --git a/bothub/common/models.py b/bothub/common/models.py
--- a/bothub/common/models.py
+++ b/bothub/common/models.py
@@ -481,6 +481,9 @@ def ready_for_train(self):
            not self.deleted.exists():
             return False
 
+        if self.examples.count() == 0:
+            return False
+
         return len(self.requirements_to_train) is 0
 
     @property


Test patch:
diff --git a/bothub/common/tests.py b/bothub/common/tests.py
--- a/bothub/common/tests.py
+++ b/bothub/common/tests.py
@@ -871,6 +871,15 @@ def test_entity_dont_have_min_examples(self):
             entity='hi')
         self.assertTrue(self.repository.current_update().ready_for_train)
 
+    def test_no_examples(self):
+        example = RepositoryExample.objects.create(
+            repository_update=self.repository.current_update(),
+            text='hi',
+            intent='greet')
+        self.repository.current_update().start_training(self.owner)
+        example.delete()
+        self.assertFalse(self.repository.current_update().ready_for_train)
+
 
 class RequestRepositoryAuthorizationTestCase(TestCase):
     def setUp(self):
Repository: weni-ai/bothub-engine

Issue:
Wrong sentences counting in intents list
Reported by @johncordeiro in https://github.com/Ilhasoft/bothub/issues/43


Discussion:

Resolving patch:
diff --git a/bothub/api/v2/repository/serializers.py b/bothub/api/v2/repository/serializers.py
--- a/bothub/api/v2/repository/serializers.py
+++ b/bothub/api/v2/repository/serializers.py
@@ -162,7 +162,7 @@ def get_intents(self, obj):
                 lambda intent: {
                     'value': intent,
                     'examples__count': obj.examples(
-                        exclude_deleted=False).filter(
+                        exclude_deleted=True).filter(
                             intent=intent).count(),
                 },
                 obj.intents),


Test patch:
diff --git a/bothub/api/v2/repository/tests.py b/bothub/api/v2/repository/tests.py
--- a/bothub/api/v2/repository/tests.py
+++ b/bothub/api/v2/repository/tests.py
@@ -8,11 +8,13 @@
 from bothub.common.models import RepositoryCategory
 from bothub.common.models import Repository
 from bothub.common.models import RequestRepositoryAuthorization
+from bothub.common.models import RepositoryExample
 from bothub.common import languages
 
 from ..tests.utils import create_user_and_token
 
 from .views import RepositoryViewSet
+from .serializers import RepositorySerializer
 
 
 def get_valid_mockups(categories):
@@ -362,3 +364,36 @@ def test_false_when_request(self):
         available_request_authorization = content_data.get(
             'available_request_authorization')
         self.assertFalse(available_request_authorization)
+
+
+class IntentsInRepositorySerializer(TestCase):
+    def setUp(self):
+        self.owner, self.owner_token = create_user_and_token('owner')
+
+        self.repository = Repository.objects.create(
+            owner=self.owner,
+            name='Testing',
+            slug='test',
+            language=languages.LANGUAGE_EN)
+        RepositoryExample.objects.create(
+            repository_update=self.repository.current_update(),
+            text='hi',
+            intent='greet')
+
+    def test_count_1(self):
+        repository_data = RepositorySerializer(self.repository).data
+        intent = repository_data.get('intents')[0]
+        self.assertEqual(intent.get('examples__count'), 1)
+
+    def test_example_deleted(self):
+        example = RepositoryExample.objects.create(
+            repository_update=self.repository.current_update(),
+            text='hi',
+            intent='greet')
+        repository_data = RepositorySerializer(self.repository).data
+        intent = repository_data.get('intents')[0]
+        self.assertEqual(intent.get('examples__count'), 2)
+        example.delete()
+        repository_data = RepositorySerializer(self.repository).data
+        intent = repository_data.get('intents')[0]
+        self.assertEqual(intent.get('examples__count'), 1)