diff --git a/docs/tutorial/dbcon.rst b/docs/tutorial/dbcon.rst index 2dd3d7be..179c962b 100644 --- a/docs/tutorial/dbcon.rst +++ b/docs/tutorial/dbcon.rst @@ -3,6 +3,9 @@ Step 4: Database Connections ---------------------------- +Let's continue building our code in the ``flaskr.py`` file. +(Scroll to the end of the page for more about project layout.) + You currently have a function for establishing a database connection with `connect_db`, but by itself, it is not particularly useful. Creating and closing database connections all the time is very inefficient, so you will diff --git a/docs/tutorial/dbinit.rst b/docs/tutorial/dbinit.rst index fbbcde00..484354ba 100644 --- a/docs/tutorial/dbinit.rst +++ b/docs/tutorial/dbinit.rst @@ -9,31 +9,37 @@ systems need a schema that tells them how to store that information. Before starting the server for the first time, it's important to create that schema. -Such a schema can be created by piping the ``schema.sql`` file into the -`sqlite3` command as follows:: +Such a schema could be created by piping the ``schema.sql`` file into the +``sqlite3`` command as follows:: sqlite3 /tmp/flaskr.db < schema.sql -The downside of this is that it requires the ``sqlite3`` command to be -installed, which is not necessarily the case on every system. This also -requires that you provide the path to the database, which can introduce -errors. It's a good idea to add a function that initializes the database -for you, to the application. +However, the downside of this is that it requires the ``sqlite3`` command +to be installed, which is not necessarily the case on every system. This +also requires that you provide the path to the database, which can introduce +errors. -To do this, you can create a function and hook it into a :command:`flask` -command that initializes the database. For now just take a look at the -code segment below. A good place to add this function, and command, is -just below the `connect_db` function in :file:`flaskr.py`:: +Instead of the ``sqlite3`` command above, it's a good idea to add a function +to our application that initializes the database for you. To do this, you +can create a function and hook it into a :command:`flask` command that +initializes the database. + +Take a look at the code segment below. A good place to add this function, +and command, is just below the ``connect_db`` function in :file:`flaskr.py`:: def init_db(): db = get_db() + with app.open_resource('schema.sql', mode='r') as f: db.cursor().executescript(f.read()) + db.commit() + @app.cli.command('initdb') def initdb_command(): """Initializes the database.""" + init_db() print('Initialized the database.') @@ -59,7 +65,8 @@ On that cursor, there is a method to execute a complete script. Finally, you only have to commit the changes. SQLite3 and other transactional databases will not commit unless you explicitly tell it to. -Now, it is possible to create a database with the :command:`flask` script:: +Now, in a terminal, from the application root directory :file:`flaskr/` it is +possible to create a database with the :command:`flask` script:: flask initdb Initialized the database. diff --git a/docs/tutorial/folders.rst b/docs/tutorial/folders.rst index ba62b3b7..23fefaec 100644 --- a/docs/tutorial/folders.rst +++ b/docs/tutorial/folders.rst @@ -3,8 +3,11 @@ Step 0: Creating The Folders ============================ -Before getting started, you will need to create the folders needed for this -application:: +It is recommended to install your Flask application within a virtualenv. Please +read the :ref:`installation` section to set up your environment. + +Now that you have installed Flask, you will need to create the folders required +for this tutorial. Your directory structure will look like this:: /flaskr /flaskr @@ -13,9 +16,10 @@ application:: The application will be installed and run as Python package. This is the recommended way to install and run Flask applications. You will see exactly -how to run ``flaskr`` later on in this tutorial. For now go ahead and create -the applications directory structure. In the next few steps you will be -creating the database schema as well as the main module. +how to run ``flaskr`` later on in this tutorial. + +For now go ahead and create the applications directory structure. In the next +few steps you will be creating the database schema as well as the main module. As a quick side note, the files inside of the :file:`static` folder are available to users of the application via HTTP. This is the place where CSS and diff --git a/docs/tutorial/index.rst b/docs/tutorial/index.rst index f0a583e0..7eee5fa0 100644 --- a/docs/tutorial/index.rst +++ b/docs/tutorial/index.rst @@ -3,19 +3,19 @@ Tutorial ======== -You want to develop an application with Python and Flask? Here you have -the chance to learn by example. In this tutorial, we will create a simple -microblogging application. It only supports one user that can create -text-only entries and there are no feeds or comments, but it still -features everything you need to get started. We will use Flask and SQLite -as a database (which comes out of the box with Python) so there is nothing -else you need. +Learn by example to develop an application with Python and Flask. + +In this tutorial, we will create a simple blogging application. It only +supports one user, only allows text entries, and has no feeds or comments. + +While very simple, this example still features everything you need to get +started. In addition to Flask, we will use SQLite for the database, which is +built-in to Python, so there is nothing else you need. If you want the full source code in advance or for comparison, check out the `example source`_. -.. _example source: - https://github.com/pallets/flask/tree/master/examples/flaskr/ +.. _example source: https://github.com/pallets/flask/tree/master/examples/flaskr/ .. toctree:: :maxdepth: 2 diff --git a/docs/tutorial/packaging.rst b/docs/tutorial/packaging.rst index 18f5c9b3..5db921aa 100644 --- a/docs/tutorial/packaging.rst +++ b/docs/tutorial/packaging.rst @@ -9,10 +9,10 @@ tutorial you will see exactly how to extend the ``flask`` command line interface (CLI). A useful pattern to manage a Flask application is to install your app -following the `Python Packaging Guide`_. Presently this involves -creating two new files; :file:`setup.py` and :file:`MANIFEST.in` in the -projects root directory. You also need to add an :file:`__init__.py` -file to make the :file:`flaskr/flaskr` directory a package. After these +following the `Python Packaging Guide`_. Presently this involves +creating two new files; :file:`setup.py` and :file:`MANIFEST.in` in the +projects root directory. You also need to add an :file:`__init__.py` +file to make the :file:`flaskr/flaskr` directory a package. After these changes, your code structure should be:: /flaskr @@ -25,9 +25,7 @@ changes, your code structure should be:: setup.py MANIFEST.in -The content of the ``setup.py`` file for ``flaskr`` is: - -.. sourcecode:: python +Create the ``setup.py`` file for ``flaskr`` with the following content:: from setuptools import setup @@ -43,53 +41,53 @@ The content of the ``setup.py`` file for ``flaskr`` is: When using setuptools, it is also necessary to specify any special files that should be included in your package (in the :file:`MANIFEST.in`). In this case, the static and templates directories need to be included, -as well as the schema. Create the :file:`MANIFEST.in` and add the -following lines:: +as well as the schema. + +Create the :file:`MANIFEST.in` and add the following lines:: graft flaskr/templates graft flaskr/static include flaskr/schema.sql -To simplify locating the application, add the following import statement -into this file, :file:`flaskr/__init__.py`: - -.. sourcecode:: python +Next, to simplify locating the application, create the file, +:file:`flaskr/__init__.py` containing only the following import statement:: from .flaskr import app -This import statement brings the application instance into the top-level -of the application package. When it is time to run the application, the -Flask development server needs the location of the app instance. This -import statement simplifies the location process. Without it the export -statement a few steps below would need to be +This import statement brings the application instance into the top-level +of the application package. When it is time to run the application, the +Flask development server needs the location of the app instance. This +import statement simplifies the location process. Without the above +import statement, the export statement a few steps below would need to be ``export FLASK_APP=flaskr.flaskr``. At this point you should be able to install the application. As usual, it is recommended to install your Flask application within a `virtualenv`_. -With that said, go ahead and install the application with:: +With that said, from the ``flaskr/`` directory, go ahead and install the +application with:: pip install --editable . -The above installation command assumes that it is run within the projects -root directory, `flaskr/`. The `editable` flag allows editing -source code without having to reinstall the Flask app each time you make -changes. The flaskr app is now installed in your virtualenv (see output +The above installation command assumes that it is run within the projects +root directory, ``flaskr/``. The ``editable`` flag allows editing +source code without having to reinstall the Flask app each time you make +changes. The flaskr app is now installed in your virtualenv (see output of ``pip freeze``). With that out of the way, you should be able to start up the application. -Do this with the following commands:: +Do this on Mac or Linux with the following commands in ``flaskr/``:: export FLASK_APP=flaskr export FLASK_DEBUG=true flask run -(In case you are on Windows you need to use `set` instead of `export`). +(In case you are on Windows you need to use ``set`` instead of ``export``). The :envvar:`FLASK_DEBUG` flag enables or disables the interactive debugger. *Never leave debug mode activated in a production system*, because it will allow users to execute code on the server! You will see a message telling you that server has started along with -the address at which you can access it. +the address at which you can access it in a browser. When you head over to the server in your browser, you will get a 404 error because we don't have any views yet. That will be addressed a little later, diff --git a/docs/tutorial/setup.rst b/docs/tutorial/setup.rst index 4bedb54c..81309e65 100644 --- a/docs/tutorial/setup.rst +++ b/docs/tutorial/setup.rst @@ -3,27 +3,31 @@ Step 2: Application Setup Code ============================== -Now that the schema is in place, you can create the application module, -:file:`flaskr.py`. This file should be placed inside of the -:file:`flaskr/flaskr` folder. The first several lines of code in the -application module are the needed import statements. After that there will be a -few lines of configuration code. For small applications like ``flaskr``, it is -possible to drop the configuration directly into the module. However, a cleaner -solution is to create a separate ``.ini`` or ``.py`` file, load that, and -import the values from there. +Next, we will create the application module, :file:`flaskr.py`. Just like the +:file:`schema.sql` file you created in the previous step, this file should be +placed inside of the :file:`flaskr/flaskr` folder. + +For this tutorial, all the Python code we use will be put into this file +(except for one line in ``__init__.py``, and any testing or optional files you +decide to create). + +The first several lines of code in the application module are the needed import +statements. After that there will be a few lines of configuration code. + +For small applications like ``flaskr``, it is possible to drop the configuration +directly into the module. However, a cleaner solution is to create a separate +``.py`` file, load that, and import the values from there. Here are the import statements (in :file:`flaskr.py`):: - # all the imports import os import sqlite3 - from flask import Flask, request, session, g, redirect, url_for, abort, \ - render_template, flash -The next couple lines will create the actual application instance and -initialize it with the config from the same file in :file:`flaskr.py`: + from flask import (Flask, request, session, g, redirect, url_for, abort, + render_template, flash) -.. sourcecode:: python +The next couple lines will create the actual application instance and +initialize it with the config from the same file in :file:`flaskr.py`:: app = Flask(__name__) # create the application instance :) app.config.from_object(__name__) # load config from this file , flaskr.py @@ -37,8 +41,8 @@ initialize it with the config from the same file in :file:`flaskr.py`: )) app.config.from_envvar('FLASKR_SETTINGS', silent=True) -The :class:`~flask.Config` object works similarly to a dictionary, so it can be -updated with new values. +In the above code, the :class:`~flask.Config` object works similarly to a +dictionary, so it can be updated with new values. .. admonition:: Database Path @@ -58,15 +62,15 @@ updated with new values. Usually, it is a good idea to load a separate, environment-specific configuration file. Flask allows you to import multiple configurations and it will use the setting defined in the last import. This enables robust -configuration setups. :meth:`~flask.Config.from_envvar` can help achieve this. - -.. sourcecode:: python +configuration setups. :meth:`~flask.Config.from_envvar` can help achieve +this. :: app.config.from_envvar('FLASKR_SETTINGS', silent=True) -Simply define the environment variable :envvar:`FLASKR_SETTINGS` that points to -a config file to be loaded. The silent switch just tells Flask to not complain -if no such environment key is set. +If you want to do this (not required for this tutorial) simply define the +environment variable :envvar:`FLASKR_SETTINGS` that points to a config file +to be loaded. The silent switch just tells Flask to not complain if no such +environment key is set. In addition to that, you can use the :meth:`~flask.Config.from_object` method on the config object and provide it with an import name of a @@ -76,22 +80,22 @@ that in all cases, only variable names that are uppercase are considered. The ``SECRET_KEY`` is needed to keep the client-side sessions secure. Choose that key wisely and as hard to guess and complex as possible. -Lastly, you will add a method that allows for easy connections to the -specified database. This can be used to open a connection on request and -also from the interactive Python shell or a script. This will come in -handy later. You can create a simple database connection through SQLite and -then tell it to use the :class:`sqlite3.Row` object to represent rows. -This allows the rows to be treated as if they were dictionaries instead of -tuples. - -.. sourcecode:: python +Lastly, add a method that allows for easy connections to the specified +database. :: def connect_db(): """Connects to the specific database.""" + rv = sqlite3.connect(app.config['DATABASE']) rv.row_factory = sqlite3.Row return rv +This can be used to open a connection on request and also from the +interactive Python shell or a script. This will come in handy later. +You can create a simple database connection through SQLite and then tell +it to use the :class:`sqlite3.Row` object to represent rows. This allows +the rows to be treated as if they were dictionaries instead of tuples. + In the next section you will see how to run the application. Continue with :ref:`tutorial-packaging`. diff --git a/docs/tutorial/templates.rst b/docs/tutorial/templates.rst index 4f7977e8..12a555e7 100644 --- a/docs/tutorial/templates.rst +++ b/docs/tutorial/templates.rst @@ -15,7 +15,8 @@ escaped with their XML equivalents. We are also using template inheritance which makes it possible to reuse the layout of the website in all pages. -Put the following templates into the :file:`templates` folder: +Create the follwing three HTML files and place them in the +:file:`templates` folder: .. _Jinja2: http://jinja.pocoo.org/docs/templates diff --git a/docs/tutorial/views.rst b/docs/tutorial/views.rst index 4364d973..1b09fcb8 100644 --- a/docs/tutorial/views.rst +++ b/docs/tutorial/views.rst @@ -4,7 +4,8 @@ Step 6: The View Functions ========================== Now that the database connections are working, you can start writing the -view functions. You will need four of them: +view functions. You will need four of them; Show Entries, Add New Entry, +Login and Logout. Add the following code snipets to :file:`flaskr.py`. Show Entries ------------