<commit_before>.. _tutorials:

Tutorials
---------


This tutorial will walk you through basic but complete CherryPy applications
that will show you common concepts as well as slightly more adavanced ones.

.. contents::
   :depth:  4

Tutorial 1: A basic web application
###################################

The following example demonstrates the most basic application
you could write with CherryPy. It starts a server and hosts
an application that will be served at request reaching
http://127.0.0.1:8080/

.. code-block:: python
   :linenos:

   import cherrypy

   class HelloWorld(object):
       @cherrypy.expose
       def index(self):
	   return "Hello world!"

   if __name__ == '__main__':
      cherrypy.quickstart(HelloWorld())

Store this code snippet into a file named `tut01.py` and
execute it as follows:

.. code-block:: bash

   $ python tut01.py

This will display something along the following:

.. code-block:: text
   :linenos:

   [24/Feb/2014:21:01:46] ENGINE Listening for SIGHUP.
   [24/Feb/2014:21:01:46] ENGINE Listening for SIGTERM.
   [24/Feb/2014:21:01:46] ENGINE Listening for SIGUSR1.
   [24/Feb/2014:21:01:46] ENGINE Bus STARTING
   CherryPy Checker:
   The Application mounted at '' has an empty config.
   
   [24/Feb/2014:21:01:46] ENGINE Started monitor thread 'Autoreloader'.
   [24/Feb/2014:21:01:46] ENGINE Started monitor thread '_TimeoutMonitor'.
   [24/Feb/2014:21:01:46] ENGINE Serving on http://127.0.0.1:8080
   [24/Feb/2014:21:01:46] ENGINE Bus STARTED

This tells you several things. The first three lines indicate
the server will handle :mod:`signal` for you. The next line tells you 
the current state of the server, as that
point it is in `STARTING` stage. Then, you are notified your
application has no specific configuration set to it.
Next, the server starts a couple of internal utilities that
we will explain later. Finally, the server indicates it is now
ready to accept incoming communications as it listens on
the address `127.0.0.1:8080`. In other words, at that stage your
application is ready to be used.

Before moving on, let's discuss the message
regarding the lack of configuration. By default, CherryPy has
a feature which will review the syntax correctness of settings
you could provide to configure the application. When none are
provided, a warning message is thus displayed in the logs. That
log is harmless and will not prevent CherryPy from working. You
can refer to :ref:`the documentation above <perappconf>` to
understand how to set the configuration.

Tutorial 2: Different URLs lead to different functions
######################################################

Your applications will obviously handle more than a single URL. 
Let's imagine you have an application that generates a random 
string each time it is called:

.. code-block:: python
   :linenos:

   import random
   import string
   
   import cherrypy

   class StringGenerator(object):
       @cherrypy.expose
       def index(self):
	   return "Hello world!"

       @cherrypy.expose
       def generate(self):
           return ''.join(random.sample(string.hexdigits, 8))
    
   if __name__ == '__main__':
       cherrypy.quickstart(StringGenerator())

Save this into a file named `tut02.py` and run it as follows:

.. code-block:: bash

   $ python tut02.py

Go now to http://localhost:8080/generate and your browser
will display a random string. 

Let's take a minute to decompose what's happening here. This is the
URL that you have typed into your browser: http://localhost:8080/generate

This URL contains various parts:

- `http://` which roughly indicates it's a URL using the HTTP protocol (see :rfc:`2616`).
- `localhost:8080` is the server's address. It's made of a hostname and a port.
- `/generate` which is the path segment of the URL. This is what CherryPy uses to
  locate an :term:`exposed` function or method to respond.

Here CherryPy uses the `index()` method to handle `/` and the
`generate()` method to handle `/generate`

.. _tut03:

Tutorial 3: My URLs have parameters
###################################

In the previous tutorial, we have seen how to create an application
that could generate a random string. Let's not assume you wish
to indicate the length of that string dynamically.

.. code-block:: python
   :linenos:

   import random
   import string
   
   import cherrypy

   class StringGenerator(object):
       @cherrypy.expose
       def index(self):
	   return "Hello world!"

       @cherrypy.expose
       def generate(self, length=8):
           return ''.join(random.sample(string.hexdigits, int(length)))
    
   if __name__ == '__main__':
       cherrypy.quickstart(StringGenerator())

Save this into a file named `tut03.py` and run it as follows:

.. code-block:: bash

   $ python tut03.py

Go now to http://localhost:8080/generate?length=16 and your browser
will display a generated string of length 16. Notice how
we benefit from Python's default arguments' values to support 
URLs such as http://localhost:8080/password still.<commit_msg>Tutorial 3: replaced "/password" by "/generate", I think that's what it was meant .<commit_after>.. _tutorials:

Tutorials
---------


