Commit 8da04b3a authored by CAMPION Sebastien's avatar CAMPION Sebastien

Dummy implementation of API v1

parent 18152481
......@@ -8,7 +8,7 @@ RUN apt-getq update && apt-getq install \
python3-django python3-django-allauth python3-misaka \
nginx-light zip gcc python3-dev python3-pip python3-wheel python3-mysqldb \
python-mysqldb python3-crypto gunicorn3 python3-redis python-mysqldb \
python3-crypto python3-djangorestframework supervisor
python3-crypto supervisor
COPY requirements.txt /tmp/
RUN cd /tmp && pip3 install -r requirements.txt && rm requirements.txt
......
import os
from django.conf import settings
def handle_uploaded_files(file_obj_dict, folder, job_id):
"""
Upload files according to a file multi dictionnary object
It save files in the datastore path defined in the settings.
Args
file_obj_dict MultiDict containing the different files to upload
folder Main directory where to store the data
job_id Sub directory created according to the job ID
Returns
Nothing
"""
for key, file_obj in file_obj_dict.items():
endpoint = os.path.join(
settings.DATASTORE,
folder,
str(job_id),
file_obj.name,
)
endpoint_dir = os.path.dirname(endpoint)
if not os.path.exists(endpoint_dir):
os.makedirs(endpoint_dir)
with open(endpoint, 'wb+') as destination:
for chunk in file_obj.chunks():
destination.write(chunk)
from rest_framework import serializers
from main.models import Job
class JobSerializer(serializers.ModelSerializer):
# files = serializers.SerializerMethodField()
# queue_id = serializers.IntegerField(label="Queue ID")
# param = serializers.CharField(label="Parameters")
class Meta:
model = Job
fields = (
'id',
'webapp',
'result',
'state',
'queue',
'param',
)
def create(self, validated_data):
return Job.objects.create(**validated_data)
......@@ -3,9 +3,7 @@ from rest_framework.authtoken import views as rest_framework_views
from . import views
urlpatterns = [
url(r'^jobs/$', views.job_list_get_create_api_view, name='job_rest_api'),
url(r'^jobs/(?P<id>[0-9]+)/$', views.job_retrieve_update_destroy_api_view, name='job_rest_api'),
url(r'^get_auth_token/$', rest_framework_views.obtain_auth_token, name='get_auth_token'),
url(r'^jobs$', views.jobs, name='jobs'),
url(r'^jobs/(\d+)', views.job, name='job'),
]
from django.conf import settings
from django.shortcuts import get_object_or_404
import logging
import os
import config.env
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework import status
from rest_framework.authentication import TokenAuthentication
from rest_framework.parsers import MultiPartParser, JSONParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.decorators import (
api_view,
authentication_classes,
parser_classes,
permission_classes,
)
from main.models import Job, AllgoUser, Webapp, JobQueue
from main.models import Job
from .serializers import JobSerializer
from api.helpers import handle_uploaded_files
log = logging.getLogger('allgo')
DATASTORE = config.env.ALLGO_DATASTORE
@api_view(['GET', 'POST'])
@authentication_classes((TokenAuthentication,))
@parser_classes((MultiPartParser, JSONParser))
@permission_classes((IsAuthenticated,))
@csrf_exempt
def job_list_get_create_api_view(request, format=None):
"""
Get the jobs through the API according an identified user and can create
a job with the following inputs:
Mandatory:
- state
- result
def get_user(request):
auth_header = request.META.get('HTTP_AUTHORIZATION', '')
if not auth_header:
log.info("API request without http authorisation %s %s %s", request.META['HTTP_USER_AGENT'],
request.META['REMOTE_ADDR'], request.META['QUERY_STRING'])
return HttpResponse(status=401)
token_type, credentials = auth_header.split(' ')
token = credentials.split('=')[-1]
log.info('API token checked for token %s', token)
return AllgoUser.objects.filter(token=token).first()
Optional:
- webapp (should be mandatory)
- queue (should have a default defined to 2)
- files (any number of files)
- param
"""
if request.method == 'GET':
"""
Display the jobs belonging to the authenticated user
"""
jobs = Job.objects.filter(user_id=request.user.id)
serializer = JobSerializer(jobs, many=True)
return Response(serializer.data)
def job_response(jobid):
status = {0: 'sumbit',
1: 'in queue',
2: 'running',
3: 'complete',
4: 'archive',
5: 'error'} # FIXME
odir = os.path.join(DATASTORE, str(jobid))
return {'status': status[job.state],
'files': os.listdir(odir)}
elif request.method == 'POST':
"""
Create a job and upload files
"""
serializer = JobSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user_id=request.user.id)
# Upload of the files
handle_uploaded_files(
request.FILES,
settings.JOBS_DIR,
serializer.data['id'],
)
return Response(serializer.data)
return Response(serializer.errors, status=400)
@csrf_exempt
def job(request, jobid):
if not get_user(request):
return HttpResponse(status=401)
job = Job.objects.filter(id=jobid, user=get_user(request)).first()
if not job:
log.error("Job %s does not exist", jobid)
return HttpResponse(status=401)
else:
return JsonResponse(job_response(jobid))
@api_view(['GET', 'DELETE'])
@authentication_classes((TokenAuthentication,))
@permission_classes((IsAuthenticated,))
@csrf_exempt
def job_retrieve_update_destroy_api_view(request, id):
def jobs(request):
user = get_user(request)
if not user:
return HttpResponse("User token invalid", status=401)
try:
job = get_object_or_404(Job, pk=id, user_id=request.user.id)
except Job.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
app = Webapp.objects.filter(id=request.POST['job[webapp_id]']).first()
if not app:
return HttpResponse("App not found", status=401)
if request.method == 'GET':
"""
Get and return a job according to its ID
"""
serializer = JobSerializer(job)
return Response(serializer.data)
queue = JobQueue.objects.filter(name=request.POST['job[queue]']).first()
if not queue:
return HttpResponse("Queue not found", status=401)
if request.method == 'DELETE':
"""
Delete the job selected
"""
job.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
job = Job.objects.create(param=request.POST['job[param]'], queue=queue, webapp=app, user=user.user)
odir = os.path.join(DATASTORE, str(job.id))
os.mkdir(odir)
print(request.FILES)
for filename, file_obj in request.FILES.items():
log.info("%s %s", filename, type(file_obj))
with open(os.path.join(odir, filename), 'wb') as fb:
for chunk in file_obj.chunks():
fb.write(chunk)
return JsonResponse(job_response(jobid))
......@@ -81,7 +81,7 @@ DATABASES['default']['ATOMIC_REQUESTS'] = True
# ------------------------------------------------------------------------------
ROOT_URLCONF = 'config.urls'
WSGI_APPLICATION = 'config.wsgi.application'
APPEND_SLASH=False
# APPS
# ------------------------------------------------------------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment