boto3 'str' object has no attribute 'get
<p>I am following the example at <a href="https://devcenter.heroku.com/articles/s3-upload-python" rel="nofollow">https://devcenter.heroku.com/articles/s3-upload-python</a> for uploading files directly to s3 from the client and am coming up with errors</p>

<p>views.api.sign_s3:</p>

<pre><code>def sign_s3(request):

    S3_BUCKET = os.environ.get('S3_BUCKET')
    file_name = request.GET.get('file_name',False)
    file_type = request.GET.get('file_type',False)

    s3 = boto3.client('s3')

    presigned_post = s3.generate_presigned_post(
        Bucket = S3_BUCKET,
        Key = file_name,
        Fields = {"acl": "public-read", "Content-Type": file_type},
        Conditions = [
          {"acl": "public-read"},
          {"Content-Type": file_type}
        ],
        ExpiresIn = 3600
    )

    return json.dumps({
        'data': presigned_post,
        'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
    })
</code></pre>

<p>settings.py:</p>

<pre><code>os.environ['S3_BUCKET'] = 'mybucketname'
os.environ['AWS_ACCESS_KEY_ID'] = 'myaccesskey'
os.environ['AWS_SECRET_ACCESS_KEY'] = 'mysecretaccesskey'
</code></pre>

<p>html file</p>

<pre><code>&lt;input id="file_input" name="video_files" type="file"&gt;
&lt;!-- other html omitted --&gt;

&lt;script&gt;
(function() {
    document.getElementById("file_input").onchange = function(){
        var files = document.getElementById("file_input").files;
        var file = files[0];
        if(!file){
            return alert("No file selected.");
        }
        $(files).each(function(i,file){
             getSignedRequest(file);
        });
   };
})();

function getSignedRequest(file){
    var xhr = new XMLHttpRequest();
    console.log(file);
    xhr.open("GET", "/api/sign_s3?file_name="+file.name+"&amp;file_type="+file.type);
    xhr.onreadystatechange = function(){
        if(xhr.readyState === 4){
            if(xhr.status === 200){
                var response = JSON.parse(xhr.responseText);
                uploadFile(file, response.data, response.url);
            }else{
                alert("Could not get signed URL.");
            }
        }
   };
   xhr.send();
}

function uploadFile(file, s3Data, url){
    var xhr = new XMLHttpRequest();
    xhr.open("POST", s3Data.url);

    var postData = new FormData();
    for(key in s3Data.fields){
        postData.append(key, s3Data.fields[key]);
    }
    postData.append('file', file);

    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4){
            if(xhr.status === 200 || xhr.status === 204){
                document.getElementById("preview").src = url;
                document.getElementById("avatar-url").value = url;
            }else{
                alert("Could not upload file.");
            }
       }
   };
   xhr.send(postData);
 }

&lt;/script&gt;
</code></pre>

<p>Traceback:</p>

<pre><code>AttributeError at /api/sign_s3/
'str' object has no attribute 'get'
Request Method: GET
Request URL:    http://127.0.0.1:1337/api/sign_s3/?    file_name=jam13.mp4&amp;file_type=video/mp4
Django Version: 1.8.5
Exception Type: AttributeError
Exception Value:    
'str' object has no attribute 'get'
Exception Location: c:\Python27\lib\site-packages\django\middleware\clickjacking.py in process_response, line 31
Python Executable:  c:\Python27\python.exe
Python Version: 2.7.3
</code></pre>

<p>...</p>

<pre><code>c:\Python27\lib\site-packages\django\middleware\clickjacking.py in process_response
clickjacking protection techniques should be used if protection in those
browsers is required.
https://en.wikipedia.org/wiki/Clickjacking#Server_and_client
"""
def process_response(self, request, response):
    # Don't set it if it's already in the response
                if response.get('X-Frame-Options', None) is not None: ...
        return response
    # Don't set it if they used @xframe_options_exempt
    if getattr(response, 'xframe_options_exempt', False):
        return response
</code></pre>

<p>anyone have any idea what's going wrong?</p>

<p>I think the way you are returning the response to your view is causing the trouble.</p>

<p>Try something like this - </p>

<pre><code>import json
from django.http import HttpResponse, JsonResponse

def sign_s3(request):
   #Your View Code Here...

   #Finally The Response (Using JsonResponse)...
   json_object = {
    'data': presigned_post,
    'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
   }
   return JsonResponse(json_object)

   #Another Response Option (Using HttpResponse)
   data = {
    'data': presigned_post,
    'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
   }
   return HttpResponse(json.dumps(data), content_type = "application/json")
</code></pre>

python django heroku amazon-s3 boto3