[Fixed]-Send, receive, save local image file with requests / django rest framework

1👍

I came to a solution that perfectly fits my needs. As I only found contributions for either the sending OR the receiving part, I’ll try to put everything together here.

Due to more flexibility my approach is to transfer json and images in seperated requests. The two following apps are completely independent.

The sending side does as follows (app with no server needed):

from django.core.serializers.json import DjangoJSONEncoder
import requests # http://docs.python-requests.org/en/master/
import datetime # in case...
import json

### send image stuff ###
urlImages = "http://127.0.0.1:8000/receive-images/"
file = "C:\\path\\to\\filename.jpg" # "\\" windows machine...

# this will probably run in a loop or so to process a bunch of images
with open(file, 'rb') as f:
    filename = "filename.jpg"
    files = {'file': (filename, f)}

    r = requests.post(urlImages, files=files)

print(r) # some logging here

### send data stuff ###
data = data # python data - lists, dicts, whatever
json = json.dumps(data, cls=DjangoJSONEncoder) # DjangoJSONEncoder handles datetime fields
urlData = "http://127.0.0.1:8000/receive-data/"
headers = {'content-type': 'application/json'}

r = requests.post(urlData, json, headers=headers)

print(r) # some logging here

The receiving side needs to run a server (built-in django server for dev, apache with the WSGInterface in production) and it has this chum installed: http://www.django-rest-framework.org/

Finally we have two views to handle the requests:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .api_controller import ApiController
from django.core.files.storage import default_storage

class ReceiveImages(APIView): # make sure to nail down corresponding url-confs
    def post(self, request, format=None):

        file = request.data.get('file')
        filename = str(file)

        with default_storage.open('images/' + filename, 'wb+') as destination:
            for chunk in file.chunks():
                destination.write(chunk)

        return Response("ok", status=status.HTTP_200_OK)

class ReceiveData(APIView): # make sure to nail down corresponding url-confs
    def post(self, request, format=None):
        json = request.data

        ApiController().createDataIfNotExists(json) 
        # As my json is quite complex, 
        # I've sourced out the DB-interactions to a controller-like class (coming 
        # from PHP symfony :)) with heavy use of the great 
        # MyModel.objects.get_or_create() method. Also the strptime() method is used 
        # to convert the datetime fields. This could also go here...

        return Response("ok", status=status.HTTP_200_OK)

using chunk() in respect to https://stackoverflow.com/a/30195605/6522103

Please (!) comment/answer if you don’t agree or think that this could be improved. Thanks!!

Leave a comment