I'm sure by now you know that I have released a book and a couple of videos on Flask in cooperation with O'Reilly Media. While the coverage of the Flask framework in these is fairly complete, there are a small number of features that for one reason or another did not get mentioned much, so I thought it would be a good idea to write articles about them here.
This article is dedicated to streaming, an interesting feature that gives Flask applications the ability to provide large responses efficiently partitioned in small chunks, potentially over a long period of time. To illustrate the topic I'm going to show you how to build a live video streaming server!
NOTE: there is now a follow-up to this article, Flask Video Streaming Revisited, in which I describe some improvements to the streaming server introduced here.
What is Streaming?
Streaming is a technique in which the server provides the response to a request in chunks. I can think of a couple of reasons why this might be useful:
- Very large responses. Having to assemble a response in memory only to return it to the client can be inefficient for very large responses. An alternative would be to write the response to disk and then return the file with
flask.send_file()
, but that adds I/O to the mix. Providing the response in small portions is a much better solution, assuming the data can be generated in chunks. - Real time data. For some applications a request may need to return data that comes from a real time source. A pretty good example of this is a real time video or audio feed. A lot of security cameras use this technique to stream video to web browsers.
Implementing Streaming With Flask
Flask provides native support for streaming responses through the use of generator functions. A generator is a special function that can be interrupted and resumed. Consider the following function:
def gen(): yield 1 yield 2 yield 3
This is a function that runs in three steps, each returning a value. Describing how generator functions are implemented is outside the scope of this article, but if you are a bit curious the following shell session will give you an idea of how generators are used:
>>> x = gen()>>> x<generator object gen at 0x7f06f3059c30>>>> next(x)1>>> next(x)2>>> next(x)3>>> next(x)Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration
You can see in this simple example that a generator function can return multiple results in sequence. Flask uses this characteristic of generator functions to implement streaming.
The example below shows how using streaming it is possible to generate a large data table, without having to assemble the entire table in memory:
from flask import Response, render_templatefrom app.models import Stockdef generate_stock_table(): yield render_template('stock_header.html') for stock in Stock.query.all(): yield render_template('stock_row.html', stock=stock) yield render_template('stock_footer.html')@app.route('/stock-table')def stock_table(): return Response(generate_stock_table())
In this example you can see how Flask works with generator functions. A route that returns a streamed response needs to return a Response
object that is initialized with the generator function. Flask then takes care of invoking the generator and sending all the partial results as chunks to the client.
For this particular example if you assume Stock.query.all()
returns the result of a database query as an iterable, then you can generate a potentially large table one row at a time, so regardless of the number of elements in the query the memory consumption in the Python process will not grow larger and larger due to having to assemble a large response string.
Multipart Responses
The table example above generates a traditional page in small portions, with all the parts concatenated into the final document. This is a good example of how to generate large responses, but something a little bit more exciting is to work with real time data.
An interesting use of streaming is to have each chunk replace the previous one in the page, as this enables streams to "play" or animate in the browser window. With this technique you can have each chunk in the stream be an image, and that gives you a cool video feed that runs in the browser!
The secret to implement in-place updates is to use a multipart response. Multipart responses consist of a header that includes one of the multipart content types, followed by the parts, separated by a boundary marker and each having its own part specific content type.
There are several multipart content types for different needs. For the purpose of having a stream where each part replaces the previous part the multipart/x-mixed-replace
content type must be used. To help you get an idea of how this looks, here is the structure of a multipart video stream:
HTTP/1.1 200 OKContent-Type: multipart/x-mixed-replace; boundary=frame--frameContent-Type: image/jpeg<jpeg data here>--frameContent-Type: image/jpeg<jpeg data here>...
As you see above, the structure is pretty simple. The main Content-Type
header is set to multipart/x-mixed-replace
and a boundary string is defined. Then each part is included, prefixed by two dashes and the part boundary string in their own line. The parts have their own Content-Type
header, and each part can optionally include a Content-Length
header with the length in bytes of the part payload, but at least for images browsers are able to deal with the stream without the length.
Building a Live Video Streaming Server
There's been enough theory in this article, now it is time to build a complete application that streams live video to web browsers.
There are many ways to stream video to browsers, and each method has its benefits and disadvantages. The method that works well with the streaming feature of Flask is to stream a sequence of independent JPEG pictures. This is called Motion JPEG, and is used by many IP security cameras. This method has low latency, but quality is not the best, since JPEG compression is not very efficient for motion video.
Below you can see a surprisingly simple, yet complete web application that can serve a Motion JPEG stream:
#!/usr/bin/env pythonfrom flask import Flask, render_template, Responsefrom camera import Cameraapp = Flask(__name__)@app.route('/')def index(): return render_template('index.html')def gen(camera): while True: frame = camera.get_frame() yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')@app.route('/video_feed')def video_feed(): return Response(gen(Camera()), mimetype='multipart/x-mixed-replace; boundary=frame')if __name__ == '__main__': app.run(host='0.0.0.0', debug=True)
This application imports a Camera
class that is in charge of providing the sequence of frames. Putting the camera control portion in a separate module is a good idea in this case, this way the web application remains clean, simple and generic.
The application has two routes. The /
route serves the main page, which is defined in the index.html
template. Below you can see the contents of this template file:
<html> <head> <title>Video Streaming Demonstration</title> </head> <body> <h1>Video Streaming Demonstration</h1> <img src="{{ url_for('video_feed') }}"> </body></html>
This is a simple HTML page with just a heading and an image tag. Note that the image tag's src
attribute points to the second route of this application, and this is where the magic happens.
The /video_feed
route returns the streaming response. Because this stream returns the images that are to be displayed in the web page, the URL to this route is in the src
attribute of the image tag. The browser will automatically keep the image element updated by displaying the stream of JPEG images in it, since multipart responses are supported in most/all browsers (let me know if you find a browser that doesn't like this).
The generator function used in the /video_feed
route is called gen()
, and takes as an argument an instance of the Camera
class. The mimetype
argument is set as shown above, with the multipart/x-mixed-replace
content type and a boundary set to the string "frame"
.
The gen()
function enters a loop where it continuously returns frames from the camera as response chunks. The function asks the camera to provide a frame by calling the camera.get_frame()
method, and then it yields with this frame formatted as a response chunk with a content type of image/jpeg
, as shown above.
Obtaining Frames from a Video Camera
Now all that is left is to implement the Camera
class, which will have to connect to the camera hardware and download live video frames from it. The nice thing about encapsulating the hardware dependent part of this application in a class is that this class can have different implementations for different people, but the rest of the application remains the same. You can think of this class as a device driver, which provides a uniform implementation regardless of the actual hardware device in use.
The other advantage of having the Camera
class separated from the rest of the application is that it is easy to fool the application into thinking there is a camera when in reality there is not, since the camera class can be implemented to emulate a camera without real hardware. In fact, while I was working on this application, the easiest way for me to test the streaming was to do that and not have to worry about the hardware until I had everything else running. Below you can see the simple emulated camera implementation that I used:
from time import timeclass Camera(object): def __init__(self): self.frames = [open(f + '.jpg', 'rb').read() for f in ['1', '2', '3']] def get_frame(self): return self.frames[int(time()) % 3]
This implementation reads three images from disk called 1.jpg
, 2.jpg
and 3.jpg
and then returns them one after another repeatedly, at a rate of one frame per second. The get_frame()
method uses the current time in seconds to determine which of the three frames to return at any given moment. Pretty simple, right?
To run this emulated camera I needed to create the three frames. Using gimp I've made the following images:
Because the camera is emulated, this application runs on any environment, so you can run this right now! I have this application all ready to go on GitHub. If you are familiar with git
you can clone it with the following command:
$ git clone https://github.com/miguelgrinberg/flask-video-streaming.git
If you prefer to download it, then you can get a zip file here.
Once you have the application installed, create a virtual environment and install Flask in it. Then you can run the application as follows:
$ python app.py
After you start the application enter http://localhost:5000
in your web browser and you will see the emulated video stream playing the 1, 2 and 3 images over and over. Pretty cool, right?
Once I had everything working I fired up my Raspberry Pi with its camera module and implemented a new Camera
class that converts the Pi into a video streaming server, using the picamera
package to control the hardware. I will not discuss this camera implementation here, but you can find it in the source code in file camera_pi.py
.
If you have a Raspberry Pi and a camera module you can edit app.py
to import the Camera
class from this module and then you will be able to live stream the Pi camera, like I'm doing in the following screenshot:
If you want to make this streaming application work with a different camera, then all you need to do is write another implementation of the Camera
class. If you end up writing one I would appreciate it if you contribute it to my GitHub project.
Limitations of Streaming
When the Flask application serves regular requests the request cycle is short. The web worker receives the request, invokes the handler function and finally returns the response. Once the response is sent back to the client the worker is free and ready to take on another request.
When a request that uses streaming is received, the worker remains attached to the client for the duration of the stream. When working with long, never ending streams such as a video stream from a camera, a worker will stay locked to the client until the client disconnects. This effectively means that unless specific measures are taken, the application can only serve as many clients as there are web workers. When working with the Flask application in debug mode that means just one, so you will not be able to connect a second browser window to watch the stream from two places at the same time.
There are ways to overcome this important limitation. The best solution in my opinion is to use a coroutine based web server such as gevent, which Flask fully supports. With the use of coroutines gevent is able to handle multiple clients on a single worker thread, as gevent modifies the Python I/O functions to issue context switches as necessary.
Conclusion
In case you missed it above, the code that supports this article is this GitHub repository: https://github.com/miguelgrinberg/flask-video-streaming/tree/v1. Here you can find a generic implementation of video streaming that does not require a camera, and also an implementation for the Raspberry Pi camera module. This follow-up article describes some improvements I made after this article was published originally.
I hope this article shed some light on the topic of streaming. I concentrated on video streaming because that is an area I have some experience, but streaming has many more uses besides video. For example, this technique can be used to keep a connection between the client and the server alive for a long time, allowing the server to push new information the moment it becomes available. These days the Web Socket protocol is a more efficient way to achieve this, but Web Socket is fairly new and works only in modern browsers, while streaming will work on pretty much any browser you can think of.
If you have any questions feel free to write them below. I plan to continue documenting more of the not well known Flask topics, so I hope you connect with me in some way to know when more articles are published. I hope to see you in the next one!
Miguel
FAQs
How do I live stream with Python? ›
- create stream from Twitch Dashboard. Edit pylivestream. ini to have the closest ingest server.
- put Twitch stream key into file ~/twitch.key.
- Run Python script for Twitch with chosen input. ScreenshareLivestream twitch.
Flask is a lightweight Python web framework that provides useful tools and features for creating web applications in the Python Language. It gives developers flexibility and is an accessible framework for new developers because you can build a web application quickly using only a single Python file.
How do you install a flask? ›- Python Version.
- Dependencies. Optional dependencies. greenlet.
- Virtual environments. Create an environment. Activate the environment.
- Install Flask.
- Create a Team.
- Choose an Online Video Host.
- Choose Your Content Delivery Network.
- Download SDK for iOS or Android.
- Load SDK to Mobile Development Software.
- Begin Live Streaming App Development.
- Package and Submit App.
- Step 1 – Define your audience and their needs. ...
- Step 2 – Choose Monetization Strategies. ...
- Step 3 – Use a reliable platform for Live Streaming, Hosting and Storage. ...
- Step 4 – Create Great UI/UX Design. ...
- Step 5 – Build and Test your MVP. ...
- Step 6 – Release, maintain, improve.
Building the Python WebRTC Signaling Server
We'll start with a file named server.py and initialize a basic Flask-SocketIO server in it. First, create a Flask app instance and set a secret_key for it. Then, create a SocketIO instance with this app and start the server on port 9000 from __main__ with socketio.
Flask is considered more “Pythonic” than Django is basically since Flask web application code is, in most cases, more unequivocal. Flask is the choice of most tenderfoots due to the need of barricades to getting a basic app up and running.
How do I access my camera in flask? ›'app. run()' is used to start the flask app in its default address: http://127.0.0.1:5000/. You can set a different host and port number by adding 'host' and 'port' arguments to the function 'run'. Setting host to broadcast address 0.0.
How do I record multiple camera streams with OpenCV? ›To capture multiple streams with OpenCV, I recommend using threading which can improve performance by alleviating the heavy I/O operations to a separate thread. Since accessing the webcam/IP/RTSP stream using cv2. VideoCapture().
Is Flask good for backend? ›Flask is a back-end framework, which means that it provides the technologies, tools, and modules that can be used to build the actual functionalities of the web app rather than the design or look of it. Flask is considered one of the easiest frameworks to learn for beginners.
Is Flask still used? ›
Django and Flask have mature communities, are widely supported and popular, and offer productive approaches to application development, letting you focus your time and energy on the unique parts of your application rather than the core scaffolding. In the end, both frameworks are used to develop web applications.
What can I build with Flask? ›Flask is a web framework. This means flask provides you with tools, libraries and technologies that allow you to build a web application. This web application can be some web pages, a blog, a wiki or go as big as a web-based calendar application or a commercial website.
Can flask run on Windows? ›To run the app outside of the VS Code debugger, use the following steps from a terminal: Set an environment variable for FLASK_APP . On Linux and macOS, use export set FLASK_APP=webapp ; on Windows use set FLASK_APP=webapp . Navigate into the hello_app folder, then launch the program using python -m flask run .
Is flask a Python library? ›Flask is a micro web framework written in Python. It is classified as a microframework because it does not require particular tools or libraries. It has no database abstraction layer, form validation, or any other components where pre-existing third-party libraries provide common functions.
Can we use flask in Windows? ›Installing Flask in Windows
To install Flask in Windows follow the following steps: Step 1: At first, open the command prompt in administrator mode. Then the following command should be run. This command will help to install Flask using Pip in Python and will take very less time to install.
Streaming features are typically pretty complex and so time-consuming and expensive to build. Talking about a Periscope-like app for two platforms (Android and iOS), its cost can range from $63,000 to $180,000 and above.
How do I make an app like Netflix? ›- Find your niche. ...
- Decide on the content availability. ...
- Choose the monetization model. ...
- Study the video streaming app requirements. ...
- Develop an on-demand streaming service MVP. ...
- Gather feedback.
How long will it take to create an engaging streaming app? Between 6 and 12 months. Take a look at our blog “How Long Does it Take to Develop an App?” for more information.
How do I make a streaming app for free? ›- Choose A Section In The Easy Start Section. Choose a template in the Easy Start section. ...
- Customize The Template, Add Content, And Make MOnetization Settings. Use the wide range of features and styles available to make the best live streaming app. ...
- Build The App And Upload It To App Store.
How can streaming companies make money? Music streaming companies will typically charge a subscription fee, play ads, or a combination of the two. Streaming services charge fees from the users in order to access the video content .
What is the difference between WebSocket and WebRTC? ›
WebSocket provides a client-server computer communication protocol, whereas WebRTC offers a peer-to-peer protocol and communication capabilities for browsers and mobile apps. While WebSocket works only over TCP, WebRTC is primarily used over UDP (although it can work over TCP as well).
What is the use of WebRTC? ›WebRTC (Web Real-Time Communication) is a technology that enables Web applications and sites to capture and optionally stream audio and/or video media, as well as to exchange arbitrary data between browsers without requiring an intermediary.
How do I use WebRTC on my website? ›- Introduction.
- Overview.
- Get the sample code.
- Stream video from your webcam.
- Stream video with RTCPeerConnection.
- Use RTCDataChannel to exchange data.
- Set up a signaling service to exchange messages.
- Combine peer connection and signaling.
Finally, Netflix uses Flask (Python Web Development library) API's to bind all of the previous segments together. Netflix makes use of Jupyter Notebook which is an open-source web app, used for Python development along with nteract (extension for Jupyter) on a large scale.
Is Flask used in industry? ›Industries do use Flask but more complex web apps are built on Django. Django's modularity makes it easier for multiple developers to work on different apps in one project. Beginners prefer Flask over Django though, because of its minimalistic design.
How difficult is Flask? ›Flask is very easy to learn, and also its implementation is straightforward. In just a few lines of code, you can get started with this. Flask is used in top tech companies also like: Netflix, Reddit, Mozilla, and so on. You can install this using pip: pip install flask.
How do I stream my Raspberry Pi camera flask? ›You can start the Flask Camera Stream via with the following command: sudo python3 /home/pi/pi-camera-stream-flask/main.py.
How do you make a python camera app? ›Back-End Implementation Steps :
Create a path variable and set it currently to blank. Add available cameras to the combo box and set the first camera as default. Add action to the Take Photo button. Inside the click action, capture the photo at the given path with name as a timestamp and increment the count.
- url = 'http://127.0.0.1:5000/im_size' my_img = {'image': open('test.jpg', 'rb')} r = requests. ...
- file. ...
- # img is PIL Image object img = Image.
The Arducam Raspberry Pi Multi-Camera Adapter is designed for connecting more than one camera module to a single CSI camera port on the Raspberry Pi. One adapter board can connect FOUR cameras on a single Raspberry Pi board, and includes support for the High-Quality Camera!
Does openCV work with any camera? ›
Pretty much any logitech camera is great for openCV, the most common one being the C270. You can get wider-angle cameras but they are nearly $100, so it's usually easier to just glue a phone camera lens on for a wider FOV. The Pixy is really popular, and it has a bunch of code and libraries available online.
How many USB cameras can a Raspberry Pi have? ›You can connect as many webcams as you want as long as they are powered up per their requirements, such as using a powered USB hub. Each usb web cam that you connect gets listed under /dev/video<n> where n, starting at 0 for camera 1, is the id of the device.
Which is better NodeJS or Flask? ›js can be primarily classified under "Frameworks (Full Stack)". "Lightweight", "Python" and "Minimal" are the key factors why developers consider Flask; whereas "Npm", "Javascript" and "Great libraries" are the primary reasons why Node. js is favored.
Should I learn NodeJS or Flask? ›However, we recommend learning both frameworks. It is easier to start with Flask and then move on to Django after gaining some experience in Web Development. If for some reason your development efforts require the use of JavaScript then you can go ahead with NodeJS.
Is Flask faster than Django? ›Due to fewer abstraction layers, Flask is faster than Django. It is a full-stack framework with almost everything built-in — a batteries-included approach. It is a microframework with minimalistic features that let developers integrate any plugins and libraries.
Is Flask worth learning in 2022? ›That's all about some of the best courses to learn Flask and Python in 2022. As I said, Flask is a great Python framework for web development. It's beautiful, elegant, lightweight, and easy to learn. It also has a lot of community support in case you need extra help and create.
Do professionals use Flask? ›It is simple, easy to use, and ideal for speedy development. Moreover, it's a popular framework that's used by a lot of professional developers. According to the 2021 Stack Overflow Survey, Flask ranks as the seventh most popular web framework .
Is Flask free for commercial use? ›Open-Source Flask Starters
Open-Source products released under the MIT License (free to use in commercial projects).
Django, on the one hand, is a full-stack web framework, whereas Flask is a light-weight, extensible framework. If you want to dig more into coding and learn core concepts, Flask helps you understand how each component from the back-end works to get a simple web application up and running.
Who uses Flask? ›Who uses Flask? 1122 companies reportedly use Flask in their tech stacks, including Netflix, reddit, and CRED.
How do I create a data stream in Python? ›
...
- 2.2 Analyze data. ...
- 2.3 Create a View to preview the tuples on the Stream. ...
- 2.4 Define output. ...
- Submit the application. ...
- Use a View to access data from the job.
Streams are high-level async/await-ready primitives to work with network connections. Streams allow sending and receiving data without using callbacks or low-level protocols and transports.
What is file stream Python? ›The file object is a data stream that supports next() method to read file line by line. When end of file is encountered, StopIteration exception is raised. f=open("python.txt","r") while True: try: line=next(f) print (line, end="") except StopIteration: break f.close()
What is data stream in Python? ›A DataStream is similar to a regular Python Collection in terms of usage but is quite different in some key ways. They are immutable, meaning that once they are created you cannot add or remove elements.
How does Python deal with streaming data? ›Using a Python library can assist you in learning the stream of data using various approaches. This library enables models to learn one data point at a time, allowing for updates as needed. This method aids in learning from large amounts of data that are not stored in the main memory.
What are the types of data streams? ›- Sensor readings from machines.
- e-Commerce purchase data.
- Stock exchange data to predict the stock price.
- Credit card transactions for fraud detection.
- Social media sentiment analysis.
Kafka Streams is a client library for building applications and microservices, where the input and output data are stored in an Apache Kafka® cluster. It combines the simplicity of writing and deploying standard Java and Scala applications on the client side with the benefits of Kafka's server-side cluster technology.
Does Python support streaming? ›stream-python is the official Python client for Stream, a web service for building scalable newsfeeds and activity streams. Note there is also a higher level Django - Stream integration library which hooks into the Django ORM. You can sign up for a Stream account at https://getstream.io/get_started.
How do I create a data stream? ›To create a stream
Sign in to the AWS Management Console and open the Kinesis console at https://console.aws.amazon.com/kinesis . Choose Data Streams in the navigation pane. In the navigation bar, expand the Region selector and choose a Region. Choose Create Kinesis stream.
We are going to cover 2 different stream classes: BytesIO — expects binary-like objects and produces bytes objects. StringIO — expects and produces str objects.
How many standard streams are available in Python? ›
There are three standard I/O streams: System.in — the input stream. System. out — the output stream for normal results.
What is byte stream in Python? ›Byte streams are a sequence of bytes used by programs to input and output information.
Can zip files be streamed? ›Limitations. It's not possible to completely stream-write ZIP files. Small bits of metadata for each member file, such as its name, must be placed at the end of the ZIP. In order to do this, stream-zip buffers this metadata in memory until it can be output.
How is data streaming done? ›What is Streaming Data? Also known as event stream processing, streaming data is the continuous flow of data generated by various sources. By using stream processing technology, data streams can be processed, stored, analyzed, and acted upon as it's generated in real-time.
What are the advantages of data streaming? ›- Increase ROI. The ability to quickly collect, analyze, and act on current data will give companies a competitive edge in their marketplace. ...
- Increase Customer Satisfaction. Customer feedback is a valuable litmus test for what an organization is doing right and where it can improve. ...
- Reduce Losses.
Data streaming can also be explained as a technology used to deliver content to devices over the internet, and it allows users to access the content immediately, rather than having to wait for it to be downloaded.