Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python requests return file-like object for streaming

I have created a requests object like this:

 obj.mp3 = requests.get('http://foo.com/bar.mp3', stream=True)

I thought that I could just feed this obj.mp3 object into any audio player that expects a file or an URI, obviously this idea is wrong: nothing played. Below are the full code:

#views.py

class ArticleDetailView(DetailView):
    model = Article
    template_name = 'song.html'

    def get_object(self):
        obj = super(ArticleDetailView, self).get_object()

        #code to store mp3 url in obj.mp3 and other stuff

        if obj.mp3:
            obj.mp3 = requests.get(obj.mp3, stream=True).content
        return obj

#song.html
<div class="audio">
  <audio src={{ article.mp3 }} type="audio/mpeg"> 
</div>

What is the correct way of treating return from requests as something that I can stream with a player? I know at least I can write the obj.mp3 to a file, then just point the player to the file location, but I am trying to avoid write the file to disk.

Thanks,

like image 832
eN_Joy Avatar asked Feb 11 '14 23:02

eN_Joy


1 Answers

There's an attribute Response.raw, which is already a file-like object.

resp = requests.get(url, stream=True)
resp.raw # is what you need

Using io.BytesIO(resp.content) is not preferable since behind the scenes you're reading the same amount of data twice (also memory-wise): accessing resp.content reads everything from the network stream, then io.BytesIO(resp.content) is allocating again the same amount of memory, and then you read it from BytesIO object.

like image 186
Innuendo Avatar answered Oct 20 '22 00:10

Innuendo