This tutorial will walk you through basic but complete CherryPy applications
that will show you common concepts as well as slightly more adavanced ones.

.. contents::
   :depth:  4

Tutorial 1: A basic web application
###################################

The following example demonstrates the most basic application
you could write with CherryPy. It starts a server and hosts
an application that will be served at request reaching
http://127.0.0.1:8080/

.. code-block:: python
   :linenos:

   import cherrypy

   class HelloWorld(object):
       @cherrypy.expose
       def index(self):
	   return "Hello world!"

   if __name__ == '__main__':
      cherrypy.quickstart(HelloWorld())

Store this code snippet into a file named `tut01.py` and
execute it as follows:

.. code-block:: bash

   $ python tut01.py

This will display something along the following:

.. code-block:: text
   :linenos:

   [24/Feb/2014:21:01:46] ENGINE Listening for SIGHUP.
   [24/Feb/2014:21:01:46] ENGINE Listening for SIGTERM.
   [24/Feb/2014:21:01:46] ENGINE Listening for SIGUSR1.
   [24/Feb/2014:21:01:46] ENGINE Bus STARTING
   CherryPy Checker:
   The Application mounted at '' has an empty config.
   
   [24/Feb/2014:21:01:46] ENGINE Started monitor thread 'Autoreloader'.
   [24/Feb/2014:21:01:46] ENGINE Started monitor thread '_TimeoutMonitor'.
   [24/Feb/2014:21:01:46] ENGINE Serving on http://127.0.0.1:8080
   [24/Feb/2014:21:01:46] ENGINE Bus STARTED

This tells you several things. The first three lines indicate
the server will handle :mod:`signal` for you. The next line tells you 
the current state of the server, as that
point it is in `STARTING` stage. Then, you are notified your
application has no specific configuration set to it.
Next, the server starts a couple of internal utilities that
we will explain later. Finally, the server indicates it is now
ready to accept incoming communications as it listens on
the address `127.0.0.1:8080`. In other words, at that stage your
application is ready to be used.

Before moving on, let's discuss the message
regarding the lack of configuration. By default, CherryPy has
a feature which will review the syntax correctness of settings
you could provide to configure the application. When none are
provided, a warning message is thus displayed in the logs. That
log is harmless and will not prevent CherryPy from working. You
can refer to :ref:`the documentation above <perappconf>` to
understand how to set the configuration.

Tutorial 2: Different URLs lead to different functions
######################################################

Your applications will obviously handle more than a single URL. 
Let's imagine you have an application that generates a random 
string each time it is called:

.. code-block:: python
   :linenos:

   import random
   import string
   
   import cherrypy

   class StringGenerator(object):
       @cherrypy.expose
       def index(self):
	   return "Hello world!"

       @cherrypy.expose
       def generate(self):
           return ''.join(random.sample(string.hexdigits, 8))
    
   if __name__ == '__main__':
       cherrypy.quickstart(StringGenerator())

Save this into a file named `tut02.py` and run it as follows:

.. code-block:: bash

   $ python tut02.py

Go now to http://localhost:8080/generate and your browser
will display a random string. 

Let's take a minute to decompose what's happening here. This is the
URL that you have typed into your browser: http://localhost:8080/generate

This URL contains various parts:

- `http://` which roughly indicates it's a URL using the HTTP protocol (see :rfc:`2616`).
- `localhost:8080` is the server's address. It's made of a hostname and a port.
- `/generate` which is the path segment of the URL. This is what CherryPy uses to
  locate an :term:`exposed` function or method to respond.

Here CherryPy uses the `index()` method to handle `/` and the
`generate()` method to handle `/generate`

.. _tut03:

Tutorial 3: My URLs have parameters
###################################

In the previous tutorial, we have seen how to create an application
that could generate a random string. Let's not assume you wish
to indicate the length of that string dynamically.

.. code-block:: python
   :linenos:

   import random
   import string
   
   import cherrypy

   class StringGenerator(object):
       @cherrypy.expose
       def index(self):
	   return "Hello world!"

       @cherrypy.expose
       def generate(self, length=8):
           return ''.join(random.sample(string.hexdigits, int(length)))
    
   if __name__ == '__main__':
       cherrypy.quickstart(StringGenerator())

Save this into a file named `tut03.py` and run it as follows:

.. code-block:: bash

   $ python tut03.py

Go now to http://localhost:8080/generate?length=16 and your browser
will display a generated string of length 16. Notice how
we benefit from Python's default arguments' values to support 
URLs such as http://localhost:8080/generate still.
{'fraction_non_alphanumeric': 0.10352987576414908, 'fraction_numerical': 0.034608558469729836, 'mean_word_length': 3.702364394993046, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 6, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6093799', 'n_tokens_mistral': 3177, 'n_tokens_neox': 2797, 'n_words': 1250}