Clients and Servers
Python provides two levels of access to network services. At a low level, you can access the basic socket support in the underlying operating system, which allows you to implement clients and servers for both connection-oriented and connectionless protocols. Python also has libraries that provide higher-level access to specific application-level network protocols, such as FTP, HTTP, and so on.
What are Sockets?
Sockets are a low-level abstraction providing the endpoints of a bidirectional communications channel. Sockets may communicate within a process, between processes on the same machine, or between processes on different continents.
Sockets may be implemented over a number of different channel types: Unix domain sockets, TCP, UDP, and so on. The socket library provides specific classes for handling the common transports as well as a generic interface for handling the rest. Documentation on sockets is found here https://docs.python.org/2/library/socket.html
A Simple Server:
To write Internet servers, we use the socket function available in socket module to create a socket object. A socket object is then used to call other functions to setup a socket server.
We first call bind(hostname, port function) to specify a port for your service on the given host. Next we call the accept method of the returned object. This method waits until a client connects to the port you specified, and then returns a connection object that represents the connection to that client.
#!/usr/bin/python # This is server.py file import socket # Import socket module s = socket.socket() # Create a socket object host = socket.gethostname() # Get local machine name port = 12345 # Reserve a port for your service. s.bind((host, port)) # Bind to the port s.listen(5) # Now wait for client connection. 5 specifies size of queue for connections while True: c, addr = s.accept() # Establish connection with client. print 'Got connection from', addr c.send('Thank you for connecting') c.close() # Close the connection
A Simple Client:
Now we will write a very simple client program which will open a connection to a given port 12345 and given host. The socket.connect(hosname, port ) opens a TCP connection to hostname on the port. Once you have a socket open, you can read from it like any IO object. When done, remember to close it, as you would close a file.
The following code is a very simple client that connects to a given host and port, reads any available data from the socket, and then exits:
#!/usr/bin/python # This is client.py file import socket # Import socket module s = socket.socket() # Create a socket object host = socket.gethostname() # Get local machine name port = 12345 # Reserve a port for your service. s.connect((host, port)) print s.recv(1024) s.close # Close the socket when done
Now run this server.py in background and then run above client.py to see the result.
# Following would start a server in background.
$ python server.py &
# Once server is started run client as follows:
$ python client.py
This would produce following result:
Got connection from ('127.0.0.1', 48437)
Thank you for connecting
The Architecture of a Data-Driven Web Application
A Web framework is a collection of packages or modules which allow developers to write Web applications without having to handle such low-level details as protocols, sockets or process/thread management. The majority of Web frameworks are exclusively server-side technology, although, with the increased prevalence of AJAX, some Web frameworks are beginning to include AJAX code that helps developers with the particularly tricky task of programming (client-side) the user’s browser. At the extreme end of the client-side Web Frameworks is technology that can use the web browser as a full-blown application execution environment (a la gmail for example): see Web Browser Programming for details.
As a developer using a framework, you typically write code which conforms to some kind of conventions that lets you “plug in” to the framework, delegating responsibility for the communications, infrastructure and low-level stuff to the framework while concentrating on the logic of the application in your own code. This “plugging in” aspect of Web development is often seen as being in opposition to the classical distinction between programs and libraries, and the notion of a “mainloop” dispatching events to application code is very similar to that found in event-driven GUI programming.
A Virtual Environment is a tool to keep the dependencies required by different projects in separate places, by creating virtual Python environments for them. It solves the “Project X depends on version 1.x but, Project Y needs 4.x” dilemma, and keeps your global site-packages directory clean and manageable.
virtualenv is a tool to create isolated Python environments. virtualenv creates a folder which contains all the necessary executables to use the packages that a Python project would need. More documentation on virtualenv can be found here http://docs.python-guide.org/en/latest/dev/virtualenvs/
Install virtualenv via pip:
$ pip install virtualenv
Create a virtual environment for a project:
$ cd my_project_folder
$ virtualenv venv
virtualenv venv will create a folder in the current directory which will contain the Python executable files, and a copy of the pip library which you can use to install other packages. The name of the virtual environment (in this case, it was venv) can be anything; omitting the name will place the files in the current directory instead.
This creates a copy of Python in whichever directory you ran the command in, placing it in a folder named venv.
You can also use a Python interpreter of your choice.
$ virtualenv -p /usr/bin/python2.7 venv
This will use the Python interpreter in /usr/bin/python2.7
To begin using the virtual environment, it needs to be activated:
$ source venv/bin/activate
The name of the current virtual environment will now appear on the left of the prompt (e.g. (venv)Your-Computer:your_project UserName$) to let you know that it’s active. From now on, any package that you install using pip will be placed in the venv folder, isolated from the global Python installation.
Install packages as usual, for example:
$ pip install requests
If you are done working in the virtual environment for the moment, you can deactivate it:
This puts you back to the system’s default Python interpreter with all its installed libraries.
To delete a virtual environment, just delete its folder. (In this case, it would be rm -rf venv.)
The Flask Framework: Quickstart
First let us install the Flask Web Framework within our virtual environment.
$ pip install flask
A Minimal Application
A minimal Flask application looks something like this program.
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run()
Just save the program above as hello.py (or something similar) and run it with your Python interpreter. Make sure to not call your application flask.py because this would conflict with Flask itself.
So what did that code do?
First we imported the Flask class. An instance of this class will be our WSGI application.
Next we create an instance of this class. The first argument is the name of the application’s module or package. If you are using a single module (as in this example), you should use __name__ because depending on if it’s started as application or imported as module the name will be different (‘__main__’ versus the actual import name). This is needed so that Flask knows where to look for templates, static files, and so on. For more information have a look at the Flask documentation.
We then use the route() decorator to tell Flask what URL should trigger our function.
The function is given a name which is also used to generate URLs for that particular function, and returns the message we want to display in the user’s browser.
Finally we use the run() function to run the local server with our application. The if __name__ == ‘__main__’: makes sure the server only runs if the script is executed directly from the Python interpreter and not used as an imported module.
To stop the server, hit control-C.
Modern web applications have beautiful URLs. This helps people remember the URLs, which is especially handy for applications that are used from mobile devices with slower network connections. If the user can directly go to the desired page without having to hit the index page it is more likely they will like the page and come back next time.
As you have seen above, the route() decorator is used to bind a function to a URL. Here are some basic examples:
@app.route('/') def index(): return 'Index Page' @app.route('/hello') def hello(): return 'Hello World'
But there is more to it! You can make certain parts of the URL dynamic and attach multiple rules to a function.
To add variable parts to a URL you can mark these special sections as
Such a part is then passed as a keyword argument to your function. Optionally a converter can be used by specifying a rule with
Here are some nice examples:
@app.route('/user/<username>') def show_user_profile(username): # show the user profile for that user return 'User %s' % username @app.route('/post/<int:post_id>') def show_post(post_id): # show the post with the given id, the id is an integer return 'Post %d' % post_id
The following converters exist:
int accepts integers
float like int but for floating point values
path like the default but also accepts slashes