Skip to content

Commit

Permalink
Small improvements in external_api
Browse files Browse the repository at this point in the history
  • Loading branch information
Pablo Grill committed May 4, 2020
1 parent 46822bd commit fe9fa8a
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 24 deletions.
3 changes: 1 addition & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ DOMAIN=<VALUE>
FLASK_SECRET_KEY=<VALUE>
POSTGRES_PASSWORD=<DB_PASS_VALUE>
SECRET_KEY=<VALUE>
TRAEFIK_EMAIL=<VALUE>
TRAEFIK_DOMAIN=<VALUE>
TRAEFIK_EMAIL=<VALUE>
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ depends_on:
networks:
- proxy
labels:
- traefik.http.routers.whoami.rule=Host(`SERVICE_NAME.${TRAEFIK_DOMAIN}`)
- traefik.http.routers.whoami.rule=Host(`SERVICE_NAME.${DOMAIN}`)
- traefik.http.routers.whoami.tls=true
- traefik.http.routers.whoami.tls.certresolver=le
```
Expand All @@ -185,7 +185,7 @@ whoami:
networks:
- proxy
labels:
- traefik.http.routers.whoami.rule=Host(`whoami.${TRAEFIK_DOMAIN}`)
- traefik.http.routers.whoami.rule=Host(`whoami.${DOMAIN}`)
- traefik.http.routers.whoami.tls=true
- traefik.http.routers.whoami.tls.certresolver=le
```
Expand Down
3 changes: 2 additions & 1 deletion docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ services:

api:
volumes:
- ./external-api:/src:ro
- ./external-api:/src

This comment has been minimized.

Copy link
@bryant1410

bryant1410 May 4, 2020

Member

Does the api change the code?

This comment has been minimized.

Copy link
@pgrill

pgrill May 4, 2020

Yes, the command make_migrations.

environment:
- DB_PASS=postgres
- DEBUG=True
- SECRET_KEY=secret
ports:
- 8000:8000
command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]
2 changes: 1 addition & 1 deletion docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ services:
- traefik.http.middlewares.https_redirect.redirectscheme.scheme=https
- traefik.http.middlewares.https_redirect.redirectscheme.permanent=true
# Dashboard
- traefik.http.routers.api.rule=Host(`proxy.${TRAEFIK_DOMAIN}`)
- traefik.http.routers.api.rule=Host(`proxy.${DOMAIN}`)
- traefik.http.routers.api.service=api@internal
- traefik.http.routers.api.tls=true
- traefik.http.routers.api.tls.certresolver=le
3 changes: 2 additions & 1 deletion external-api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ RUN pip install --upgrade pip \
COPY external_api /src/external_api
COPY questions /src/questions
COPY manage.py /src
COPY wsgi.py /src
EXPOSE 8000

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
CMD ["uwsgi", "--http", ":8000", "--wsgi-file", "wsgi.py"]

This comment has been minimized.

Copy link
@bryant1410

bryant1410 May 4, 2020

Member

Just to check, it listens to 0.0.0.0, right?

This comment has been minimized.

Copy link
@pgrill

pgrill May 4, 2020

Yes, by default 0.0.0.0.

5 changes: 3 additions & 2 deletions external-api/external_api/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ def get_env(key, default=None, f=None):
SECRET_KEY = get_env('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = bool(get_env("DEBUG", "False"))
DEBUG = bool(get_env("DEBUG", 'False'))


ALLOWED_HOSTS = [
'127.0.0.1',
Expand Down Expand Up @@ -78,7 +79,7 @@ def get_env(key, default=None, f=None):
},
]

WSGI_APPLICATION = 'external_api.wsgi.application'
WSGI_APPLICATION = 'wsgi.application'

REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':
Expand Down
8 changes: 6 additions & 2 deletions external-api/external_api/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from django.conf.urls import include, url
from django.contrib import admin

from questions.views import AnswerFeedbackApiView, QuestionApiView, FrequentQuestionsApiView
from questions.views import (AnswerFeedbackApiView, CorrectApiView, QuestionApiView,
FrequentQuestionsApiView, WrongApiView, FakeApiView)

urlpatterns = [
url('admin/', admin.site.urls),
url('question/', QuestionApiView.as_view()),
url('feedback/', AnswerFeedbackApiView.as_view()),
url('frequent-questions/', FrequentQuestionsApiView.as_view())
url('frequent-questions/', FrequentQuestionsApiView.as_view()),
url('correct-answers/', CorrectApiView.as_view()),
url('wrong-answers/', WrongApiView.as_view()),
url('fake-answers/', FakeApiView.as_view()),
]
36 changes: 36 additions & 0 deletions external-api/questions/migrations/0003_auto_20200504_2151.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Generated by Django 3.0.5 on 2020-05-04 21:51

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('questions', '0002_auto_20200422_1920'),
]

