title: Setting up a file upload stream scan using Clamav in a Django back-end
body: <p>Working on a React/Django app. I have files being uploaded by users through the React front-end that end up in the Django/DRF back-end. We have antivirus (AV) running on the server constantly, but we want to add stream scanning before it is written to disk.</p>
  
  <p>It is a bit over my head as how to set it up. Here are a few sources I am looking at.</p>
  
  <p><a href="https://stackoverflow.com/questions/3363767/how-do-you-virus-scan-a-file-being-uploaded-to-your-java-webapp-as-it-streams">How do you virus scan a file being uploaded to your java webapp as it streams?</a></p>
  
  <p>Although accepted best answer describes it being "... quite easy" to setup, I'm struggling.</p>
  
  <p>I apparently need to <code>cat testfile | clamscan -</code> per the post and the corresponding documentation:</p>
  
  <p><a href="https://stackoverflow.com/questions/3363767/how-do-you-virus-scan-a-file-being-uploaded-to-your-java-webapp-as-it-streams">How do you virus scan a file being uploaded to your java webapp as it streams?</a></p>
  
  <p>So if my back-end looks like the following:</p>
  
  <pre><code>class SaveDocumentAPIView(APIView):
      permission_classes = [IsAuthenticated]
  
      def post(self, request, *args, **kwargs):
  
          # this is for handling the files we do want
          # it writes the files to disk and writes them to the database
          for f in request.FILES.getlist('file'):
              max_id = Uploads.objects.all().aggregate(Max('id'))
              if max_id['id__max'] == None:
                  max_id = 1
              else:    
                  max_id = max_id['id__max'] + 1
              data = {
                  'user_id': request.user.id,
                  'sur_id': kwargs.get('sur_id'),
                  'co': User.objects.get(id=request.user.id).co,
                  'date_uploaded': datetime.datetime.now(),
                  'size': f.size
              }
              filename = str(data['co']) + '_' + \
                      str(data['sur_id']) + '_' + \
                      str(max_id) + '_' + \
                      f.name
              data['doc_path'] = filename
              self.save_file(f, filename)
              serializer = SaveDocumentSerializer(data=data)
              if serializer.is_valid(raise_exception=True):
                  serializer.save()
          return Response(status=HTTP_200_OK)
  
      # Handling the document
      def save_file(self, file, filename):
          with open('fileupload/' + filename, 'wb+') as destination:
              for chunk in file.chunks():
                  destination.write(chunk)
  </code></pre>
  
  <p>I think I need to add something to the <code>save_file</code> method like:</p>
  
  <pre><code>for chunk in file.chunks():
      # run bash comman from python
      cat chunk | clamscan -
      if passes_clamscan:
          destination.write(chunk)
          return HttpResponse('It passed')
      else:
          return HttpResponse('Virus detected')
  </code></pre>
  
  <p>So my issues are:</p>
  
  <p>1) How to run the Bash from Python?</p>
  
  <p>2) How to receive a result response from the scan so that it can be sent back to the user and other things can be done with the response on the back-end? (Like creating logic to send the user and the admin an email that their file had a virus).</p>
  
  <p>I have been toying with this, but not much luck.</p>
  
  <p><a href="https://stackoverflow.com/questions/4256107/running-bash-commands-in-python">Running Bash commands in Python</a></p>
  
  <p>Furthermore, there are Github repos out there that claim to marry Clamav with Django pretty well, but they either haven't been updated in years or the existing documentation is pretty bad. See the following:</p>
  
  <p><a href="https://github.com/vstoykov/django-clamd" rel="nofollow noreferrer">https://github.com/vstoykov/django-clamd</a></p>
  
  <p><a href="https://github.com/musashiXXX/django-clamav-upload" rel="nofollow noreferrer">https://github.com/musashiXXX/django-clamav-upload</a></p>
  
  <p><a href="https://github.com/QueraTeam/django-clamav" rel="nofollow noreferrer">https://github.com/QueraTeam/django-clamav</a></p>