operations = [
migrations.AddField(
model_name='answer',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='question',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AlterField(
model_name='answer',
name='feedback',
field=models.IntegerField(blank=True, choices=[(1, 'Respuesta Correcta'), (2, 'Respuesta Incorrecta'), (3, 'Noticia Falsa')], null=True),
),
migrations.AlterField(
model_name='question',
name='question',
field=models.CharField(blank=True, max_length=500, unique=True),
),
]
4 changes: 3 additions & 1 deletion external-api/questions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@


class Question(models.Model):
question = models.CharField(max_length=500, blank=True)
question = models.CharField(max_length=500, blank=True, unique=True)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.question
Expand All @@ -24,6 +25,7 @@ class Answer(models.Model):
context = models.TextField()
answer = models.CharField(max_length=500, blank=True)
feedback = models.IntegerField(choices=FEEDBACK_CHOICES, blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.answer
Expand Down
32 changes: 32 additions & 0 deletions external-api/questions/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from rest_framework import serializers

from .models import Answer


class QuestionInputSerializer(serializers.Serializer):
question = serializers.CharField()


class AnswerSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField()
context = serializers.CharField()
answer = serializers.CharField()
answer_start_index = serializers.CharField()
answer_end_index = serializers.CharField()
date = serializers.CharField()
source = serializers.CharField()
url = serializers.CharField()


class FeedbackInputSerializer(serializers.Serializer):
answer_id = serializers.IntegerField()
feedback = serializers.ChoiceField(choices=Answer.FEEDBACK_CHOICES)


class FeedbackSerializer(serializers.Serializer):
id = serializers.IntegerField()
question = serializers.CharField(source='question.question')
context = serializers.CharField()
answer = serializers.CharField()
answer_date = serializers.DateTimeField(source='created_at')
57 changes: 45 additions & 12 deletions external-api/questions/views.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,79 @@
import requests

from django.conf import settings
from django.db import transaction
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.parsers import JSONParser
from rest_framework.response import Response

from .models import Answer, Question
from .serializers import (AnswerSerializer, FeedbackInputSerializer, FeedbackSerializer,
QuestionInputSerializer)


class QuestionApiView(APIView):

@transaction.atomic
def post(self, request):
question = request.data.get('question')
question_serializer = QuestionInputSerializer(data=request.data)
question_serializer.is_valid(raise_exception=True)
question = question_serializer.validated_data['question'].lower()
question_obj, _ = Question.objects.get_or_create(question=question)
qa_response = requests.post(
f'{settings.QA_SERVER}/Covid19-QA/question',
json={'question': question}
)
if qa_response.status_code == 400:
answers = qa_response.json()
if qa_response.status_code != 200:
return qa_response
question_obj = Question.objects.create(question=question)
response = []
for answer in qa_response.json():
print(answer)
for answer in answers:
answer_obj = Answer.objects.create(
question=question_obj,
title=answer['title'],
context=answer['context'],
answer=answer['answer'],
)
answer['id'] = answer_obj.id
response.append(answer)
return Response(qa_response.json())
answer_serializer = AnswerSerializer(data=answers, many=True)
answer_serializer.is_valid(raise_exception=True)
return Response(answer_serializer.validated_data)


class AnswerFeedbackApiView(APIView):
@transaction.atomic
def post(self, request):
feedback = request.data.get('feedback')
answer_id = request.data.get('answer_id')
answer = Answer.objects.get(id=answer_id)
answer.feedback = feedback
feedback_serializer = FeedbackInputSerializer(data=request.data)
feedback_serializer.is_valid(raise_exception=True)
answer = get_object_or_404(
Answer, id=feedback_serializer.validated_data['answer_id']
)
answer.feedback = feedback_serializer.validated_data['feedback']
answer.save()
return Response(status=204)



class AnswersApiView(APIView):

queryset = Answer.objects
def get(self, request):
feedback_serializer = FeedbackSerializer(self.queryset.all(), many=True)
return Response(feedback_serializer.data)


class CorrectApiView(AnswersApiView):
queryset = Answer.objects.filter(feedback=Answer.CORRECT)


class WrongApiView(AnswersApiView):
queryset = Answer.objects.filter(feedback=Answer.WRONG)


class FakeApiView(AnswersApiView):
queryset = Answer.objects.filter(feedback=Answer.FAKE)


class FrequentQuestionsApiView(APIView):
def get(self, request):
hardcoded_response = [
Expand Down
1 change: 1 addition & 0 deletions external-api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ django_extensions==2.2.9
ipython==7.0.1

This comment has been minimized.

Copy link
@bryant1410

bryant1410 May 4, 2020

Member

Maybe we can remove this one.

This comment has been minimized.

Copy link
@pgrill

pgrill May 4, 2020

Yes, we can remove it. It is only a better shell for pyhton.

psycopg2-binary
requests==2.23.0
uWSGI==2.0.18
File renamed without changes.

0 comments on commit fe9fa8a

Please sign in to comment.