├── .gitattributes ├── .gitignore ├── LICENSE ├── Module 1 ├── Chapter01 │ ├── hello.conf │ ├── hello.py │ └── hello.wsgi ├── Chapter02 │ ├── headlines.conf │ ├── headlines.py │ └── headlines.wsgi ├── Chapter03 │ ├── headlines.py │ └── templates │ │ └── home.html ├── Chapter04 │ ├── headlines.py │ └── templates │ │ └── home.html ├── Chapter05 │ ├── headlines.py │ └── templates │ │ └── home.html ├── Chapter06 │ ├── crimemap.py │ ├── crimemap.wsgi │ ├── db_setup.py │ ├── dbconfig.py │ ├── dbhelper.py │ ├── misc │ │ └── crimemap.conf │ └── templates │ │ └── home.html ├── Chapter07 │ ├── crimemap.py │ ├── db_setup.py │ ├── dbconfig.py │ ├── dbhelper.py │ ├── misc │ │ ├── crimemap.conf │ │ └── crimemap.wsgi │ ├── mockdbhelper.py │ ├── static │ │ └── css │ │ │ └── style.css │ └── templates │ │ └── home.html ├── Chapter08 │ ├── crimemap.py │ ├── db_setup.py │ ├── dbconfig.py │ ├── dbhelper.py │ ├── misc │ │ ├── crimemap.conf │ │ └── crimemap.wsgi │ ├── mockdbhelper.py │ ├── static │ │ └── css │ │ │ └── style.css │ └── templates │ │ └── home.html ├── Chapter09 │ ├── config.py │ ├── mockdbhelper.py │ ├── passwordhelper.py │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ ├── templates │ │ └── home.html │ ├── user.py │ ├── waitercaller.py │ └── waitercaller.wsgi ├── Chapter10 │ ├── bitlyhelper.py │ ├── config.py │ ├── forms.py │ ├── mockbitlyhelper.py │ ├── mockdbhelper.py │ ├── passwordhelper.py │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ ├── templates │ │ ├── account.html │ │ ├── base.html │ │ ├── dashboard.html │ │ ├── home.html │ │ └── home_1.html │ ├── user.py │ ├── waitercaller.py │ └── waitercaller.wsgi ├── Chapter11 │ ├── .gitignore │ ├── bitlyhelper.py │ ├── create_mongo_indices.py │ ├── dbhelper.py │ ├── forms.py │ ├── mockbitlyhelper.py │ ├── mockdbhelper.py │ ├── passwordhelper.py │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── favicon.ico │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ ├── templates │ │ ├── account.html │ │ ├── base.html │ │ ├── dashboard.html │ │ └── home.html │ ├── user.py │ ├── waitercaller.py │ └── waitercaller.wsgi ├── ReadMe.txt └── Software Hardware List.docx ├── Module 2 ├── Chapter01 │ ├── app.py │ ├── my_app │ │ ├── __init__.py │ │ └── hello │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ ├── run.py │ └── setup.py ├── Chapter02 │ ├── my_app │ │ ├── __init__.py │ │ ├── product │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ └── js │ │ │ │ └── bootstrap.min.js │ │ └── templates │ │ │ ├── base.html │ │ │ ├── home.html │ │ │ └── product.html │ ├── run.py │ └── setup.py ├── Chapter03 │ ├── migrations │ │ ├── README │ │ ├── alembic.ini │ │ ├── env.py │ │ ├── env.pyc │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── 538264df91d2_.py │ │ │ └── 538264df91d2_.pyc │ ├── my_app │ │ ├── __init__.py │ │ └── catalog │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ └── run.py ├── Chapter04 │ ├── my_app │ │ ├── __init__.py │ │ ├── catalog │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ └── js │ │ │ │ └── bootstrap.min.js │ │ └── templates │ │ │ ├── 404.html │ │ │ ├── base.html │ │ │ ├── categories.html │ │ │ ├── category.html │ │ │ ├── home.html │ │ │ ├── product-create.html │ │ │ ├── product.html │ │ │ └── products.html │ └── run.py ├── Chapter05 │ ├── my_app │ │ ├── __init__.py │ │ ├── catalog │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ ├── js │ │ │ │ └── bootstrap.min.js │ │ │ └── uploads │ │ │ │ └── apple-iphone-5-front.jpg │ │ └── templates │ │ │ ├── 404.html │ │ │ ├── base.html │ │ │ ├── categories.html │ │ │ ├── category-create.html │ │ │ ├── category.html │ │ │ ├── home.html │ │ │ ├── product-create.html │ │ │ ├── product.html │ │ │ └── products.html │ └── run.py ├── Chapter06 │ ├── my_app │ │ ├── __init__.py │ │ ├── auth │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ └── js │ │ │ │ └── bootstrap.min.js │ │ └── templates │ │ │ ├── base.html │ │ │ ├── home.html │ │ │ ├── login.html │ │ │ └── register.html │ └── run.py ├── Chapter07 │ ├── my_app │ │ ├── __init__.py │ │ ├── catalog │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ └── js │ │ │ │ └── bootstrap.min.js │ │ └── templates │ │ │ ├── 404.html │ │ │ ├── base.html │ │ │ ├── categories.html │ │ │ ├── category.html │ │ │ ├── home.html │ │ │ ├── product-create.html │ │ │ ├── product.html │ │ │ └── products.html │ └── run.py ├── Chapter08 │ ├── my_app │ │ ├── __init__.py │ │ ├── auth │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ └── js │ │ │ │ └── bootstrap.min.js │ │ └── templates │ │ │ ├── admin-home.html │ │ │ ├── base.html │ │ │ ├── edit.html │ │ │ ├── home.html │ │ │ ├── login.html │ │ │ ├── register.html │ │ │ ├── some-template.html │ │ │ ├── user-create-admin.html │ │ │ ├── user-update-admin.html │ │ │ └── users-list-admin.html │ └── run.py ├── Chapter09 │ ├── my_app │ │ ├── __init__.py │ │ ├── babel.cfg │ │ ├── catalog │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── messages.pot │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ ├── js │ │ │ │ └── bootstrap.min.js │ │ │ └── uploads │ │ │ │ └── apple-iphone-5-front.jpg │ │ ├── templates │ │ │ ├── 404.html │ │ │ ├── base.html │ │ │ ├── categories.html │ │ │ ├── category-create.html │ │ │ ├── category.html │ │ │ ├── home.html │ │ │ ├── product-create.html │ │ │ ├── product.html │ │ │ └── products.html │ │ └── translations │ │ │ └── fr │ │ │ └── LC_MESSAGES │ │ │ ├── messages.mo │ │ │ └── messages.po │ └── run.py ├── Chapter10 │ ├── app_tests.py │ ├── application.log │ ├── coverage │ │ ├── coverage_html.js │ │ ├── index.html │ │ ├── jquery.hotkeys.js │ │ ├── jquery.isonscreen.js │ │ ├── jquery.min.js │ │ ├── jquery.tablesorter.min.js │ │ ├── keybd_closed.png │ │ ├── keybd_open.png │ │ ├── my_app_catalog_models.html │ │ ├── my_app_catalog_views.html │ │ ├── status.dat │ │ └── style.css │ ├── generate_profile.py │ ├── htmlcov │ │ ├── coverage_html.js │ │ ├── index.html │ │ ├── jquery.hotkeys.js │ │ ├── jquery.isonscreen.js │ │ ├── jquery.min.js │ │ ├── jquery.tablesorter.min.js │ │ ├── keybd_closed.png │ │ ├── keybd_open.png │ │ ├── my_app___init__.html │ │ ├── my_app_catalog___init__.html │ │ ├── my_app_catalog_models.html │ │ ├── my_app_catalog_views.html │ │ ├── status.dat │ │ └── style.css │ ├── my_app │ │ ├── __init__.py │ │ ├── babel.cfg │ │ ├── catalog │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── messages.pot │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ ├── js │ │ │ │ └── bootstrap.min.js │ │ │ └── uploads │ │ │ │ └── apple-iphone-5-front.jpg │ │ ├── templates │ │ │ ├── 404.html │ │ │ ├── base.html │ │ │ ├── categories.html │ │ │ ├── category-create.html │ │ │ ├── category.html │ │ │ ├── home.html │ │ │ ├── product-create.html │ │ │ ├── product.html │ │ │ └── products.html │ │ └── translations │ │ │ └── fr │ │ │ └── LC_MESSAGES │ │ │ ├── messages.mo │ │ │ └── messages.po │ └── run.py ├── Chapter11 │ ├── MANIFEST.in │ ├── Procfile │ ├── apache_wsgi.conf │ ├── app.wsgi │ ├── app_tests.py │ ├── application.log │ ├── application.py │ ├── coverage │ │ ├── coverage_html.js │ │ ├── index.html │ │ ├── jquery.hotkeys.js │ │ ├── jquery.isonscreen.js │ │ ├── jquery.min.js │ │ ├── jquery.tablesorter.min.js │ │ ├── keybd_closed.png │ │ ├── keybd_open.png │ │ ├── my_app_catalog_models.html │ │ ├── my_app_catalog_views.html │ │ ├── status.dat │ │ └── style.css │ ├── fabfile.py │ ├── generate_profile.py │ ├── htmlcov │ │ ├── coverage_html.js │ │ ├── index.html │ │ ├── jquery.hotkeys.js │ │ ├── jquery.isonscreen.js │ │ ├── jquery.min.js │ │ ├── jquery.tablesorter.min.js │ │ ├── keybd_closed.png │ │ ├── keybd_open.png │ │ ├── my_app___init__.html │ │ ├── my_app_catalog___init__.html │ │ ├── my_app_catalog_models.html │ │ ├── my_app_catalog_views.html │ │ ├── status.dat │ │ └── style.css │ ├── my_app │ │ ├── __init__.py │ │ ├── babel.cfg │ │ ├── catalog │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ └── views.py │ │ ├── messages.pot │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── main.css │ │ │ ├── js │ │ │ │ └── bootstrap.min.js │ │ │ └── uploads │ │ │ │ └── apple-iphone-5-front.jpg │ │ ├── templates │ │ │ ├── 404.html │ │ │ ├── base.html │ │ │ ├── categories.html │ │ │ ├── category-create.html │ │ │ ├── category.html │ │ │ ├── home.html │ │ │ ├── product-create.html │ │ │ ├── product.html │ │ │ └── products.html │ │ └── translations │ │ │ └── fr │ │ │ └── LC_MESSAGES │ │ │ ├── messages.mo │ │ │ └── messages.po │ ├── newrelic.ini │ ├── nginx-wsgi.conf │ ├── requirements.txt │ ├── run.py │ ├── setup.py │ ├── tornado_server.py │ └── uwsgi.ini └── Chapter12 │ ├── my_app │ ├── __init__.py │ ├── catalog │ │ ├── __init__.py │ │ ├── models.py │ │ └── views.py │ ├── static │ │ ├── css │ │ │ ├── bootstrap.min.css │ │ │ └── main.css │ │ └── js │ │ │ └── bootstrap.min.js │ └── templates │ │ ├── 404.html │ │ ├── base.html │ │ ├── categories.html │ │ ├── category-create-email-html.html │ │ ├── category-create-email-text.html │ │ ├── category.html │ │ ├── home.html │ │ ├── product-create.html │ │ ├── product.html │ │ └── products.html │ └── run.py ├── Module 3 ├── Chapter01 │ └── chapter_1 │ │ ├── config.py │ │ ├── main.py │ │ └── manage.py ├── Chapter02 │ └── chapter_2 │ │ ├── config.py │ │ ├── main.py │ │ ├── manage.py │ │ └── migrations │ │ ├── README │ │ ├── alembic.ini │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ └── 7ded34bc4fb_.py ├── Chapter03 │ └── chapter_3 │ │ ├── config.py │ │ ├── main.py │ │ ├── manage.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ └── templates │ │ ├── base.html │ │ ├── home.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html ├── Chapter04 │ └── chapter_4 │ │ ├── config.py │ │ ├── main.py │ │ ├── manage.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ └── templates │ │ └── blog │ │ ├── base.html │ │ ├── home.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html ├── Chapter05 │ └── chapter_5 │ │ ├── manage.py │ │ └── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ ├── __init__.py │ │ ├── blog.py │ │ └── main.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ └── templates │ │ └── blog │ │ ├── base.html │ │ ├── home.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html ├── Chapter06 │ └── Chapter 6 │ │ └── chapter_6 │ │ ├── manage.py │ │ └── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ ├── __init__.py │ │ ├── blog.py │ │ └── main.py │ │ ├── extensions.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ └── templates │ │ ├── blog │ │ ├── base.html │ │ ├── edit.html │ │ ├── home.html │ │ ├── new.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html │ │ └── main │ │ ├── base.html │ │ ├── login.html │ │ └── register.html ├── Chapter07 │ └── chapter_7 │ │ ├── manage.py │ │ ├── requirements.txt │ │ └── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ ├── __init__.py │ │ ├── blog.py │ │ └── main.py │ │ ├── extensions.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── formbuilder-min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ └── vendor │ │ │ ├── bootstrap.js │ │ │ └── bootstrap.min.js │ │ └── templates │ │ ├── blog │ │ ├── base.html │ │ ├── edit.html │ │ ├── home.html │ │ ├── new.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html │ │ └── main │ │ ├── base.html │ │ ├── login.html │ │ └── register.html ├── Chapter08 │ └── chapter_8 │ │ ├── manage.py │ │ └── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ ├── __init__.py │ │ ├── blog.py │ │ ├── main.py │ │ └── rest │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── fields.py │ │ │ ├── parsers.py │ │ │ └── post.py │ │ ├── extensions.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ └── templates │ │ ├── blog │ │ ├── base.html │ │ ├── edit.html │ │ ├── home.html │ │ ├── new.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html │ │ └── main │ │ ├── base.html │ │ ├── login.html │ │ └── register.html ├── Chapter09 │ └── chapter_9 │ │ ├── celery_runner.py │ │ ├── manage.py │ │ └── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ ├── __init__.py │ │ ├── blog.py │ │ ├── main.py │ │ └── rest │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── fields.py │ │ │ ├── parsers.py │ │ │ └── post.py │ │ ├── extensions.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ ├── tasks.py │ │ └── templates │ │ ├── blog │ │ ├── base.html │ │ ├── edit.html │ │ ├── home.html │ │ ├── new.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html │ │ ├── digest.html │ │ └── main │ │ ├── base.html │ │ ├── login.html │ │ └── register.html ├── Chapter10 │ └── Chapter 10 │ │ ├── celery_runner.py │ │ ├── manage.py │ │ └── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── blog.py │ │ ├── main.py │ │ └── rest │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── fields.py │ │ │ ├── parsers.py │ │ │ └── post.py │ │ ├── extensions.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── jquery.js │ │ ├── tasks.py │ │ └── templates │ │ ├── admin │ │ ├── custom.html │ │ ├── post_edit.html │ │ └── second_page.html │ │ ├── blog │ │ ├── base.html │ │ ├── edit.html │ │ ├── home.html │ │ ├── new.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html │ │ ├── digest.html │ │ └── main │ │ ├── base.html │ │ ├── login.html │ │ └── register.html ├── Chapter11 │ └── Chapter 11 │ │ ├── Flask-YouTube │ │ ├── Flask_YouTube.egg-info │ │ │ ├── PKG-INFO │ │ │ ├── SOURCES.txt │ │ │ ├── dependency_links.txt │ │ │ ├── requires.txt │ │ │ └── top_level.txt │ │ ├── build │ │ │ └── lib │ │ │ │ └── flask_youtube │ │ │ │ └── __init__.py │ │ ├── dist │ │ │ └── Flask_YouTube-0.1-py2.7.egg │ │ ├── flask_youtube │ │ │ ├── __init__.py │ │ │ └── templates │ │ │ │ └── youtube │ │ │ │ └── video.html │ │ └── setup.py │ │ ├── celery_runner.py │ │ ├── manage.py │ │ └── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── blog.py │ │ ├── main.py │ │ └── rest │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── fields.py │ │ │ ├── parsers.py │ │ │ └── post.py │ │ ├── extensions.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── jquery.js │ │ ├── tasks.py │ │ └── templates │ │ ├── admin │ │ ├── custom.html │ │ ├── post_edit.html │ │ └── second_page.html │ │ ├── blog │ │ ├── base.html │ │ ├── edit.html │ │ ├── home.html │ │ ├── new.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html │ │ ├── digest.html │ │ ├── main │ │ ├── base.html │ │ ├── login.html │ │ └── register.html │ │ └── youtube │ │ └── video.html ├── Chapter12 │ └── chapter_12 │ │ ├── .coverage │ │ ├── Flask-GZip │ │ ├── flask_gzip │ │ │ └── __init__.py │ │ └── setup.py │ │ ├── Flask-YouTube │ │ ├── Flask_YouTube.egg-info │ │ │ ├── PKG-INFO │ │ │ ├── SOURCES.txt │ │ │ ├── dependency_links.txt │ │ │ ├── requires.txt │ │ │ └── top_level.txt │ │ ├── build │ │ │ └── lib │ │ │ │ └── flask_youtube │ │ │ │ └── __init__.py │ │ ├── dist │ │ │ └── Flask_YouTube-0.1-py2.7.egg │ │ ├── flask_youtube │ │ │ ├── __init__.py │ │ │ └── templates │ │ │ │ └── youtube │ │ │ │ └── video.html │ │ └── setup.py │ │ ├── celery_runner.py │ │ ├── manage.py │ │ ├── run_test_server.py │ │ ├── tests │ │ ├── __init__.py │ │ ├── test_ui.py │ │ └── test_urls.py │ │ └── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── blog.py │ │ ├── main.py │ │ └── rest │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── fields.py │ │ │ ├── parsers.py │ │ │ └── post.py │ │ ├── extensions.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ ├── .webassets-cache │ │ │ ├── 49d7031c832760f1c8af0e8f1f9a1954 │ │ │ ├── 592e4efb9c5f8cd91720dd6d646679e7 │ │ │ ├── 593c7cdfba4d0c04f3e56780333b67bb │ │ │ ├── 677b6b8fc43f52ebf6307be93396d33b │ │ │ ├── cc4f5a625c710457f3da55054fb81d39 │ │ │ └── efe2845331acfbfa19510a0d780942a5 │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── common.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ ├── common.js │ │ │ └── jquery.js │ │ ├── tasks.py │ │ └── templates │ │ ├── admin │ │ ├── custom.html │ │ ├── post_edit.html │ │ └── second_page.html │ │ ├── blog │ │ ├── base.html │ │ ├── edit.html │ │ ├── home.html │ │ ├── new.html │ │ ├── post.html │ │ ├── tag.html │ │ └── user.html │ │ ├── digest.html │ │ └── main │ │ ├── base.html │ │ ├── login.html │ │ └── register.html ├── Chapter13 │ └── Chapter 13 │ │ ├── .gitignore │ │ ├── Flask-GZip │ │ ├── flask_gzip │ │ │ └── __init__.py │ │ └── setup.py │ │ ├── Flask-YouTube │ │ ├── Flask_YouTube.egg-info │ │ │ ├── PKG-INFO │ │ │ ├── SOURCES.txt │ │ │ ├── dependency_links.txt │ │ │ ├── requires.txt │ │ │ └── top_level.txt │ │ ├── build │ │ │ └── lib │ │ │ │ └── flask_youtube │ │ │ │ └── __init__.py │ │ ├── dist │ │ │ └── Flask_YouTube-0.1-py2.7.egg │ │ ├── flask_youtube │ │ │ ├── __init__.py │ │ │ └── templates │ │ │ │ └── youtube │ │ │ │ └── video.html │ │ └── setup.py │ │ ├── Procfile │ │ ├── application.py │ │ ├── celery_runner.py │ │ ├── fabfile.py │ │ ├── gserver.py │ │ ├── manage.py │ │ ├── nginx.conf │ │ ├── requirements.txt │ │ ├── run_test_server.py │ │ ├── runtime.txt │ │ ├── supervisor.conf │ │ ├── tests │ │ ├── __init__.py │ │ ├── test_ui.py │ │ └── test_urls.py │ │ ├── tserver.py │ │ ├── uwsgi.ini │ │ ├── webapp │ │ ├── __init__.py │ │ ├── config.py │ │ ├── controllers │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ ├── blog.py │ │ │ ├── main.py │ │ │ └── rest │ │ │ │ ├── __init__.py │ │ │ │ ├── auth.py │ │ │ │ ├── fields.py │ │ │ │ ├── parsers.py │ │ │ │ └── post.py │ │ ├── extensions.py │ │ ├── forms.py │ │ ├── models.py │ │ ├── static │ │ │ ├── .webassets-cache │ │ │ │ ├── 49d7031c832760f1c8af0e8f1f9a1954 │ │ │ │ ├── 592e4efb9c5f8cd91720dd6d646679e7 │ │ │ │ ├── 593c7cdfba4d0c04f3e56780333b67bb │ │ │ │ ├── 677b6b8fc43f52ebf6307be93396d33b │ │ │ │ ├── cc4f5a625c710457f3da55054fb81d39 │ │ │ │ └── efe2845331acfbfa19510a0d780942a5 │ │ │ ├── css │ │ │ │ ├── bootstrap-theme.css │ │ │ │ ├── bootstrap-theme.css.map │ │ │ │ ├── bootstrap-theme.min.css │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── common.css │ │ │ ├── fonts │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ └── js │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.min.js │ │ │ │ ├── common.js │ │ │ │ └── jquery.js │ │ ├── tasks.py │ │ └── templates │ │ │ ├── admin │ │ │ ├── custom.html │ │ │ ├── post_edit.html │ │ │ └── second_page.html │ │ │ ├── blog │ │ │ ├── base.html │ │ │ ├── edit.html │ │ │ ├── home.html │ │ │ ├── new.html │ │ │ ├── post.html │ │ │ ├── tag.html │ │ │ └── user.html │ │ │ ├── digest.html │ │ │ └── main │ │ │ ├── base.html │ │ │ ├── login.html │ │ │ └── register.html │ │ └── wsgi.py └── Software Hardware List.docx ├── Readme.md └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Module 1/Chapter01/hello.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerName example.com 3 | 4 | WSGIScriptAlias / /var/www/firstapp/hello.wsgi 5 | WSGIDaemonProcess hello 6 | 7 | WSGIProcessGroup hello 8 | WSGIApplicationGroup %{GLOBAL} 9 | Order deny,allow 10 | Allow from all 11 | 12 | 13 | -------------------------------------------------------------------------------- /Module 1/Chapter01/hello.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | 3 | app = Flask(__name__) 4 | 5 | 6 | @app.route("/") 7 | def index(): 8 | return "Hello, World!" 9 | 10 | 11 | if __name__ == '__main__': 12 | app.run(port=5000, debug=True) -------------------------------------------------------------------------------- /Module 1/Chapter01/hello.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "/var/www/firstapp") 3 | from hello import app as application 4 | -------------------------------------------------------------------------------- /Module 1/Chapter02/headlines.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerName example.com 3 | 4 | WSGIScriptAlias / /var/www/headlines/headlines.wsgi 5 | WSGIDaemonProcess headlines 6 | 7 | WSGIProcessGroup headlines 8 | WSGIApplicationGroup %{GLOBAL} 9 | Order deny,allow 10 | Allow from all 11 | 12 | 13 | -------------------------------------------------------------------------------- /Module 1/Chapter02/headlines.py: -------------------------------------------------------------------------------- 1 | import feedparser 2 | from flask import Flask 3 | 4 | app = Flask(__name__) 5 | 6 | RSS_FEEDS = {'bbc': 'http://feeds.bbci.co.uk/news/rss.xml', 7 | 'cnn': 'http://rss.cnn.com/rss/edition.rss', 8 | 'fox': 'http://feeds.foxnews.com/foxnews/latest', 9 | 'iol': 'http://www.iol.co.za/cmlink/1.640'} 10 | 11 | 12 | @app.route("/") 13 | @app.route("/") 14 | def get_news(publication="bbc"): 15 | feed = feedparser.parse(RSS_FEEDS[publication]) 16 | first_article = feed['entries'][0] 17 | return """ 18 | 19 |

Headlines

20 | {0} 21 | {1} 22 |

{2}

23 | 24 | """.format(first_article.get("title"), 25 | first_article.get("published"), 26 | first_article.get("summary")) 27 | 28 | 29 | if __name__ == "__main__": 30 | app.run(port=5000, debug=True) 31 | -------------------------------------------------------------------------------- /Module 1/Chapter02/headlines.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "/var/www/headlines") 3 | from headlines import app as application 4 | -------------------------------------------------------------------------------- /Module 1/Chapter03/headlines.py: -------------------------------------------------------------------------------- 1 | import feedparser 2 | from flask import Flask 3 | from flask import render_template 4 | 5 | app = Flask(__name__) 6 | 7 | RSS_FEEDS = {'bbc': 'http://feeds.bbci.co.uk/news/rss.xml', 8 | 'cnn': 'http://rss.cnn.com/rss/edition.rss', 9 | 'fox': 'http://feeds.foxnews.com/foxnews/latest', 10 | 'iol': 'http://www.iol.co.za/cmlink/1.640'} 11 | 12 | 13 | @app.route("/") 14 | @app.route("/") 15 | def get_news(publication="bbc"): 16 | feed = feedparser.parse(RSS_FEEDS[publication]) 17 | return render_template("home.html", articles=feed['entries']) 18 | 19 | if __name__ == "__main__": 20 | app.run(port=5000, debug=True) 21 | -------------------------------------------------------------------------------- /Module 1/Chapter03/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Headlines 4 | 5 | 6 |

Headlines

7 | {% for article in articles %} 8 | {{article.title}}
9 | {{article.published}}
10 |

{{article.summary}}

11 |
12 | {% endfor %} 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Module 1/Chapter06/crimemap.py: -------------------------------------------------------------------------------- 1 | from dbhelper import DBHelper 2 | from flask import Flask 3 | from flask import render_template 4 | from flask import request 5 | 6 | 7 | app = Flask(__name__) 8 | DB = DBHelper() 9 | 10 | 11 | @app.route("/") 12 | def home(): 13 | try: 14 | data = DB.get_all_inputs() 15 | except Exception as e: 16 | print e 17 | data = None 18 | return render_template("home.html", data=data) 19 | 20 | 21 | @app.route("/add", methods=["POST"]) 22 | def add(): 23 | try: 24 | data = request.form.get("userinput") 25 | DB.add_input(data) 26 | except Exception as e: 27 | print e 28 | return home() 29 | 30 | 31 | @app.route("/clear") 32 | def clear(): 33 | try: 34 | DB.clear_all() 35 | except Exception as e: 36 | print e 37 | return home() 38 | 39 | if __name__ == '__main__': 40 | app.run(port=5000, debug=True) 41 | -------------------------------------------------------------------------------- /Module 1/Chapter06/crimemap.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "/var/www/crimemap") 3 | from crimemap import app as application 4 | -------------------------------------------------------------------------------- /Module 1/Chapter06/db_setup.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | import dbconfig 3 | connection = pymysql.connect(host='localhost', 4 | user=dbconfig.db_user, 5 | passwd=dbconfig.db_password) 6 | 7 | try: 8 | with connection.cursor() as cursor: 9 | sql = "CREATE DATABASE IF NOT EXISTS crimemap" 10 | cursor.execute(sql) 11 | sql = """CREATE TABLE IF NOT EXISTS crimemap.crimes ( 12 | id int NOT NULL AUTO_INCREMENT, 13 | latitude FLOAT(10,6), 14 | longitude FLOAT(10,6), 15 | date DATETIME, 16 | category VARCHAR(50), 17 | description VARCHAR(255), 18 | updated_at TIMESTAMP, 19 | PRIMARY KEY (id) 20 | )""" 21 | cursor.execute(sql) 22 | connection.commit() 23 | finally: 24 | connection.close() 25 | -------------------------------------------------------------------------------- /Module 1/Chapter06/dbconfig.py: -------------------------------------------------------------------------------- 1 | test = False 2 | db_user = '' 3 | db_password = '' 4 | -------------------------------------------------------------------------------- /Module 1/Chapter06/dbhelper.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | import dbconfig 3 | 4 | 5 | class DBHelper: 6 | 7 | def connect(self, database="crimemap"): 8 | return pymysql.connect(host='localhost', 9 | user=dbconfig.db_user, 10 | passwd=dbconfig.db_password, 11 | db=database) 12 | 13 | def get_all_inputs(self): 14 | connection = self.connect() 15 | try: 16 | query = "SELECT description FROM crimes;" 17 | with connection.cursor() as cursor: 18 | cursor.execute(query) 19 | return cursor.fetchall() 20 | finally: 21 | connection.close() 22 | 23 | def add_input(self, data): 24 | connection = self.connect() 25 | try: 26 | query = "INSERT INTO crimes (description) VALUES (%s);" 27 | with connection.cursor() as cursor: 28 | cursor.execute(query, data) 29 | connection.commit() 30 | finally: 31 | connection.close() 32 | 33 | def clear_all(self): 34 | connection = self.connect() 35 | try: 36 | query = "DELETE FROM crimes;" 37 | with connection.cursor() as cursor: 38 | cursor.execute(query) 39 | connection.commit() 40 | finally: 41 | connection.close() 42 | -------------------------------------------------------------------------------- /Module 1/Chapter06/misc/crimemap.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerName example.com 3 | 4 | WSGIScriptAlias / /var/www/crimemap/crimemap.wsgi 5 | WSGIDaemonProcess crimemap 6 | 7 | WSGIProcessGroup crimemap 8 | WSGIApplicationGroup %{GLOBAL} 9 | Order deny,allow 10 | Allow from all 11 | 12 | 13 | -------------------------------------------------------------------------------- /Module 1/Chapter06/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Crime Map 5 | 6 | 7 |

Crime Map

8 |
9 | 10 | 11 |
12 | clear 13 | 14 | {% for userinput in data %} 15 |

{{userinput}}

16 | {% endfor %} 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Module 1/Chapter07/crimemap.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask import render_template 3 | from flask import request 4 | import json 5 | import dbconfig 6 | if dbconfig.test: 7 | from mockdbhelper import MockDBHelper as DBHelper 8 | else: 9 | from dbhelper import DBHelper 10 | 11 | app = Flask(__name__) 12 | DB = DBHelper() 13 | 14 | 15 | @app.route("/") 16 | def home(): 17 | crimes = DB.get_all_crimes() 18 | crimes = json.dumps(crimes) 19 | return render_template("home.html", crimes=crimes) 20 | 21 | 22 | @app.route("/submitcrime", methods=['POST']) 23 | def submitcrime(): 24 | category = request.form.get("category") 25 | date = request.form.get("date") 26 | latitude = float(request.form.get("latitude")) 27 | longitude = float(request.form.get("longitude")) 28 | description = request.form.get("description") 29 | DB.add_crime(category, date, latitude, longitude, description) 30 | return home() 31 | 32 | 33 | if __name__ == '__main__': 34 | app.run(debug=True) 35 | -------------------------------------------------------------------------------- /Module 1/Chapter07/db_setup.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | import dbconfig 3 | connection = pymysql.connect(host='localhost', 4 | user=dbconfig.db_user, 5 | passwd=dbconfig.db_password) 6 | 7 | try: 8 | with connection.cursor() as cursor: 9 | sql = "CREATE DATABASE IF NOT EXISTS crimemap" 10 | cursor.execute(sql) 11 | sql = """CREATE TABLE IF NOT EXISTS crimemap.crimes ( 12 | id int NOT NULL AUTO_INCREMENT, 13 | latitude FLOAT(10,6), 14 | longitude FLOAT(10,6), 15 | date DATETIME, 16 | category VARCHAR(50), 17 | description VARCHAR(255), 18 | updated_at TIMESTAMP, 19 | PRIMARY KEY (id) 20 | )""" 21 | cursor.execute(sql) 22 | connection.commit() 23 | finally: 24 | connection.close() 25 | -------------------------------------------------------------------------------- /Module 1/Chapter07/dbconfig.py: -------------------------------------------------------------------------------- 1 | test = True -------------------------------------------------------------------------------- /Module 1/Chapter07/misc/crimemap.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerName example.com 3 | 4 | WSGIScriptAlias / /var/www/crimemap/crimemap.wsgi 5 | WSGIDaemonProcess crimemap 6 | 7 | WSGIProcessGroup crimemap 8 | WSGIApplicationGroup %{GLOBAL} 9 | Order deny,allow 10 | Allow from all 11 | 12 | 13 | -------------------------------------------------------------------------------- /Module 1/Chapter07/misc/crimemap.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "/var/www/crimemap") 3 | from crimemap import app as application 4 | -------------------------------------------------------------------------------- /Module 1/Chapter07/mockdbhelper.py: -------------------------------------------------------------------------------- 1 | class MockDBHelper: 2 | 3 | def connect(self, database="crimemap"): 4 | pass 5 | 6 | def add_crime(self, category, date, latitude, longitude, description): 7 | data = [category, date, latitude, longitude, description] 8 | for i in data: 9 | print i, type(i) 10 | 11 | def get_all_crimes(self): 12 | return [{'latitude': -33.301304, 13 | 'longitude': 26.523355, 14 | 'date': "2000-01-01", 15 | 'category': "mugging", 16 | 'description': "mock description"}] 17 | 18 | def add_input(self, data): 19 | pass 20 | 21 | def clear_all(self): 22 | pass 23 | -------------------------------------------------------------------------------- /Module 1/Chapter07/static/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | background: #eee; 4 | } 5 | 6 | #map-canvas { 7 | width: 70%; 8 | height: 500px; 9 | float: left; 10 | } 11 | 12 | #newcrimeform { 13 | float: right; 14 | width: 25%; 15 | } 16 | 17 | input, select, textarea { 18 | display: block; 19 | color: grey; 20 | border: 1px solid lightsteelblue; 21 | line-height: 15px; 22 | margin: 2px 6px 16px 0px; 23 | width: 100%; 24 | } 25 | 26 | input[type="submit"] { 27 | padding: 5px 10px 5px 10px; 28 | color: black; 29 | background: lightsteelblue; 30 | border: none; 31 | box-shadow: 1px 1px 1px #4C6E91; 32 | } 33 | 34 | input[type="submit"]:hover { 35 | background: steelblue; 36 | } 37 | -------------------------------------------------------------------------------- /Module 1/Chapter08/db_setup.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | import dbconfig 3 | connection = pymysql.connect(host='localhost', 4 | user=dbconfig.db_user, 5 | passwd=dbconfig.db_password) 6 | 7 | try: 8 | with connection.cursor() as cursor: 9 | sql = "CREATE DATABASE IF NOT EXISTS crimemap" 10 | cursor.execute(sql) 11 | sql = """CREATE TABLE IF NOT EXISTS crimemap.crimes ( 12 | id int NOT NULL AUTO_INCREMENT, 13 | latitude FLOAT(10,6), 14 | longitude FLOAT(10,6), 15 | date DATETIME, 16 | category VARCHAR(50), 17 | description VARCHAR(255), 18 | updated_at TIMESTAMP, 19 | PRIMARY KEY (id) 20 | )""" 21 | cursor.execute(sql) 22 | connection.commit() 23 | finally: 24 | connection.close() 25 | -------------------------------------------------------------------------------- /Module 1/Chapter08/dbconfig.py: -------------------------------------------------------------------------------- 1 | test = True -------------------------------------------------------------------------------- /Module 1/Chapter08/misc/crimemap.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerName example.com 3 | 4 | WSGIScriptAlias / /var/www/crimemap/crimemap.wsgi 5 | WSGIDaemonProcess crimemap 6 | 7 | WSGIProcessGroup crimemap 8 | WSGIApplicationGroup %{GLOBAL} 9 | Order deny,allow 10 | Allow from all 11 | 12 | 13 | -------------------------------------------------------------------------------- /Module 1/Chapter08/misc/crimemap.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "/var/www/crimemap") 3 | from crimemap import app as application 4 | -------------------------------------------------------------------------------- /Module 1/Chapter08/mockdbhelper.py: -------------------------------------------------------------------------------- 1 | class MockDBHelper: 2 | 3 | def connect(self, database="crimemap"): 4 | pass 5 | 6 | def add_crime(self, category, date, latitude, longitude, description): 7 | data = [category, date, latitude, longitude, description] 8 | for i in data: 9 | print i, type(i) 10 | 11 | def get_all_crimes(self): 12 | return [{'latitude': -33.301304, 13 | 'longitude': 26.523355, 14 | 'date': "2000-01-01", 15 | 'category': "mugging", 16 | 'description': "mock description"}] 17 | 18 | def add_input(self, data): 19 | pass 20 | 21 | def clear_all(self): 22 | pass 23 | -------------------------------------------------------------------------------- /Module 1/Chapter08/static/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | background: #eee; 4 | } 5 | 6 | #map-canvas { 7 | width: 70%; 8 | height: 500px; 9 | float: left; 10 | } 11 | 12 | #newcrimeform { 13 | float: right; 14 | width: 25%; 15 | } 16 | 17 | #error { 18 | color: red; 19 | } 20 | 21 | input, select, textarea { 22 | display: block; 23 | color: grey; 24 | border: 1px solid lightsteelblue; 25 | line-height: 15px; 26 | margin: 2px 6px 16px 0px; 27 | width: 100%; 28 | } 29 | 30 | input[type="submit"] { 31 | padding: 5px 10px 5px 10px; 32 | color: black; 33 | background: lightsteelblue; 34 | border: none; 35 | box-shadow: 1px 1px 1px #4C6E91; 36 | } 37 | 38 | input[type="submit"]:hover { 39 | background: steelblue; 40 | } 41 | -------------------------------------------------------------------------------- /Module 1/Chapter09/config.py: -------------------------------------------------------------------------------- 1 | test = True 2 | -------------------------------------------------------------------------------- /Module 1/Chapter09/mockdbhelper.py: -------------------------------------------------------------------------------- 1 | MOCK_USERS = [{"email": "test@example.com", "salt": "8Fb23mMNHD5Zb8pr2qWA3PE9bH0=", "hashed": 2 | "1736f83698df3f8153c1fbd6ce2840f8aace4f200771a46672635374073cc876cf0aa6a31f780e576578f791b5555b50df46303f0c3a7f2d21f91aa1429ac22e"}] 3 | 4 | 5 | class MockDBHelper: 6 | 7 | def get_user(self, email): 8 | user = [x for x in MOCK_USERS if x.get("email") == email] 9 | if user: 10 | return user[0] 11 | return None 12 | 13 | def add_user(self, email, salt, hashed): 14 | MOCK_USERS.append({"email": email, "salt": salt, "hashed": hashed}) 15 | -------------------------------------------------------------------------------- /Module 1/Chapter09/passwordhelper.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import os 3 | import base64 4 | 5 | 6 | class PasswordHelper: 7 | 8 | def get_hash(self, plain): 9 | return hashlib.sha512(plain).hexdigest() 10 | 11 | def get_salt(self): 12 | return base64.b64encode(os.urandom(20)) 13 | 14 | def validate_password(self, plain, salt, expected): 15 | return self.get_hash(plain + salt) == expected 16 | -------------------------------------------------------------------------------- /Module 1/Chapter09/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter09/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 1/Chapter09/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter09/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 1/Chapter09/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter09/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 1/Chapter09/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter09/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 1/Chapter09/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 1/Chapter09/user.py: -------------------------------------------------------------------------------- 1 | class User: 2 | def __init__(self, email): 3 | self.email = email 4 | 5 | def get_id(self): 6 | return self.email 7 | 8 | def is_active(self): 9 | return True 10 | 11 | def is_anonymous(self): 12 | return False 13 | 14 | def is_authenticated(self): 15 | return True 16 | -------------------------------------------------------------------------------- /Module 1/Chapter09/waitercaller.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "/var/www/waitercaller") 3 | from waitercaller import app as application 4 | -------------------------------------------------------------------------------- /Module 1/Chapter10/bitlyhelper.py: -------------------------------------------------------------------------------- 1 | import urllib2 2 | import json 3 | 4 | TOKEN = "cc922578a7a1c6065a2aa91bc62b02e41a99afdb" 5 | ROOT_URL = "https://api-ssl.bitly.com" 6 | SHORTEN = "/v3/shorten?access_token={}&longUrl={}" 7 | 8 | 9 | class BitlyHelper: 10 | 11 | def shorten_url(self, longurl): 12 | try: 13 | url = ROOT_URL + SHORTEN.format(TOKEN, longurl) 14 | response = urllib2.urlopen(url).read() 15 | jr = json.loads(response) 16 | return jr['data']['url'] 17 | except Exception as e: 18 | print e 19 | -------------------------------------------------------------------------------- /Module 1/Chapter10/config.py: -------------------------------------------------------------------------------- 1 | test = True 2 | base_url = "http://127.0.0.1:5000/" 3 | 4 | -------------------------------------------------------------------------------- /Module 1/Chapter10/forms.py: -------------------------------------------------------------------------------- 1 | from flask_wtf import Form 2 | from wtforms import PasswordField 3 | from wtforms import SubmitField 4 | from wtforms.fields.html5 import EmailField 5 | from wtforms import TextField 6 | from wtforms import validators 7 | 8 | 9 | class RegistrationForm(Form): 10 | email = EmailField('email', validators=[validators.DataRequired(), validators.Email()]) 11 | password = PasswordField('password', validators=[validators.DataRequired(), 12 | validators.Length(min=8, message="Please choose a password of at least 8 characters")]) 13 | password2 = PasswordField('password2', validators=[validators.DataRequired(), 14 | validators.EqualTo('password', message='Passwords must match')]) 15 | submit = SubmitField('submit', [validators.DataRequired()]) 16 | 17 | 18 | class LoginForm(Form): 19 | loginemail = EmailField('email', validators=[validators.DataRequired(), validators.Email()]) 20 | loginpassword = PasswordField('password', validators=[validators.DataRequired(message="Password field is required")]) 21 | submit = SubmitField('submit', [validators.DataRequired()]) 22 | 23 | 24 | class CreateTableForm(Form): 25 | tablenumber = TextField('tablenumber', validators=[validators.DataRequired()]) 26 | submit = SubmitField('createtablesubmit', validators=[validators.DataRequired()]) 27 | 28 | 29 | -------------------------------------------------------------------------------- /Module 1/Chapter10/mockbitlyhelper.py: -------------------------------------------------------------------------------- 1 | class MockBitlyHelper: 2 | 3 | def shorten_url(self, long_url): 4 | return long_url 5 | -------------------------------------------------------------------------------- /Module 1/Chapter10/passwordhelper.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import os 3 | import base64 4 | 5 | class PasswordHelper: 6 | 7 | def get_hash(self, plain): 8 | return hashlib.sha512(plain).hexdigest() 9 | 10 | def get_salt(self): 11 | return base64.b64encode(os.urandom(20)) 12 | 13 | def validate_password(self, plain, salt, expected): 14 | return self.get_hash(plain + salt) == expected 15 | -------------------------------------------------------------------------------- /Module 1/Chapter10/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter10/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 1/Chapter10/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter10/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 1/Chapter10/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter10/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 1/Chapter10/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter10/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 1/Chapter10/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 1/Chapter10/user.py: -------------------------------------------------------------------------------- 1 | class User: 2 | def __init__(self, email): 3 | self.email = email 4 | 5 | def get_id(self): 6 | return self.email 7 | 8 | def is_active(self): 9 | return True 10 | 11 | def is_anonymous(self): 12 | return False 13 | 14 | def is_authenticated(self): 15 | return True -------------------------------------------------------------------------------- /Module 1/Chapter10/waitercaller.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "/var/www/waitercaller") 3 | from waitercaller import app as application 4 | -------------------------------------------------------------------------------- /Module 1/Chapter11/.gitignore: -------------------------------------------------------------------------------- 1 | config.py 2 | *.pyc 3 | 4 | -------------------------------------------------------------------------------- /Module 1/Chapter11/bitlyhelper.py: -------------------------------------------------------------------------------- 1 | import urllib2 2 | import json 3 | 4 | TOKEN = "cc922578a7a1c6065a2aa91bc62b02e41a99afdb" 5 | ROOT_URL = "https://api-ssl.bitly.com" 6 | SHORTEN = "/v3/shorten?access_token={}&longUrl={}" 7 | 8 | 9 | class BitlyHelper: 10 | 11 | def shorten_url(self, longurl): 12 | try: 13 | url = ROOT_URL + SHORTEN.format(TOKEN, longurl) 14 | response = urllib2.urlopen(url).read() 15 | jr = json.loads(response) 16 | return jr['data']['url'] 17 | except Exception as e: 18 | print e 19 | -------------------------------------------------------------------------------- /Module 1/Chapter11/create_mongo_indices.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | 3 | client = pymongo.MongoClient() 4 | c = client['waitercaller'] 5 | 6 | print c.users.create_index("email", unique=True) 7 | print c.requests.create_index("table_id", unique=True) 8 | -------------------------------------------------------------------------------- /Module 1/Chapter11/forms.py: -------------------------------------------------------------------------------- 1 | from flask_wtf import Form 2 | from wtforms import PasswordField 3 | from wtforms import SubmitField 4 | from wtforms.fields.html5 import EmailField 5 | from wtforms import TextField 6 | from wtforms import validators 7 | 8 | 9 | class RegistrationForm(Form): 10 | email = EmailField('email', validators=[validators.DataRequired(), validators.Email()]) 11 | password = PasswordField('password', validators=[validators.DataRequired(), 12 | validators.Length(min=8, message="Please choose a password of at least 8 characters")]) 13 | password2 = PasswordField('password2', validators=[validators.DataRequired(), 14 | validators.EqualTo('password', message='Passwords must match')]) 15 | submit = SubmitField('submit', [validators.DataRequired()]) 16 | 17 | 18 | class LoginForm(Form): 19 | loginemail = EmailField('email', validators=[validators.DataRequired(), validators.Email()]) 20 | loginpassword = PasswordField('password', validators=[validators.DataRequired(message="Password field is required")]) 21 | submit = SubmitField('submit', [validators.DataRequired()]) 22 | 23 | 24 | class CreateTableForm(Form): 25 | tablenumber = TextField('tablenumber', validators=[validators.DataRequired()]) 26 | submit = SubmitField('createtablesubmit', validators=[validators.DataRequired()]) 27 | 28 | 29 | -------------------------------------------------------------------------------- /Module 1/Chapter11/mockbitlyhelper.py: -------------------------------------------------------------------------------- 1 | class MockBitlyHelper: 2 | 3 | def shorten_url(self, long_url): 4 | return long_url 5 | -------------------------------------------------------------------------------- /Module 1/Chapter11/passwordhelper.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import os 3 | import base64 4 | 5 | class PasswordHelper: 6 | 7 | def get_hash(self, plain): 8 | return hashlib.sha512(plain).hexdigest() 9 | 10 | def get_salt(self): 11 | return base64.b64encode(os.urandom(20)) 12 | 13 | def validate_password(self, plain, salt, expected): 14 | return self.get_hash(plain + salt) == expected 15 | -------------------------------------------------------------------------------- /Module 1/Chapter11/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter11/static/favicon.ico -------------------------------------------------------------------------------- /Module 1/Chapter11/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter11/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 1/Chapter11/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter11/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 1/Chapter11/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter11/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 1/Chapter11/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Chapter11/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 1/Chapter11/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 1/Chapter11/user.py: -------------------------------------------------------------------------------- 1 | class User: 2 | def __init__(self, email): 3 | self.email = email 4 | 5 | def get_id(self): 6 | return self.email 7 | 8 | def is_active(self): 9 | return True 10 | 11 | def is_anonymous(self): 12 | return False 13 | 14 | def is_authenticated(self): 15 | return True -------------------------------------------------------------------------------- /Module 1/Chapter11/waitercaller.wsgi: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.insert(0, "/var/www/waitercaller") 3 | from waitercaller import app as application 4 | -------------------------------------------------------------------------------- /Module 1/ReadMe.txt: -------------------------------------------------------------------------------- 1 | While installing python select the radio option set the environment variables to be able to run the python files directly from the terminal or Command prompt. 2 | If not you need to set the environment variables directly from the control panel. 3 | 4 | To deploy the app on the remote server we set up a VPS (Virtual private server), to connect to this server we use ssh (sercure shell) protocol to gain control over the remote server. 5 | For such operations PuTTy is one of the best open source ssh client. 6 | 7 | While pushing files in to git there might be some integrity or to be more specific merge issues which would deny the push request since the both the local and remote versions to be same in order to push into git. 8 | If you want to give more priority to your local version you can use a git force command (git push origin --force) to push your local version in to the git directory. -------------------------------------------------------------------------------- /Module 1/Software Hardware List.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 1/Software Hardware List.docx -------------------------------------------------------------------------------- /Module 2/Chapter01/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def hello_world(): 6 | return 'Hello to the World of Flask!' 7 | 8 | if __name__ == '__main__': 9 | app.run() 10 | -------------------------------------------------------------------------------- /Module 2/Chapter01/my_app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from my_app.hello.views import hello 3 | 4 | app = Flask(__name__) 5 | app.register_blueprint(hello) 6 | -------------------------------------------------------------------------------- /Module 2/Chapter01/my_app/hello/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter01/my_app/hello/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter01/my_app/hello/models.py: -------------------------------------------------------------------------------- 1 | MESSAGES = { 2 | 'default': 'Hello to the World of Flask!', 3 | } 4 | -------------------------------------------------------------------------------- /Module 2/Chapter01/my_app/hello/views.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | from my_app.hello.models import MESSAGES 3 | 4 | hello = Blueprint('hello', __name__) 5 | 6 | 7 | @hello.route('/') 8 | @hello.route('/hello') 9 | def hello_world(): 10 | return MESSAGES['default'] 11 | 12 | 13 | @hello.route('/show/') 14 | def get_message(key): 15 | return MESSAGES.get(key) or "%s not found!" % key 16 | 17 | 18 | @hello.route('/add//') 19 | def add_or_update_message(key, message): 20 | MESSAGES[key] = message 21 | return "%s Added/Updated" % key 22 | -------------------------------------------------------------------------------- /Module 2/Chapter01/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter01/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | import os 4 | from setuptools import setup 5 | 6 | setup( 7 | name = 'my_app', 8 | version='1.0', 9 | license='GNU General Public License v3', 10 | author='Shalabh Aggarwal', 11 | author_email='contact@shalabhaggarwal.com', 12 | description='Hello world application for Flask', 13 | packages=['my_app'], 14 | platforms='any', 15 | install_requires=[ 16 | 'flask', 17 | ], 18 | classifiers=[ 19 | 'Development Status :: 4 - Beta', 20 | 'Environment :: Web Environment', 21 | 'Intended Audience :: Developers', 22 | 'License :: OSI Approved :: GNU General Public License v3', 23 | 'Operating System :: OS Independent', 24 | 'Programming Language :: Python', 25 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 26 | 'Topic :: Software Development :: Libraries :: Python Modules' 27 | ], 28 | ) 29 | -------------------------------------------------------------------------------- /Module 2/Chapter02/my_app/__init__.py: -------------------------------------------------------------------------------- 1 | import ccy 2 | from flask import Flask, request 3 | from my_app.product.views import product_blueprint 4 | 5 | app = Flask(__name__) 6 | app.register_blueprint(product_blueprint) 7 | 8 | 9 | @app.template_filter('format_currency') 10 | def format_currency_filter(amount): 11 | currency_code = ccy.countryccy(request.accept_languages.best[-2:]) 12 | return '{0} {1}'.format(currency_code, amount) 13 | -------------------------------------------------------------------------------- /Module 2/Chapter02/my_app/product/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter02/my_app/product/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter02/my_app/product/models.py: -------------------------------------------------------------------------------- 1 | PRODUCTS = { 2 | 'iphone': { 3 | 'name': 'iPhone 5S', 4 | 'category': 'Phones', 5 | 'price': 699, 6 | }, 7 | 'galaxy': { 8 | 'name': 'Samsung Galaxy 5', 9 | 'category': 'Phones', 10 | 'price': 649, 11 | }, 12 | 'ipad-air': { 13 | 'name': 'iPad Air', 14 | 'category': 'Tablets', 15 | 'price': 649, 16 | }, 17 | 'ipad-mini': { 18 | 'name': 'iPad Mini', 19 | 'category': 'Tablets', 20 | 'price': 549 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 2/Chapter02/my_app/product/views.py: -------------------------------------------------------------------------------- 1 | from werkzeug import abort 2 | from flask import render_template 3 | from flask import Blueprint 4 | from my_app.product.models import PRODUCTS 5 | 6 | product_blueprint = Blueprint('product', __name__) 7 | 8 | 9 | @product_blueprint.context_processor 10 | def some_processor(): 11 | def full_name(product): 12 | return '{0} / {1}'.format(product['category'], product['name']) 13 | return {'full_name': full_name} 14 | 15 | 16 | @product_blueprint.route('/') 17 | @product_blueprint.route('/home') 18 | def home(): 19 | return render_template('home.html', products=PRODUCTS) 20 | 21 | @product_blueprint.route('/product/') 22 | def product(key): 23 | product = PRODUCTS.get(key) 24 | if not product: 25 | abort(404) 26 | return render_template('product.html', product=product) 27 | -------------------------------------------------------------------------------- /Module 2/Chapter02/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter02/my_app/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Flask Framework Cookbook 8 | 9 | 10 | 11 | 12 | 19 |
20 | {% block container %}{% endblock %} 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Module 2/Chapter02/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for id, product in products.iteritems() %} 6 |
7 |

8 | {{ product['name'] }} 9 | $ {{ product['price'] }} 10 |

11 |
12 | {% endfor %} 13 |
14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /Module 2/Chapter02/my_app/templates/product.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ full_name(product) }}

6 |

{{ product['name'] }} 7 | {{ product['category'] }} 8 |

9 |

{{ product['price']|format_currency }}

10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter02/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter02/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | import os 4 | from setuptools import setup 5 | 6 | setup( 7 | name = 'my_app', 8 | version='1.0', 9 | license='GNU General Public License v3', 10 | author='Shalabh Aggarwal', 11 | author_email='contact@shalabhaggarwal.com', 12 | description='Hello world application for Flask', 13 | packages=['my_app'], 14 | platforms='any', 15 | install_requires=[ 16 | 'flask', 17 | ], 18 | classifiers=[ 19 | 'Development Status :: 4 - Beta', 20 | 'Environment :: Web Environment', 21 | 'Intended Audience :: Developers', 22 | 'License :: OSI Approved :: GNU General Public License v3', 23 | 'Operating System :: OS Independent', 24 | 'Programming Language :: Python', 25 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 26 | 'Topic :: Software Development :: Libraries :: Python Modules' 27 | ], 28 | ) 29 | -------------------------------------------------------------------------------- /Module 2/Chapter03/migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /Module 2/Chapter03/migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /Module 2/Chapter03/migrations/env.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter03/migrations/env.pyc -------------------------------------------------------------------------------- /Module 2/Chapter03/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /Module 2/Chapter03/migrations/versions/538264df91d2_.py: -------------------------------------------------------------------------------- 1 | """empty message 2 | 3 | Revision ID: 538264df91d2 4 | Revises: None 5 | Create Date: 2014-09-23 16:55:41.296855 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '538264df91d2' 11 | down_revision = None 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.add_column('product', sa.Column('company', sa.String(length=100), nullable=True)) 20 | ### end Alembic commands ### 21 | 22 | 23 | def downgrade(): 24 | ### commands auto generated by Alembic - please adjust! ### 25 | op.drop_column('product', 'company') 26 | ### end Alembic commands ### 27 | -------------------------------------------------------------------------------- /Module 2/Chapter03/migrations/versions/538264df91d2_.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter03/migrations/versions/538264df91d2_.pyc -------------------------------------------------------------------------------- /Module 2/Chapter03/my_app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask.ext.mongoengine import MongoEngine 3 | from redis import Redis 4 | 5 | 6 | app = Flask(__name__) 7 | app.config['MONGODB_SETTINGS'] = {'DB': 'my_catalog'} 8 | app.debug = True 9 | db = MongoEngine(app) 10 | 11 | redis = Redis() 12 | 13 | from my_app.catalog.views import catalog 14 | app.register_blueprint(catalog) 15 | -------------------------------------------------------------------------------- /Module 2/Chapter03/my_app/catalog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter03/my_app/catalog/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter03/my_app/catalog/models.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | from my_app import db 3 | 4 | 5 | class Product(db.Document): 6 | created_at = db.DateTimeField( 7 | default=datetime.datetime.now, required=True 8 | ) 9 | key = db.StringField(max_length=255, required=True) 10 | name = db.StringField(max_length=255, required=True) 11 | price = db.DecimalField() 12 | 13 | def __repr__(self): 14 | return '' % self.id 15 | -------------------------------------------------------------------------------- /Module 2/Chapter03/my_app/catalog/views.py: -------------------------------------------------------------------------------- 1 | from decimal import Decimal 2 | from flask import request, Blueprint, jsonify 3 | from my_app.catalog.models import Product 4 | 5 | catalog = Blueprint('catalog', __name__) 6 | 7 | 8 | @catalog.route('/') 9 | @catalog.route('/home') 10 | def home(): 11 | return "Welcome to the Catalog Home." 12 | 13 | 14 | @catalog.route('/product/') 15 | def product(key): 16 | product = Product.objects.get_or_404(key=key) 17 | return 'Product - %s, $%s' % (product.name, product.price) 18 | 19 | 20 | @catalog.route('/products') 21 | def products(): 22 | products = Product.objects.all() 23 | res = {} 24 | for product in products: 25 | res[product.key] = { 26 | 'name': product.name, 27 | 'price': str(product.price), 28 | } 29 | return jsonify(res) 30 | 31 | 32 | @catalog.route('/product-create', methods=['POST',]) 33 | def create_product(): 34 | name = request.form.get('name') 35 | key = request.form.get('key') 36 | price = request.form.get('price') 37 | product = Product( 38 | name=name, 39 | key=key, 40 | price=Decimal(price) 41 | ) 42 | product.save() 43 | return 'Product created.' 44 | -------------------------------------------------------------------------------- /Module 2/Chapter03/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask.ext.sqlalchemy import SQLAlchemy 3 | 4 | app = Flask(__name__) 5 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' 6 | db = SQLAlchemy(app) 7 | 8 | app.secret_key = 'some_random_key' 9 | 10 | from my_app.catalog.views import catalog 11 | app.register_blueprint(catalog) 12 | 13 | db.create_all() 14 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/catalog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter04/my_app/catalog/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/catalog/models.py: -------------------------------------------------------------------------------- 1 | from my_app import db 2 | 3 | class Product(db.Model): 4 | id = db.Column(db.Integer, primary_key=True) 5 | name = db.Column(db.String(255)) 6 | price = db.Column(db.Float) 7 | category_id = db.Column(db.Integer, db.ForeignKey('category.id')) 8 | category = db.relationship( 9 | 'Category', backref=db.backref('products', lazy='dynamic') 10 | ) 11 | 12 | def __init__(self, name, price, category): 13 | self.name = name 14 | self.price = price 15 | self.category = category 16 | 17 | def __repr__(self): 18 | return '' % self.id 19 | 20 | 21 | class Category(db.Model): 22 | id = db.Column(db.Integer, primary_key=True) 23 | name = db.Column(db.String(100)) 24 | 25 | def __init__(self, name): 26 | self.name = name 27 | 28 | def __repr__(self): 29 | return '' % self.id 30 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

Hola Friend! Looks like in your quest you have reached a location which does not exist yet.

6 |

To continue, either check your map location (URL) or go back home

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/templates/categories.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for category in categories %} 6 | 7 |

{{ category.name }}

8 |
9 | {% endfor %} 10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ category.name }}

6 |
7 | {% for product in category.products %} 8 |

9 | {{ product.name }} 10 | $ {{ product.price }} 11 |

12 | {% endfor %} 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

Welcome to the Catalog Home

5 | 6 | Click here to see the catalog 7 | 8 | {% endblock %} 9 | 10 | {% block scripts %} 11 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/templates/product-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 |
19 | 20 |
21 |
22 |
23 | 24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 | {% endblock %} 32 | 33 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/templates/product.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ product.name }} {{ product.category.name }}

6 |

{{ product.company }}

7 |

{{ product.price }}

8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Module 2/Chapter04/my_app/templates/products.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for product in products.items %} 6 |
7 |

8 | {{ product.name }} 9 | $ {{ product.price }} 10 |

11 |
12 | {% endfor %} 13 | {% if products.has_prev %} 14 | 15 | {{"<< Previous Page"}} 16 | 17 | {% else %} 18 | {{"<< Previous Page"}} 19 | {% endif %} | 20 | {% if products.has_next %} 21 | 22 | {{"Next page >>"}} 23 | 24 | {% else %} 25 | {{"Next page >>"}} 26 | {% endif %} 27 |
28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /Module 2/Chapter04/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from flask import Flask 3 | from flask.ext.sqlalchemy import SQLAlchemy 4 | 5 | 6 | ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) 7 | 8 | app = Flask(__name__) 9 | app.config['UPLOAD_FOLDER'] = os.path.realpath('.') + '/my_app/static/uploads' 10 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' 11 | app.config['WTF_CSRF_SECRET_KEY'] = 'random key for form' 12 | db = SQLAlchemy(app) 13 | 14 | app.secret_key = 'some_random_key' 15 | 16 | from my_app.catalog.views import catalog 17 | app.register_blueprint(catalog) 18 | 19 | db.create_all() 20 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/catalog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter05/my_app/catalog/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/static/uploads/apple-iphone-5-front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter05/my_app/static/uploads/apple-iphone-5-front.jpg -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

Hola Friend! Looks like in your quest you have reached a location which does not exist yet.

6 |

To continue, either check your map location (URL) or go back home

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/templates/categories.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for category in categories %} 6 | 7 |

{{ category.name }}

8 |
9 | {% endfor %} 10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/templates/category-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
6 | {{ form.csrf_token }} 7 |
{{ form.name.label }}: {{ form.name() }}
8 | 9 |
10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ category.name }}

6 |
7 | {% for product in category.products %} 8 |

9 | {{ product.name }} 10 | $ {{ product.price }} 11 |

12 | {% endfor %} 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

Welcome to the Catalog Home

5 | 6 | Click here to see the catalog 7 | 8 | {% endblock %} 9 | 10 | {% block scripts %} 11 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/templates/product-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.name.label }}: {{ form.name() }}
11 |
{{ form.price.label }}: {{ form.price() }}
12 |
{{ form.category.label }}: {{ form.category() }}
13 |
{{ form.image.label }}: {{ form.image(style='display:inline;') }}
14 | 15 |
16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/templates/product.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | 6 |

{{ product.name }} {{ product.category.name }}

7 |

{{ product.price }}

8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Module 2/Chapter05/my_app/templates/products.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for product in products.items %} 6 |
7 |

8 | {{ product.name }} 9 | $ {{ product.price }} 10 |

11 |
12 | {% endfor %} 13 | {% if products.has_prev %} 14 | 15 | {{"<< Previous Page"}} 16 | 17 | {% else %} 18 | {{"<< Previous Page"}} 19 | {% endif %} | 20 | {% if products.has_next %} 21 | 22 | {{"Next page >>"}} 23 | 24 | {% else %} 25 | {{"Next page >>"}} 26 | {% endif %} 27 |
28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /Module 2/Chapter05/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter06/my_app/auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter06/my_app/auth/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter06/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter06/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

Welcome to the Authentication Demo

5 | {% if current_user.is_authenticated() %} 6 |

Hey {{ current_user.username }}!!

7 | Click here to logout 8 | {% else %} 9 | Click here to login or register 10 | {% endif %} 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter06/my_app/templates/register.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.username.label }}: {{ form.username() }}
11 |
{{ form.password.label }}: {{ form.password() }}
12 |
{{ form.confirm.label }}: {{ form.confirm() }}
13 | 14 |
15 |
16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /Module 2/Chapter06/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask.ext.sqlalchemy import SQLAlchemy 3 | from flask.ext.restful import Api 4 | 5 | app = Flask(__name__) 6 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' 7 | db = SQLAlchemy(app) 8 | 9 | app.secret_key = 'some_random_key' 10 | 11 | api = Api(app) 12 | 13 | from my_app.catalog.views import catalog 14 | app.register_blueprint(catalog) 15 | 16 | db.create_all() 17 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/catalog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter07/my_app/catalog/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/catalog/models.py: -------------------------------------------------------------------------------- 1 | from my_app import db 2 | 3 | class Product(db.Model): 4 | id = db.Column(db.Integer, primary_key=True) 5 | name = db.Column(db.String(255)) 6 | price = db.Column(db.Float) 7 | category_id = db.Column(db.Integer, db.ForeignKey('category.id')) 8 | category = db.relationship( 9 | 'Category', backref=db.backref('products', lazy='dynamic') 10 | ) 11 | 12 | def __init__(self, name, price, category=None): 13 | self.name = name 14 | self.price = price 15 | self.category = category 16 | 17 | def __repr__(self): 18 | return '' % self.id 19 | 20 | 21 | class Category(db.Model): 22 | id = db.Column(db.Integer, primary_key=True) 23 | name = db.Column(db.String(100)) 24 | 25 | def __init__(self, name): 26 | self.name = name 27 | 28 | def __repr__(self): 29 | return '' % self.id 30 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

Hola Friend! Looks like in your quest you have reached a location which does not exist yet.

6 |

To continue, either check your map location (URL) or go back home

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/templates/categories.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for category in categories %} 6 | 7 |

{{ category.name }}

8 |
9 | {% endfor %} 10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ category.name }}

6 |
7 | {% for product in category.products %} 8 |

9 | {{ product.name }} 10 | $ {{ product.price }} 11 |

12 | {% endfor %} 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

Welcome to the Catalog Home

5 | 6 | Click here to see the catalog 7 | 8 | {% endblock %} 9 | 10 | {% block scripts %} 11 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/templates/product-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 |
19 | 20 |
21 |
22 |
23 | 24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 | {% endblock %} 32 | 33 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/templates/product.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ product.name }} {{ product.category.name }}

6 |

{{ product.company }}

7 |

{{ product.price }}

8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Module 2/Chapter07/my_app/templates/products.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for product in products.items %} 6 |
7 |

8 | {{ product.name }} 9 | $ {{ product.price }} 10 |

11 |
12 | {% endfor %} 13 | {% if products.has_prev %} 14 | 15 | {{"<< Previous Page"}} 16 | 17 | {% else %} 18 | {{"<< Previous Page"}} 19 | {% endif %} | 20 | {% if products.has_next %} 21 | 22 | {{"Next page >>"}} 23 | 24 | {% else %} 25 | {{"Next page >>"}} 26 | {% endif %} 27 |
28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /Module 2/Chapter07/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask.ext.sqlalchemy import SQLAlchemy 3 | from flask.ext.login import LoginManager 4 | from flask.ext.admin import Admin 5 | 6 | 7 | app = Flask(__name__) 8 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' 9 | app.config['WTF_CSRF_SECRET_KEY'] = 'random key for form' 10 | db = SQLAlchemy(app) 11 | 12 | app.secret_key = 'some_random_key' 13 | 14 | login_manager = LoginManager() 15 | login_manager.init_app(app) 16 | login_manager.login_view = 'auth.login' 17 | 18 | import my_app.auth.views as views 19 | admin = Admin(app, index_view=views.MyAdminIndexView()) 20 | admin.add_view(views.HelloView(name='Hello')) 21 | admin.add_view(views.UserAdminView(views.User, db.session)) 22 | 23 | from my_app.auth.views import auth 24 | app.register_blueprint(auth) 25 | 26 | db.create_all() 27 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter08/my_app/auth/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/admin-home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

Welcome to the Admin Demo

5 |

Hey {{ current_user.username }}!!

6 | List of all users 7 |
8 | Create a new user 9 |
10 | Click here to logout 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/model/edit.html' %} 2 | 3 | {% block tail %} 4 | {{ super() }} 5 | 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

Welcome to the Authentication Demo

5 | {% if current_user.is_authenticated() %} 6 |

Hey {{ current_user.username }}!!

7 | Click here to logout 8 | {% else %} 9 | Click here to login or register 10 | {% endif %} 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.username.label }}: {{ form.username() }}
11 |
{{ form.password.label }}: {{ form.password() }}
12 | 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/register.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.username.label }}: {{ form.username() }}
11 |
{{ form.password.label }}: {{ form.password() }}
12 |
{{ form.confirm.label }}: {{ form.confirm() }}
13 | 14 |
15 |
16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/some-template.html: -------------------------------------------------------------------------------- 1 | This is a template just for demonstration of Flask Admin Views. 2 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/user-create-admin.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.username.label }}: {{ form.username() }}
11 |
{{ form.password.label }}: {{ form.password() }}
12 |
{{ form.admin.label }}: {{ form.admin() }}
13 | 14 |
15 |
16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/user-update-admin.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.username.label }}: {{ form.username() }}
11 |
{{ form.admin.label }}: {{ form.admin() }}
12 | 13 |
14 |
15 | {% endblock %} 16 | 17 | -------------------------------------------------------------------------------- /Module 2/Chapter08/my_app/templates/users-list-admin.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin-home.html' %} 2 | 3 | {% block container %} 4 |

Hey {{ current_user.username }}!! Below is the list of users in system

5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% for user in users %} 18 | 19 | 20 | 21 | 22 | 25 | 28 | 29 | {% endfor %} 30 | 31 |
IDUsernameIs Admin ?
{{ user.id }}{{ user.username }}{{ user.admin }} 23 | Edit 24 | 26 | Delete 27 |
32 | {% endblock %} 33 | -------------------------------------------------------------------------------- /Module 2/Chapter08/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from flask import Flask 3 | from flask.ext.sqlalchemy import SQLAlchemy 4 | from flask.ext.babel import Babel 5 | 6 | 7 | ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) 8 | 9 | ALLOWED_LANGUAGES = { 10 | 'en': 'English', 11 | 'fr': 'French', 12 | } 13 | 14 | app = Flask(__name__) 15 | app.config['UPLOAD_FOLDER'] = os.path.realpath('.') + '/my_app/static/uploads' 16 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' 17 | app.config['WTF_CSRF_SECRET_KEY'] = 'random key for form' 18 | db = SQLAlchemy(app) 19 | 20 | 21 | babel = Babel(app) 22 | 23 | app.secret_key = 'some_random_key' 24 | 25 | from my_app.catalog.views import catalog 26 | app.register_blueprint(catalog) 27 | 28 | db.create_all() 29 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/babel.cfg: -------------------------------------------------------------------------------- 1 | [python: catalog/**.py] 2 | [jinja2: templates/**.html] 3 | extensions=jinja2.ext.autoescape,jinja2.ext.with_ 4 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/catalog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter09/my_app/catalog/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/static/uploads/apple-iphone-5-front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter09/my_app/static/uploads/apple-iphone-5-front.jpg -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

Hola Friend! Looks like in your quest you have reached a location which does not exist yet.

6 |

To continue, either check your map location (URL) or go back home

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/templates/categories.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for category in categories %} 6 | 7 |

{{ category.name }}

8 |
9 | {% endfor %} 10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/templates/category-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
6 | {{ form.csrf_token }} 7 |
{{ form.name.label }}: {{ form.name() }}
8 | 9 |
10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ category.name }}

6 |
7 | {% for product in category.products %} 8 |

9 | {{ product.name }} 10 | $ {{ product.price }} 11 |

12 | {% endfor %} 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

{{ _('Welcome to the Catalog Home') }}

5 | 6 | {{ _('Click here to see the catalog ') }} 7 | 8 | {% endblock %} 9 | 10 | {% block scripts %} 11 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/templates/product-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.name.label }}: {{ form.name() }}
11 |
{{ form.price.label }}: {{ form.price() }}
12 |
{{ form.category.label }}: {{ form.category() }}
13 |
{{ form.image.label }}: {{ form.image(style='display:inline;') }}
14 | 15 |
16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/templates/product.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | 6 |

{{ product.name }} {{ product.category.name }}

7 |

{{ product.price }}

8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/templates/products.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for product in products.items %} 6 |
7 |

8 | {{ product.name }} 9 | $ {{ product.price }} 10 |

11 |
12 | {% endfor %} 13 | {% if products.has_prev %} 14 | 15 | {{_("<< Previous Page")}} 16 | 17 | {% else %} 18 | {{_("No Previous Page")}} 19 | {% endif %} 20 | {{ ngettext('%(num)d page', '%(num)d pages', products.pages) }} | 21 | {% if products.has_next %} 22 | 23 | {{_("Next page >>")}} 24 | 25 | {% else %} 26 | {{_("No Next page")}} 27 | {% endif %} 28 |
29 | {% endblock %} 30 | -------------------------------------------------------------------------------- /Module 2/Chapter09/my_app/translations/fr/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter09/my_app/translations/fr/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /Module 2/Chapter09/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter10/coverage/keybd_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter10/coverage/keybd_closed.png -------------------------------------------------------------------------------- /Module 2/Chapter10/coverage/keybd_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter10/coverage/keybd_open.png -------------------------------------------------------------------------------- /Module 2/Chapter10/generate_profile.py: -------------------------------------------------------------------------------- 1 | from werkzeug.contrib.profiler import ProfilerMiddleware 2 | from my_app import app 3 | 4 | app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions = [10]) 5 | app.run(debug=True) 6 | -------------------------------------------------------------------------------- /Module 2/Chapter10/htmlcov/keybd_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter10/htmlcov/keybd_closed.png -------------------------------------------------------------------------------- /Module 2/Chapter10/htmlcov/keybd_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter10/htmlcov/keybd_open.png -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/babel.cfg: -------------------------------------------------------------------------------- 1 | [python: catalog/**.py] 2 | [jinja2: templates/**.html] 3 | extensions=jinja2.ext.autoescape,jinja2.ext.with_ 4 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/catalog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter10/my_app/catalog/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/static/uploads/apple-iphone-5-front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter10/my_app/static/uploads/apple-iphone-5-front.jpg -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

Hola Friend! Looks like in your quest you have reached a location which does not exist yet.

6 |

To continue, either check your map location (URL) or go back home

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/templates/categories.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for category in categories %} 6 | 7 |

{{ category.name }}

8 |
9 | {% endfor %} 10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/templates/category-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
6 | {{ form.csrf_token }} 7 |
{{ form.name.label }}: {{ form.name() }}
8 | 9 |
10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ category.name }}

6 |
7 | {% for product in category.products %} 8 |

9 | {{ product.name }} 10 | $ {{ product.price }} 11 |

12 | {% endfor %} 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

{{ _('Welcome to the Catalog Home') }}

5 | 6 | {{ _('Click here to see the catalog ') }} 7 | 8 | {% endblock %} 9 | 10 | {% block scripts %} 11 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/templates/product-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.name.label }}: {{ form.name() }}
11 |
{{ form.price.label }}: {{ form.price() }}
12 |
{{ form.category.label }}: {{ form.category() }}
13 |
{{ form.image.label }}: {{ form.image(style='display:inline;') }}
14 | 15 |
16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/templates/product.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | 6 |

{{ product.name }} {{ product.category.name }}

7 |

{{ product.price }}

8 |

{{ product.user_timezone }}

9 |
10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/templates/products.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for product in products.items %} 6 |
7 |

8 | {{ product.name }} 9 | $ {{ product.price }} 10 |

11 |
12 | {% endfor %} 13 | {% if products.has_prev %} 14 | 15 | {{_("<< Previous Page")}} 16 | 17 | {% else %} 18 | {{_("No Previous Page")}} 19 | {% endif %} 20 | {{ ngettext('%(num)d page', '%(num)d pages', products.pages) }} | 21 | {% if products.has_next %} 22 | 23 | {{_("Next Page >>")}} 24 | 25 | {% else %} 26 | {{_("No Next Page")}} 27 | {% endif %} 28 |
29 | {% endblock %} 30 | -------------------------------------------------------------------------------- /Module 2/Chapter10/my_app/translations/fr/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter10/my_app/translations/fr/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /Module 2/Chapter10/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter11/MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include my_app/templates * 2 | recursive-include my_app/static * 3 | recursive-include my_app/translations * 4 | -------------------------------------------------------------------------------- /Module 2/Chapter11/Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn -w 4 my_app:app --debug --log-level debug 2 | -------------------------------------------------------------------------------- /Module 2/Chapter11/apache_wsgi.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | WSGIScriptAlias / /Users/shalabhaggarwal/workspace/mydev/flask_catalog_deployment/app.wsgi 4 | 5 | 6 | Order allow,deny 7 | Allow from all 8 | 9 | 10 | Alias /static/uploads/ "/Users/shalabhaggarwal/workspace/mydev/flask_test_uploads/" 11 | 12 | Order allow,deny 13 | Options Indexes 14 | Allow from all 15 | IndexOptions FancyIndexing 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Module 2/Chapter11/app.wsgi: -------------------------------------------------------------------------------- 1 | activate_this = '/Users/shalabhaggarwal/workspace/mydev/bin/activate_this.py' 2 | execfile(activate_this, dict(__file__=activate_this)) 3 | 4 | from my_app import app as application 5 | import sys, logging 6 | logging.basicConfig(stream = sys.stderr) 7 | -------------------------------------------------------------------------------- /Module 2/Chapter11/application.py: -------------------------------------------------------------------------------- 1 | from my_app import app as application 2 | import sys, logging 3 | logging.basicConfig(stream = sys.stderr) 4 | -------------------------------------------------------------------------------- /Module 2/Chapter11/coverage/keybd_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter11/coverage/keybd_closed.png -------------------------------------------------------------------------------- /Module 2/Chapter11/coverage/keybd_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter11/coverage/keybd_open.png -------------------------------------------------------------------------------- /Module 2/Chapter11/fabfile.py: -------------------------------------------------------------------------------- 1 | from fabric.api import sudo, cd, prefix, run, settings 2 | 3 | def deploy_app(): 4 | "Deploy to the server specified" 5 | root_path = '/usr/local/my_env' 6 | 7 | with cd(root_path): 8 | with prefix("source %s/bin/activate" % root_path): 9 | with cd('flask_catalog_deployment'): 10 | run('git pull') 11 | run('python setup.py install') 12 | 13 | sudo('bin/supervisorctl restart all') 14 | 15 | def deploy_app_to_server(): 16 | "Deploy to the server hardcoded" 17 | with settings(host_string='my.remote.server'): 18 | deploy_app() 19 | 20 | -------------------------------------------------------------------------------- /Module 2/Chapter11/generate_profile.py: -------------------------------------------------------------------------------- 1 | from werkzeug.contrib.profiler import ProfilerMiddleware 2 | from my_app import app 3 | 4 | app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions = [10]) 5 | app.run(debug=True) 6 | -------------------------------------------------------------------------------- /Module 2/Chapter11/htmlcov/keybd_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter11/htmlcov/keybd_closed.png -------------------------------------------------------------------------------- /Module 2/Chapter11/htmlcov/keybd_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter11/htmlcov/keybd_open.png -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/babel.cfg: -------------------------------------------------------------------------------- 1 | [python: catalog/**.py] 2 | [jinja2: templates/**.html] 3 | extensions=jinja2.ext.autoescape,jinja2.ext.with_ 4 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/catalog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter11/my_app/catalog/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/static/uploads/apple-iphone-5-front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter11/my_app/static/uploads/apple-iphone-5-front.jpg -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

Hola Friend! Looks like in your quest you have reached a location which does not exist yet.

6 |

To continue, either check your map location (URL) or go back home

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/templates/categories.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for category in categories %} 6 | 7 |

{{ category.name }}

8 |
9 | {% endfor %} 10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/templates/category-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
6 | {{ form.csrf_token }} 7 |
{{ form.name.label }}: {{ form.name() }}
8 | 9 |
10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ category.name }}

6 |
7 | {% for product in category.products %} 8 |

9 | {{ product.name }} 10 | $ {{ product.price }} 11 |

12 | {% endfor %} 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

{{ _('Welcome to the Catalog Home') }}

5 | 6 | {{ _('Click here to see the catalog ') }} 7 | 8 | {% endblock %} 9 | 10 | {% block scripts %} 11 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/templates/product-create.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |
9 | {{ form.csrf_token }} 10 |
{{ form.name.label }}: {{ form.name() }}
11 |
{{ form.price.label }}: {{ form.price() }}
12 |
{{ form.category.label }}: {{ form.category() }}
13 |
{{ form.image.label }}: {{ form.image(style='display:inline;') }}
14 | 15 |
16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/templates/product.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | 6 |

{{ product.name }} {{ product.category.name }}

7 |

{{ product.price }}

8 |

{{ product.user_timezone }}

9 |
10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/templates/products.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for product in products.items %} 6 |
7 |

8 | {{ product.name }} 9 | $ {{ product.price }} 10 |

11 |
12 | {% endfor %} 13 | {% if products.has_prev %} 14 | 15 | {{_("<< Previous Page")}} 16 | 17 | {% else %} 18 | {{_("No Previous Page")}} 19 | {% endif %} 20 | {{ ngettext('%(num)d page', '%(num)d pages', products.pages) }} | 21 | {% if products.has_next %} 22 | 23 | {{_("Next Page >>")}} 24 | 25 | {% else %} 26 | {{_("No Next Page")}} 27 | {% endif %} 28 |
29 | {% endblock %} 30 | -------------------------------------------------------------------------------- /Module 2/Chapter11/my_app/translations/fr/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter11/my_app/translations/fr/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /Module 2/Chapter11/nginx-wsgi.conf: -------------------------------------------------------------------------------- 1 | location / { 2 | include uwsgi_params; 3 | uwsgi_pass 127.0.0.1:9090; 4 | } 5 | location /static/uploads/ { 6 | alias /Users/shalabhaggarwal/workspace/mydev/flask_test_uploads/; 7 | } 8 | -------------------------------------------------------------------------------- /Module 2/Chapter11/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.10.1 2 | Flask-Restless==0.14.0 3 | Flask-SQLAlchemy==1.0 4 | Flask-WTF==0.10.0 5 | Jinja2==2.7.3 6 | MarkupSafe==0.23 7 | SQLAlchemy==0.9.7 8 | WTForms==2.0.1 9 | Werkzeug==0.9.6 10 | boto==2.32.1 11 | gunicorn==19.1.1 12 | itsdangerous==0.24 13 | mimerender==0.5.4 14 | python-dateutil==2.2 15 | python-geoip==1.2 16 | python-geoip-geolite2==2014.0207 17 | python-mimeparse==0.1.4 18 | six==1.7.3 19 | wsgiref==0.1.2 20 | -------------------------------------------------------------------------------- /Module 2/Chapter11/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 2/Chapter11/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | import os 4 | from setuptools import setup 5 | 6 | setup( 7 | name = 'my_app', 8 | version='1.0', 9 | license='GNU General Public License v3', 10 | author='Shalabh Aggarwal', 11 | author_email='contact@shalabhaggarwal.com', 12 | description='Catalog application for Flask', 13 | packages=[ 14 | 'my_app', 15 | 'my_app.catalog', 16 | ], 17 | platforms='any', 18 | install_requires=[ 19 | 'flask', 20 | 'flask-sqlalchemy', 21 | 'flask-wtf' 22 | ], 23 | include_package_data=True, 24 | classifiers=[ 25 | 'Development Status :: 4 - Beta', 26 | 'Environment :: Web Environment', 27 | 'Intended Audience :: Developers', 28 | 'License :: OSI Approved :: GNU General Public License v3', 29 | 'Operating System :: OS Independent', 30 | 'Programming Language :: Python', 31 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 32 | 'Topic :: Software Development :: Libraries :: Python Modules' 33 | ], 34 | zip_safe = False, 35 | ) 36 | -------------------------------------------------------------------------------- /Module 2/Chapter11/tornado_server.py: -------------------------------------------------------------------------------- 1 | from tornado.wsgi import WSGIContainer 2 | from tornado.httpserver import HTTPServer 3 | from tornado.ioloop import IOLoop 4 | from my_app import app 5 | 6 | http_server = HTTPServer(WSGIContainer(app)) 7 | http_server.listen(5000) 8 | IOLoop.instance().start() 9 | -------------------------------------------------------------------------------- /Module 2/Chapter11/uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | socket = :9090 3 | plugin = python 4 | wsgi-file = /Users/shalabhaggarwal/workspace/mydev/flask_catalog_deployment/app.wsgi 5 | processes = 3 6 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/catalog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 2/Chapter12/my_app/catalog/__init__.py -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .top-pad { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

Hola Friend! Looks like in your quest you have reached a location which does not exist yet.

6 |

To continue, either check your map location (URL) or go back home

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/templates/categories.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for category in categories %} 6 | 7 |

{{ category.name }}

8 |
9 | {% endfor %} 10 |
11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/templates/category-create-email-html.html: -------------------------------------------------------------------------------- 1 |

A new category has been added to the catalog.

2 | 3 |

The name of the category is 4 |

{{ category.name }}

5 | . 6 |

7 | 8 |

This is an automated email. Do not reply to it.

9 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/templates/category-create-email-text.html: -------------------------------------------------------------------------------- 1 | A new category has been added to the catalog. 2 | 3 | The name of the category is {{ category.name }}. 4 | Click on the URL below to acces the same: 5 | {{ url_for('catalog.category', id=category.id, _external = True) }} 6 | 7 | This is an automated email. Do not reply to it. 8 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ category.name }}

6 |
7 | {% for product in category.products %} 8 |

9 | {{ product.name }} 10 | $ {{ product.price }} 11 |

12 | {% endfor %} 13 |
14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block container %} 4 |

Welcome to the Catalog Home

5 | 6 | Click here to see the catalog 7 | 8 | {% endblock %} 9 | 10 | {% block scripts %} 11 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/templates/product.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 |

{{ product.name }} {{ product.category.name }}

6 |

{{ product.company }}

7 |

{{ product.price }}

8 |
9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /Module 2/Chapter12/my_app/templates/products.html: -------------------------------------------------------------------------------- 1 | {% extends 'home.html' %} 2 | 3 | {% block container %} 4 |
5 | {% for product in products.items %} 6 |
7 |

8 | {{ product.name }} 9 | $ {{ product.price }} 10 |

11 |
12 | {% endfor %} 13 | {% if products.has_prev %} 14 | 15 | {{"<< Previous Page"}} 16 | 17 | {% else %} 18 | {{"<< Previous Page"}} 19 | {% endif %} | 20 | {% if products.has_next %} 21 | 22 | {{"Next page >>"}} 23 | 24 | {% else %} 25 | {{"Next page >>"}} 26 | {% endif %} 27 |
28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /Module 2/Chapter12/run.py: -------------------------------------------------------------------------------- 1 | from my_app import app 2 | app.run(debug=True) 3 | -------------------------------------------------------------------------------- /Module 3/Chapter01/chapter_1/config.py: -------------------------------------------------------------------------------- 1 | class DevConfig(object): 2 | DEBUG = True 3 | -------------------------------------------------------------------------------- /Module 3/Chapter01/chapter_1/main.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from config import DevConfig 3 | 4 | app = Flask(__name__) 5 | app.config.from_object(DevConfig) 6 | 7 | 8 | @app.route('/') 9 | def home(): 10 | return '

Hello World!

' 11 | 12 | if __name__ == '__main__': 13 | app.run() 14 | -------------------------------------------------------------------------------- /Module 3/Chapter01/chapter_1/manage.py: -------------------------------------------------------------------------------- 1 | from flask.ext.script import Manager, Server 2 | from main import app 3 | 4 | manager = Manager(app) 5 | manager.add_command("server", Server()) 6 | 7 | @manager.shell 8 | def make_shell_context(): 9 | return dict(app=app) 10 | 11 | if __name__ == "__main__": 12 | manager.run() 13 | -------------------------------------------------------------------------------- /Module 3/Chapter02/chapter_2/config.py: -------------------------------------------------------------------------------- 1 | class DevConfig(object): 2 | DEBUG = True 3 | SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db' 4 | -------------------------------------------------------------------------------- /Module 3/Chapter02/chapter_2/manage.py: -------------------------------------------------------------------------------- 1 | from flask.ext.script import Manager, Server 2 | from flask.ext.migrate import Migrate, MigrateCommand 3 | 4 | from main import app, db, User, Post, Tag 5 | 6 | migrate = Migrate(app, db) 7 | 8 | manager = Manager(app) 9 | manager.add_command("server", Server()) 10 | manager.add_command('db', MigrateCommand) 11 | 12 | 13 | @manager.shell 14 | def make_shell_context(): 15 | return dict(app=app, db=db, User=User, Post=Post, Tag=Tag) 16 | 17 | if __name__ == "__main__": 18 | manager.run() 19 | -------------------------------------------------------------------------------- /Module 3/Chapter02/chapter_2/migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /Module 3/Chapter02/chapter_2/migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /Module 3/Chapter02/chapter_2/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /Module 3/Chapter03/chapter_3/config.py: -------------------------------------------------------------------------------- 1 | class Config(object): 2 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 3 | 4 | 5 | class ProdConfig(Config): 6 | SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db' 7 | 8 | 9 | class DevConfig(Config): 10 | DEBUG = True 11 | SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db' 12 | -------------------------------------------------------------------------------- /Module 3/Chapter03/chapter_3/manage.py: -------------------------------------------------------------------------------- 1 | from flask.ext.script import Manager, Server 2 | from flask.ext.migrate import Migrate, MigrateCommand 3 | 4 | from main import app, db, User, Post, Tag, Comment 5 | 6 | migrate = Migrate(app, db) 7 | 8 | manager = Manager(app) 9 | manager.add_command("server", Server()) 10 | manager.add_command('db', MigrateCommand) 11 | 12 | 13 | @manager.shell 14 | def make_shell_context(): 15 | return dict( 16 | app=app, 17 | db=db, 18 | User=User, 19 | Post=Post, 20 | Tag=Tag, 21 | Comment=Comment 22 | ) 23 | 24 | if __name__ == "__main__": 25 | manager.run() 26 | -------------------------------------------------------------------------------- /Module 3/Chapter03/chapter_3/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter03/chapter_3/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter03/chapter_3/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter03/chapter_3/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter03/chapter_3/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter03/chapter_3/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter03/chapter_3/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter03/chapter_3/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter03/chapter_3/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 3/Chapter04/chapter_4/config.py: -------------------------------------------------------------------------------- 1 | class Config(object): 2 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 3 | 4 | 5 | class ProdConfig(Config): 6 | SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db' 7 | 8 | 9 | class DevConfig(Config): 10 | DEBUG = True 11 | SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db' 12 | -------------------------------------------------------------------------------- /Module 3/Chapter04/chapter_4/manage.py: -------------------------------------------------------------------------------- 1 | from flask.ext.script import Manager, Server 2 | from flask.ext.migrate import Migrate, MigrateCommand 3 | 4 | from main import app, db, User, Post, Tag, Comment 5 | 6 | migrate = Migrate(app, db) 7 | 8 | manager = Manager(app) 9 | manager.add_command("server", Server()) 10 | manager.add_command('db', MigrateCommand) 11 | 12 | 13 | @manager.shell 14 | def make_shell_context(): 15 | return dict( 16 | app=app, 17 | db=db, 18 | User=User, 19 | Post=Post, 20 | Tag=Tag, 21 | Comment=Comment 22 | ) 23 | 24 | if __name__ == "__main__": 25 | manager.run() 26 | -------------------------------------------------------------------------------- /Module 3/Chapter04/chapter_4/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter04/chapter_4/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter04/chapter_4/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter04/chapter_4/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter04/chapter_4/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter04/chapter_4/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter04/chapter_4/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter04/chapter_4/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter04/chapter_4/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/manage.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from flask.ext.script import Manager, Server 4 | from flask.ext.script.commands import ShowUrls 5 | from flask.ext.migrate import Migrate, MigrateCommand 6 | 7 | from webapp import create_app 8 | from webapp.models import db, User, Post, Tag, Comment 9 | 10 | # default to dev config 11 | env = os.environ.get('WEBAPP_ENV', 'dev') 12 | app = create_app('webapp.config.%sConfig' % env.capitalize()) 13 | 14 | migrate = Migrate(app, db) 15 | 16 | manager = Manager(app) 17 | manager.add_command("server", Server()) 18 | manager.add_command("show-urls", ShowUrls()) 19 | manager.add_command('db', MigrateCommand) 20 | 21 | 22 | @manager.shell 23 | def make_shell_context(): 24 | return dict( 25 | app=app, 26 | db=db, 27 | User=User, 28 | Post=Post, 29 | Tag=Tag, 30 | Comment=Comment 31 | ) 32 | 33 | if __name__ == "__main__": 34 | manager.run() 35 | -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | 3 | from models import db 4 | from controllers.main import main_blueprint 5 | from controllers.blog import blog_blueprint 6 | 7 | 8 | def create_app(object_name): 9 | """ 10 | An flask application factory, as explained here: 11 | http://flask.pocoo.org/docs/patterns/appfactories/ 12 | 13 | Arguments: 14 | object_name: the python path of the config object, 15 | e.g. project.config.ProdConfig 16 | """ 17 | 18 | app = Flask(__name__) 19 | app.config.from_object(object_name) 20 | 21 | db.init_app(app) 22 | 23 | app.register_blueprint(main_blueprint) 24 | app.register_blueprint(blog_blueprint) 25 | 26 | return app 27 | 28 | if __name__ == '__main__': 29 | app = app = create_app('project.config.ProdConfig') 30 | app.run() 31 | -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/config.py: -------------------------------------------------------------------------------- 1 | class Config(object): 2 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 3 | 4 | 5 | class ProdConfig(Config): 6 | SQLALCHEMY_DATABASE_URI = 'sqlite://../database.db' 7 | 8 | 9 | class DevConfig(Config): 10 | DEBUG = True 11 | SQLALCHEMY_DATABASE_URI = 'sqlite:///../database.db' 12 | -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter05/chapter_5/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/controllers/main.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint, redirect, url_for 2 | 3 | main_blueprint = Blueprint( 4 | 'main', 5 | __name__, 6 | template_folder='../templates/main' 7 | ) 8 | 9 | 10 | @main_blueprint.route('/') 11 | def index(): 12 | return redirect(url_for('blog.home')) 13 | -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/forms.py: -------------------------------------------------------------------------------- 1 | from flask_wtf import Form 2 | from wtforms import StringField, TextAreaField 3 | from wtforms.validators import DataRequired, Length 4 | 5 | 6 | class CommentForm(Form): 7 | name = StringField( 8 | 'Name', 9 | validators=[DataRequired(), Length(max=255)] 10 | ) 11 | text = TextAreaField(u'Comment', validators=[DataRequired()]) 12 | -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter05/chapter_5/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter05/chapter_5/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter05/chapter_5/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter05/chapter_5/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter05/chapter_5/webapp/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 3/Chapter06/Chapter 6/chapter_6/manage.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from flask.ext.script import Manager, Server 4 | from flask.ext.migrate import Migrate, MigrateCommand 5 | 6 | from webapp import create_app 7 | from webapp.models import db, User, Post, Tag, Comment 8 | 9 | # default to dev config 10 | env = os.environ.get('WEBAPP_ENV', 'dev') 11 | app = create_app('webapp.config.%sConfig' % env.capitalize()) 12 | 13 | migrate = Migrate(app, db) 14 | 15 | manager = Manager(app) 16 | manager.add_command("server", Server()) 17 | manager.add_command('db', MigrateCommand) 18 | 19 | 20 | @manager.shell 21 | def make_shell_context(): 22 | return dict( 23 | app=app, 24 | db=db, 25 | User=User, 26 | Post=Post, 27 | Tag=Tag, 28 | Comment=Comment 29 | ) 30 | 31 | if __name__ == "__main__": 32 | manager.run() 33 | -------------------------------------------------------------------------------- /Module 3/Chapter06/Chapter 6/chapter_6/webapp/config.py: -------------------------------------------------------------------------------- 1 | class Config(object): 2 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 3 | RECAPTCHA_PUBLIC_KEY = "6LdKkQQTAAAAAEH0GFj7NLg5tGicaoOus7G9Q5Uw" 4 | RECAPTCHA_PRIVATE_KEY = '6LdKkQQTAAAAAMYroksPTJ7pWhobYb88fTAcxcYn' 5 | 6 | 7 | class ProdConfig(Config): 8 | SQLALCHEMY_DATABASE_URI = 'sqlite://../database.db' 9 | 10 | 11 | class DevConfig(Config): 12 | DEBUG = True 13 | SQLALCHEMY_DATABASE_URI = 'sqlite:///../database.db' 14 | -------------------------------------------------------------------------------- /Module 3/Chapter06/Chapter 6/chapter_6/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter06/Chapter 6/chapter_6/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter06/Chapter 6/chapter_6/webapp/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 3/Chapter07/chapter_7/manage.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from flask.ext.script import Manager, Server 4 | from flask.ext.migrate import Migrate, MigrateCommand 5 | 6 | from webapp import create_app 7 | from webapp.models import db, User, Post, Tag, Comment 8 | 9 | # default to dev config 10 | env = os.environ.get('WEBAPP_ENV', 'dev') 11 | app = create_app('webapp.config.%sConfig' % env.capitalize()) 12 | 13 | migrate = Migrate(app, db) 14 | 15 | manager = Manager(app) 16 | manager.add_command("server", Server()) 17 | manager.add_command('db', MigrateCommand) 18 | 19 | 20 | @manager.shell 21 | def make_shell_context(): 22 | return dict( 23 | app=app, 24 | db=db, 25 | User=User, 26 | Post=Post, 27 | Tag=Tag, 28 | Comment=Comment 29 | ) 30 | 31 | if __name__ == "__main__": 32 | manager.run() 33 | -------------------------------------------------------------------------------- /Module 3/Chapter07/chapter_7/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.10.1 2 | 3 | # Flask Extensions 4 | Flask-Assets==0.10 5 | Flask-Bcrypt==0.6.2 6 | Flask-Cache==0.13.1 7 | Flask-DebugToolbar==0.10.0 8 | Flask-Login==0.2.11 9 | Flask-Migrate==1.3.1 10 | Flask-OAuth==0.12 11 | Flask-OpenID==1.2.4 12 | Flask-Principal==0.4.0 13 | Flask-Script==2.0.5 14 | Flask-SQLAlchemy==2.0 15 | Flask-WTF==0.11 16 | 17 | # Other 18 | itsdangerous==0.24 19 | cssmin==0.2.0 20 | jsmin==2.1.1 21 | 22 | # Testing 23 | pytest==2.7.0 24 | pytest-cov==1.8.1 25 | mccabe==0.3 26 | flake8==2.4.0 -------------------------------------------------------------------------------- /Module 3/Chapter07/chapter_7/webapp/config.py: -------------------------------------------------------------------------------- 1 | class Config(object): 2 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 3 | RECAPTCHA_PUBLIC_KEY = "6LdKkQQTAAAAAEH0GFj7NLg5tGicaoOus7G9Q5Uw" 4 | RECAPTCHA_PRIVATE_KEY = '6LdKkQQTAAAAAMYroksPTJ7pWhobYb88fTAcxcYn' 5 | 6 | 7 | class ProdConfig(Config): 8 | SQLALCHEMY_DATABASE_URI = 'sqlite://../database.db' 9 | 10 | 11 | class DevConfig(Config): 12 | DEBUG = True 13 | SQLALCHEMY_DATABASE_URI = 'sqlite:///../database.db' 14 | MONGODB_SETTINGS = { 15 | 'db': 'local', 16 | 'host': 'localhost', 17 | 'port': 27017 18 | } 19 | -------------------------------------------------------------------------------- /Module 3/Chapter07/chapter_7/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter07/chapter_7/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter07/chapter_7/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter07/chapter_7/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter07/chapter_7/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter07/chapter_7/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter07/chapter_7/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter07/chapter_7/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter07/chapter_7/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter07/chapter_7/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/manage.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from flask.ext.script import Manager, Server 4 | from flask.ext.migrate import Migrate, MigrateCommand 5 | 6 | from webapp import create_app 7 | from webapp.models import db, User, Post, Tag, Comment 8 | 9 | # default to dev config 10 | env = os.environ.get('WEBAPP_ENV', 'dev') 11 | app = create_app('webapp.config.%sConfig' % env.capitalize()) 12 | 13 | migrate = Migrate(app, db) 14 | 15 | manager = Manager(app) 16 | manager.add_command("server", Server()) 17 | manager.add_command('db', MigrateCommand) 18 | 19 | 20 | @manager.shell 21 | def make_shell_context(): 22 | return dict( 23 | app=app, 24 | db=db, 25 | User=User, 26 | Post=Post, 27 | Tag=Tag, 28 | Comment=Comment 29 | ) 30 | 31 | if __name__ == "__main__": 32 | manager.run() 33 | -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/config.py: -------------------------------------------------------------------------------- 1 | class Config(object): 2 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 3 | RECAPTCHA_PUBLIC_KEY = "6LdKkQQTAAAAAEH0GFj7NLg5tGicaoOus7G9Q5Uw" 4 | RECAPTCHA_PRIVATE_KEY = '6LdKkQQTAAAAAMYroksPTJ7pWhobYb88fTAcxcYn' 5 | 6 | 7 | class ProdConfig(Config): 8 | SQLALCHEMY_DATABASE_URI = 'sqlite://../database.db' 9 | 10 | 11 | class DevConfig(Config): 12 | DEBUG = True 13 | SQLALCHEMY_DATABASE_URI = 'sqlite:///../database.db' 14 | -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter08/chapter_8/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/controllers/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter08/chapter_8/webapp/controllers/rest/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/controllers/rest/auth.py: -------------------------------------------------------------------------------- 1 | from flask import abort, current_app 2 | from flask.ext.restful import Resource 3 | 4 | from webapp.models import User 5 | from .parsers import user_post_parser 6 | 7 | from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 8 | 9 | 10 | class AuthApi(Resource): 11 | def post(self): 12 | args = user_post_parser.parse_args() 13 | user = User.query.filter_by(username=args['username']).one() 14 | 15 | if user.check_password(args['password']): 16 | s = Serializer(current_app.config['SECRET_KEY'], expires_in=604800) 17 | return {"token": s.dumps({'id': user.id})} 18 | else: 19 | abort(401) 20 | -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/controllers/rest/fields.py: -------------------------------------------------------------------------------- 1 | from HTMLParser import HTMLParser 2 | from flask.ext.restful import fields 3 | 4 | 5 | class HTMLStripper(HTMLParser): 6 | def __init__(self): 7 | self.reset() 8 | self.fed = [] 9 | 10 | def handle_data(self, d): 11 | self.fed.append(d) 12 | 13 | def get_data(self): 14 | return ''.join(self.fed) 15 | 16 | 17 | def strip_tags(html): 18 | s = HTMLStripper() 19 | s.feed(html) 20 | 21 | return s.get_data() 22 | 23 | 24 | class HTMLField(fields.Raw): 25 | def format(self, value): 26 | return strip_tags(str(value)) 27 | -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter08/chapter_8/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter08/chapter_8/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter08/chapter_8/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter08/chapter_8/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter08/chapter_8/webapp/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/celery_runner.py: -------------------------------------------------------------------------------- 1 | import os 2 | from webapp import create_app 3 | from celery import Celery 4 | 5 | 6 | def make_celery(app): 7 | celery = Celery( 8 | app.import_name, 9 | broker=app.config['CELERY_BROKER_URL'], 10 | backend=app.config['CELERY_BACKEND_URL'] 11 | ) 12 | celery.conf.update(app.config) 13 | TaskBase = celery.Task 14 | 15 | class ContextTask(TaskBase): 16 | abstract = True 17 | 18 | def __call__(self, *args, **kwargs): 19 | with app.app_context(): 20 | return TaskBase.__call__(self, *args, **kwargs) 21 | 22 | celery.Task = ContextTask 23 | 24 | return celery 25 | 26 | env = os.environ.get('WEBAPP_ENV', 'dev') 27 | flask_app = create_app('webapp.config.%sConfig' % env.capitalize()) 28 | 29 | celery = make_celery(flask_app) 30 | -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/manage.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from flask.ext.script import Manager, Server 4 | from flask.ext.migrate import Migrate, MigrateCommand 5 | 6 | from webapp import create_app 7 | from webapp.models import db, User, Post, Tag, Comment 8 | 9 | # default to dev config 10 | env = os.environ.get('WEBAPP_ENV', 'dev') 11 | app = create_app('webapp.config.%sConfig' % env.capitalize()) 12 | 13 | migrate = Migrate(app, db) 14 | 15 | manager = Manager(app) 16 | manager.add_command("server", Server()) 17 | manager.add_command('db', MigrateCommand) 18 | 19 | 20 | @manager.shell 21 | def make_shell_context(): 22 | return dict( 23 | app=app, 24 | db=db, 25 | User=User, 26 | Post=Post, 27 | Tag=Tag, 28 | Comment=Comment 29 | ) 30 | 31 | if __name__ == "__main__": 32 | manager.run() 33 | -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/config.py: -------------------------------------------------------------------------------- 1 | from celery.schedules import crontab 2 | 3 | 4 | class Config(object): 5 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 6 | RECAPTCHA_PUBLIC_KEY = "6LdKkQQTAAAAAEH0GFj7NLg5tGicaoOus7G9Q5Uw" 7 | RECAPTCHA_PRIVATE_KEY = '6LdKkQQTAAAAAMYroksPTJ7pWhobYb88fTAcxcYn' 8 | 9 | 10 | class ProdConfig(Config): 11 | SQLALCHEMY_DATABASE_URI = 'sqlite://../database.db' 12 | 13 | 14 | class DevConfig(Config): 15 | DEBUG = True 16 | SQLALCHEMY_DATABASE_URI = 'sqlite:///../database.db' 17 | CELERY_BROKER_URL = "amqp://guest:guest@localhost:5672//" 18 | CELERY_BACKEND_URL = "amqp://guest:guest@localhost:5672//" 19 | 20 | CELERYBEAT_SCHEDULE = { 21 | 'weekly-digest': { 22 | 'task': 'tasks.digest', 23 | 'schedule': crontab(day_of_week=6, hour='10') 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter09/chapter_9/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/controllers/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter09/chapter_9/webapp/controllers/rest/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/controllers/rest/auth.py: -------------------------------------------------------------------------------- 1 | from flask import abort, current_app 2 | from flask.ext.restful import Resource 3 | 4 | from webapp.models import User 5 | from .parsers import user_post_parser 6 | 7 | from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 8 | 9 | 10 | class AuthApi(Resource): 11 | def post(self): 12 | args = user_post_parser.parse_args() 13 | user = User.query.filter_by(username=args['username']).one() 14 | 15 | if user.check_password(args['password']): 16 | s = Serializer(current_app.config['SECRET_KEY'], expires_in=604800) 17 | return {"token": s.dumps({'id': user.id})} 18 | else: 19 | abort(401) 20 | -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/controllers/rest/fields.py: -------------------------------------------------------------------------------- 1 | from HTMLParser import HTMLParser 2 | from flask.ext.restful import fields 3 | 4 | 5 | class HTMLStripper(HTMLParser): 6 | def __init__(self): 7 | self.reset() 8 | self.fed = [] 9 | 10 | def handle_data(self, d): 11 | self.fed.append(d) 12 | 13 | def get_data(self): 14 | return ''.join(self.fed) 15 | 16 | 17 | def strip_tags(html): 18 | s = HTMLStripper() 19 | s.feed(html) 20 | 21 | return s.get_data() 22 | 23 | 24 | class HTMLField(fields.Raw): 25 | def format(self, value): 26 | return strip_tags(str(value)) 27 | -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter09/chapter_9/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter09/chapter_9/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter09/chapter_9/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter09/chapter_9/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter09/chapter_9/webapp/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/celery_runner.py: -------------------------------------------------------------------------------- 1 | import os 2 | from webapp import create_app 3 | from celery import Celery 4 | 5 | 6 | def make_celery(app): 7 | celery = Celery( 8 | app.import_name, 9 | broker=app.config['CELERY_BROKER_URL'], 10 | backend=app.config['CELERY_BACKEND_URL'] 11 | ) 12 | celery.conf.update(app.config) 13 | TaskBase = celery.Task 14 | 15 | class ContextTask(TaskBase): 16 | abstract = True 17 | 18 | def __call__(self, *args, **kwargs): 19 | with app.app_context(): 20 | return TaskBase.__call__(self, *args, **kwargs) 21 | 22 | celery.Task = ContextTask 23 | 24 | return celery 25 | 26 | env = os.environ.get('WEBAPP_ENV', 'dev') 27 | flask_app = create_app('webapp.config.%sConfig' % env.capitalize()) 28 | 29 | celery = make_celery(flask_app) 30 | -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/config.py: -------------------------------------------------------------------------------- 1 | from celery.schedules import crontab 2 | 3 | 4 | class Config(object): 5 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 6 | RECAPTCHA_PUBLIC_KEY = "6LdKkQQTAAAAAEH0GFj7NLg5tGicaoOus7G9Q5Uw" 7 | RECAPTCHA_PRIVATE_KEY = '6LdKkQQTAAAAAMYroksPTJ7pWhobYb88fTAcxcYn' 8 | 9 | CELERYBEAT_SCHEDULE = { 10 | 'weekly-digest': { 11 | 'task': 'tasks.digest', 12 | 'schedule': crontab(day_of_week=6, hour='10') 13 | }, 14 | } 15 | 16 | 17 | class ProdConfig(Config): 18 | SQLALCHEMY_DATABASE_URI = 'sqlite://../database.db' 19 | 20 | CACHE_TYPE = 'simple' 21 | 22 | CELERY_BROKER_URL = "amqp://guest:guest@localhost:5672//" 23 | CELERY_BACKEND_URL = "amqp://guest:guest@localhost:5672//" 24 | 25 | 26 | class DevConfig(Config): 27 | DEBUG = True 28 | DEBUG_TB_INTERCEPT_REDIRECTS = False 29 | 30 | ASSETS_DEBUG = True 31 | 32 | SQLALCHEMY_DATABASE_URI = 'sqlite:///../database.db' 33 | 34 | CACHE_TYPE = 'simple' 35 | 36 | CELERY_BROKER_URL = "amqp://guest:guest@localhost:5672//" 37 | CELERY_BACKEND_URL = "amqp://guest:guest@localhost:5672//" 38 | 39 | MAIL_SERVER = 'localhost' 40 | MAIL_PORT = 25 41 | MAIL_USERNAME = 'username' 42 | MAIL_PASSWORD = 'password' 43 | -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter10/Chapter 10/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/controllers/admin.py: -------------------------------------------------------------------------------- 1 | from flask.ext.admin import BaseView, expose 2 | from flask.ext.admin.contrib.sqla import ModelView 3 | from flask.ext.admin.contrib.fileadmin import FileAdmin 4 | from flask.ext.login import login_required, current_user 5 | 6 | from webapp.extensions import admin_permission 7 | from webapp.forms import CKTextAreaField 8 | 9 | 10 | class CustomView(BaseView): 11 | @expose('/') 12 | @login_required 13 | @admin_permission.require(http_exception=403) 14 | def index(self): 15 | return self.render('admin/custom.html') 16 | 17 | @expose('/second_page') 18 | @login_required 19 | @admin_permission.require(http_exception=403) 20 | def second_page(self): 21 | return self.render('admin/second_page.html') 22 | 23 | 24 | class CustomModelView(ModelView): 25 | def is_accessible(self): 26 | return current_user.is_authenticated() and admin_permission.can() 27 | 28 | 29 | class PostView(CustomModelView): 30 | form_overrides = dict(text=CKTextAreaField) 31 | column_searchable_list = ('text', 'title') 32 | column_filters = ('publish_date',) 33 | 34 | create_template = 'admin/post_edit.html' 35 | edit_template = 'admin/post_edit.html' 36 | 37 | 38 | class CustomFileAdmin(FileAdmin): 39 | def is_accessible(self): 40 | return current_user.is_authenticated() and admin_permission.can() 41 | -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/controllers/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter10/Chapter 10/webapp/controllers/rest/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/controllers/rest/auth.py: -------------------------------------------------------------------------------- 1 | from flask import abort, current_app 2 | from flask.ext.restful import Resource 3 | 4 | from webapp.models import User 5 | from .parsers import user_post_parser 6 | 7 | from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 8 | 9 | 10 | class AuthApi(Resource): 11 | def post(self): 12 | args = user_post_parser.parse_args() 13 | user = User.query.filter_by(username=args['username']).one() 14 | 15 | if user.check_password(args['password']): 16 | s = Serializer(current_app.config['SECRET_KEY'], expires_in=604800) 17 | return {"token": s.dumps({'id': user.id})} 18 | else: 19 | abort(401) 20 | -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/controllers/rest/fields.py: -------------------------------------------------------------------------------- 1 | from HTMLParser import HTMLParser 2 | from flask.ext.restful import fields 3 | 4 | 5 | class HTMLStripper(HTMLParser): 6 | def __init__(self): 7 | self.reset() 8 | self.fed = [] 9 | 10 | def handle_data(self, d): 11 | self.fed.append(d) 12 | 13 | def get_data(self): 14 | return ''.join(self.fed) 15 | 16 | 17 | def strip_tags(html): 18 | s = HTMLStripper() 19 | s.feed(html) 20 | 21 | return s.get_data() 22 | 23 | 24 | class HTMLField(fields.Raw): 25 | def format(self, value): 26 | return strip_tags(str(value)) 27 | -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter10/Chapter 10/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter10/Chapter 10/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter10/Chapter 10/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter10/Chapter 10/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/templates/admin/custom.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/master.html' %} 2 | 3 | {% block body %} 4 | This is the custom view! 5 | 6 | Link 7 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/templates/admin/post_edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/model/edit.html' %} 2 | {% block tail %} 3 | {{ super() }} 4 | 5 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter10/Chapter 10/webapp/templates/admin/second_page.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/master.html' %} 2 | 3 | {% block body %} 4 | This is the second page! 5 | 6 | Link 7 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/Flask_YouTube.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: Flask-YouTube 3 | Version: 0.1 4 | Summary: Flask extension to allow easy embedding of YouTube videos 5 | Home-page: UNKNOWN 6 | Author: Jack Stouffer 7 | Author-email: example@gmail.com 8 | License: MIT 9 | Description: UNKNOWN 10 | Platform: any 11 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/Flask_YouTube.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | setup.py 2 | Flask_YouTube.egg-info/PKG-INFO 3 | Flask_YouTube.egg-info/SOURCES.txt 4 | Flask_YouTube.egg-info/dependency_links.txt 5 | Flask_YouTube.egg-info/requires.txt 6 | Flask_YouTube.egg-info/top_level.txt 7 | flask_youtube/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/Flask_YouTube.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/Flask_YouTube.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/Flask_YouTube.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | flask_youtube 2 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/build/lib/flask_youtube/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import render_template, Blueprint, Markup 2 | 3 | 4 | class Video(object): 5 | def __init__(self, video_id, cls="youtube"): 6 | self.video_id = video_id 7 | self.cls = cls 8 | 9 | def render(self, *args, **kwargs): 10 | return render_template(*args, **kwargs) 11 | 12 | @property 13 | def html(self): 14 | return Markup(self.render('youtube/video.html', video=self)) 15 | 16 | 17 | def youtube(*args, **kwargs): 18 | video = Video(*args, **kwargs) 19 | return video.html 20 | 21 | 22 | class Youtube(object): 23 | def __init__(self, app=None, **kwargs): 24 | if app: 25 | self.init_app(app) 26 | 27 | def init_app(self, app): 28 | self.register_blueprint(app) 29 | app.add_template_global(youtube) 30 | 31 | def register_blueprint(self, app): 32 | module = Blueprint( 33 | "youtube", 34 | __name__, 35 | template_folder="templates" 36 | ) 37 | app.register_blueprint(module) 38 | return module 39 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/dist/Flask_YouTube-0.1-py2.7.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter11/Chapter 11/Flask-YouTube/dist/Flask_YouTube-0.1-py2.7.egg -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/flask_youtube/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import render_template, Blueprint, Markup 2 | 3 | 4 | class Video(object): 5 | def __init__(self, video_id, cls="youtube"): 6 | self.video_id = video_id 7 | self.cls = cls 8 | 9 | def render(self, *args, **kwargs): 10 | return render_template(*args, **kwargs) 11 | 12 | @property 13 | def html(self): 14 | return Markup(self.render('youtube/video.html', video=self)) 15 | 16 | 17 | def youtube(*args, **kwargs): 18 | video = Video(*args, **kwargs) 19 | return video.html 20 | 21 | 22 | class Youtube(object): 23 | def __init__(self, app=None, **kwargs): 24 | if app: 25 | self.init_app(app) 26 | 27 | def init_app(self, app): 28 | self.register_blueprint(app) 29 | app.add_template_global(youtube) 30 | 31 | def register_blueprint(self, app): 32 | module = Blueprint( 33 | "youtube", 34 | __name__, 35 | template_folder="templates" 36 | ) 37 | app.register_blueprint(module) 38 | return module 39 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/flask_youtube/templates/youtube/video.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/Flask-YouTube/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='Flask-YouTube', 5 | version='0.1', 6 | license='MIT', 7 | description='Flask extension to allow easy embedding of YouTube videos', 8 | author='Jack Stouffer', 9 | author_email='example@gmail.com', 10 | platforms='any', 11 | install_requires=['Flask'], 12 | packages=find_packages() 13 | ) 14 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/celery_runner.py: -------------------------------------------------------------------------------- 1 | import os 2 | from webapp import create_app 3 | from celery import Celery 4 | 5 | 6 | def make_celery(app): 7 | celery = Celery( 8 | app.import_name, 9 | broker=app.config['CELERY_BROKER_URL'], 10 | backend=app.config['CELERY_BACKEND_URL'] 11 | ) 12 | celery.conf.update(app.config) 13 | TaskBase = celery.Task 14 | 15 | class ContextTask(TaskBase): 16 | abstract = True 17 | 18 | def __call__(self, *args, **kwargs): 19 | with app.app_context(): 20 | return TaskBase.__call__(self, *args, **kwargs) 21 | 22 | celery.Task = ContextTask 23 | 24 | return celery 25 | 26 | env = os.environ.get('WEBAPP_ENV', 'dev') 27 | flask_app = create_app('webapp.config.%sConfig' % env.capitalize()) 28 | 29 | celery = make_celery(flask_app) 30 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/config.py: -------------------------------------------------------------------------------- 1 | from celery.schedules import crontab 2 | 3 | 4 | class Config(object): 5 | SECRET_KEY = '736670cb10a600b695a55839ca3a5aa54a7d7356cdef815d2ad6e19a2031182b' 6 | RECAPTCHA_PUBLIC_KEY = "6LdKkQQTAAAAAEH0GFj7NLg5tGicaoOus7G9Q5Uw" 7 | RECAPTCHA_PRIVATE_KEY = '6LdKkQQTAAAAAMYroksPTJ7pWhobYb88fTAcxcYn' 8 | 9 | CELERYBEAT_SCHEDULE = { 10 | 'weekly-digest': { 11 | 'task': 'tasks.digest', 12 | 'schedule': crontab(day_of_week=6, hour='10') 13 | }, 14 | } 15 | 16 | 17 | class ProdConfig(Config): 18 | SQLALCHEMY_DATABASE_URI = 'sqlite://../database.db' 19 | 20 | CACHE_TYPE = 'simple' 21 | 22 | CELERY_BROKER_URL = "amqp://guest:guest@localhost:5672//" 23 | CELERY_BACKEND_URL = "amqp://guest:guest@localhost:5672//" 24 | 25 | 26 | class DevConfig(Config): 27 | DEBUG = True 28 | DEBUG_TB_INTERCEPT_REDIRECTS = False 29 | 30 | ASSETS_DEBUG = True 31 | 32 | SQLALCHEMY_DATABASE_URI = 'sqlite:///../database.db' 33 | 34 | CACHE_TYPE = 'simple' 35 | 36 | CELERY_BROKER_URL = "amqp://guest:guest@localhost:5672//" 37 | CELERY_BACKEND_URL = "amqp://guest:guest@localhost:5672//" 38 | 39 | MAIL_SERVER = 'localhost' 40 | MAIL_PORT = 25 41 | MAIL_USERNAME = 'username' 42 | MAIL_PASSWORD = 'password' 43 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter11/Chapter 11/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/controllers/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter11/Chapter 11/webapp/controllers/rest/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/controllers/rest/auth.py: -------------------------------------------------------------------------------- 1 | from flask import abort, current_app 2 | from flask.ext.restful import Resource 3 | 4 | from webapp.models import User 5 | from .parsers import user_post_parser 6 | 7 | from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 8 | 9 | 10 | class AuthApi(Resource): 11 | def post(self): 12 | args = user_post_parser.parse_args() 13 | user = User.query.filter_by(username=args['username']).one() 14 | 15 | if user.check_password(args['password']): 16 | s = Serializer(current_app.config['SECRET_KEY'], expires_in=604800) 17 | return {"token": s.dumps({'id': user.id})} 18 | else: 19 | abort(401) 20 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/controllers/rest/fields.py: -------------------------------------------------------------------------------- 1 | from HTMLParser import HTMLParser 2 | from flask.ext.restful import fields 3 | 4 | 5 | class HTMLStripper(HTMLParser): 6 | def __init__(self): 7 | self.reset() 8 | self.fed = [] 9 | 10 | def handle_data(self, d): 11 | self.fed.append(d) 12 | 13 | def get_data(self): 14 | return ''.join(self.fed) 15 | 16 | 17 | def strip_tags(html): 18 | s = HTMLStripper() 19 | s.feed(html) 20 | 21 | return s.get_data() 22 | 23 | 24 | class HTMLField(fields.Raw): 25 | def format(self, value): 26 | return strip_tags(str(value)) 27 | -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter11/Chapter 11/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter11/Chapter 11/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter11/Chapter 11/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter11/Chapter 11/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/templates/admin/custom.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/master.html' %} 2 | 3 | {% block body %} 4 | This is the custom view! 5 | 6 | Link 7 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/templates/admin/post_edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/model/edit.html' %} 2 | {% block tail %} 3 | {{ super() }} 4 | 5 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/templates/admin/second_page.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/master.html' %} 2 | 3 | {% block body %} 4 | This is the second page! 5 | 6 | Link 7 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter11/Chapter 11/webapp/templates/youtube/video.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/.coverage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/.coverage -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-GZip/flask_gzip/__init__.py: -------------------------------------------------------------------------------- 1 | from gzip import GzipFile 2 | from io import BytesIO 3 | 4 | from flask import request 5 | 6 | 7 | class GZip(object): 8 | def __init__(self, app=None): 9 | self.app = app 10 | if app is not None: 11 | self.init_app(app) 12 | 13 | def init_app(self, app): 14 | app.after_request(self.after_request) 15 | 16 | def after_request(self, response): 17 | encoding = request.headers.get('Accept-Encoding') 18 | 19 | if 'gzip' not in encoding or \ 20 | not response.status_code == 200 or \ 21 | 'Content-Encoding' in response.headers: 22 | return response 23 | 24 | response.direct_passthrough = False 25 | 26 | gzip_buffer = BytesIO() 27 | with GzipFile(mode='wb', compresslevel=5, fileobj=gzip_buffer) as gzip_file: 28 | gzip_file.write(response.get_data()) 29 | 30 | response.set_data(bytes(gzip_buffer.getvalue())) 31 | 32 | response.headers['Content-Encoding'] = 'gzip' 33 | response.headers['Content-Length'] = response.content_length 34 | 35 | return response 36 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-GZip/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='Flask-GZip', 5 | version='0.1', 6 | license='MIT', 7 | description='Flask extension to allow easy GZip compressing of web pagess', 8 | author='Jack Stouffer', 9 | author_email='example@gmail.com', 10 | platforms='any', 11 | install_requires=['Flask'], 12 | packages=find_packages() 13 | ) 14 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/Flask_YouTube.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: Flask-YouTube 3 | Version: 0.1 4 | Summary: Flask extension to allow easy embedding of YouTube videos 5 | Home-page: UNKNOWN 6 | Author: Jack Stouffer 7 | Author-email: example@gmail.com 8 | License: MIT 9 | Description: UNKNOWN 10 | Platform: any 11 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/Flask_YouTube.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | setup.py 2 | Flask_YouTube.egg-info/PKG-INFO 3 | Flask_YouTube.egg-info/SOURCES.txt 4 | Flask_YouTube.egg-info/dependency_links.txt 5 | Flask_YouTube.egg-info/requires.txt 6 | Flask_YouTube.egg-info/top_level.txt 7 | flask_youtube/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/Flask_YouTube.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/Flask_YouTube.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/Flask_YouTube.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | flask_youtube 2 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/build/lib/flask_youtube/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import render_template, Blueprint, Markup 2 | 3 | 4 | class Video(object): 5 | def __init__(self, video_id, cls="youtube"): 6 | self.video_id = video_id 7 | self.cls = cls 8 | 9 | def render(self, *args, **kwargs): 10 | return render_template(*args, **kwargs) 11 | 12 | @property 13 | def html(self): 14 | return Markup(self.render('youtube/video.html', video=self)) 15 | 16 | 17 | def youtube(*args, **kwargs): 18 | video = Video(*args, **kwargs) 19 | return video.html 20 | 21 | 22 | class Youtube(object): 23 | def __init__(self, app=None, **kwargs): 24 | if app: 25 | self.init_app(app) 26 | 27 | def init_app(self, app): 28 | self.register_blueprint(app) 29 | app.add_template_global(youtube) 30 | 31 | def register_blueprint(self, app): 32 | module = Blueprint( 33 | "youtube", 34 | __name__, 35 | template_folder="templates" 36 | ) 37 | app.register_blueprint(module) 38 | return module 39 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/dist/Flask_YouTube-0.1-py2.7.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/Flask-YouTube/dist/Flask_YouTube-0.1-py2.7.egg -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/flask_youtube/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import render_template, Blueprint, Markup 2 | 3 | 4 | class Video(object): 5 | def __init__(self, video_id, cls="youtube"): 6 | self.video_id = video_id 7 | self.cls = cls 8 | 9 | def render(self, *args, **kwargs): 10 | return render_template(*args, **kwargs) 11 | 12 | @property 13 | def html(self): 14 | return Markup(self.render('youtube/video.html', video=self)) 15 | 16 | 17 | def youtube(*args, **kwargs): 18 | video = Video(*args, **kwargs) 19 | return video.html 20 | 21 | 22 | class Youtube(object): 23 | def __init__(self, app=None, **kwargs): 24 | if app: 25 | self.init_app(app) 26 | 27 | def init_app(self, app): 28 | self.register_blueprint(app) 29 | app.add_template_global(youtube) 30 | 31 | def register_blueprint(self, app): 32 | module = Blueprint( 33 | "youtube", 34 | __name__, 35 | template_folder="templates" 36 | ) 37 | app.register_blueprint(module) 38 | return module 39 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/flask_youtube/templates/youtube/video.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/Flask-YouTube/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='Flask-YouTube', 5 | version='0.1', 6 | license='MIT', 7 | description='Flask extension to allow easy embedding of YouTube videos', 8 | author='Jack Stouffer', 9 | author_email='example@gmail.com', 10 | platforms='any', 11 | install_requires=['Flask'], 12 | packages=find_packages() 13 | ) 14 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/celery_runner.py: -------------------------------------------------------------------------------- 1 | import os 2 | from webapp import create_app 3 | from celery import Celery 4 | 5 | 6 | def make_celery(app): 7 | celery = Celery( 8 | app.import_name, 9 | broker=app.config['CELERY_BROKER_URL'], 10 | backend=app.config['CELERY_BACKEND_URL'] 11 | ) 12 | celery.conf.update(app.config) 13 | TaskBase = celery.Task 14 | 15 | class ContextTask(TaskBase): 16 | abstract = True 17 | 18 | def __call__(self, *args, **kwargs): 19 | with app.app_context(): 20 | return TaskBase.__call__(self, *args, **kwargs) 21 | 22 | celery.Task = ContextTask 23 | 24 | return celery 25 | 26 | env = os.environ.get('WEBAPP_ENV', 'dev') 27 | flask_app = create_app('webapp.config.%sConfig' % env.capitalize()) 28 | 29 | celery = make_celery(flask_app) 30 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/run_test_server.py: -------------------------------------------------------------------------------- 1 | from webapp import create_app 2 | from webapp.models import db, User, Role 3 | 4 | app = create_app('webapp.config.TestConfig') 5 | 6 | db.app = app 7 | db.create_all() 8 | 9 | default = Role("default") 10 | poster = Role("poster") 11 | db.session.add(default) 12 | db.session.add(poster) 13 | db.session.commit() 14 | 15 | test_user = User("test") 16 | test_user.set_password("test") 17 | test_user.roles.append(poster) 18 | db.session.add(test_user) 19 | db.session.commit() 20 | 21 | app.run() 22 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/tests/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/controllers/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/webapp/controllers/rest/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/controllers/rest/auth.py: -------------------------------------------------------------------------------- 1 | from flask import abort, current_app 2 | from flask.ext.restful import Resource 3 | 4 | from webapp.models import User 5 | from .parsers import user_post_parser 6 | 7 | from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 8 | 9 | 10 | class AuthApi(Resource): 11 | def post(self): 12 | args = user_post_parser.parse_args() 13 | user = User.query.filter_by(username=args['username']).one() 14 | 15 | if user.check_password(args['password']): 16 | s = Serializer(current_app.config['SECRET_KEY'], expires_in=604800) 17 | return {"token": s.dumps({'id': user.id})} 18 | else: 19 | abort(401) 20 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/controllers/rest/fields.py: -------------------------------------------------------------------------------- 1 | from HTMLParser import HTMLParser 2 | from flask.ext.restful import fields 3 | 4 | 5 | class HTMLStripper(HTMLParser): 6 | def __init__(self): 7 | self.reset() 8 | self.fed = [] 9 | 10 | def handle_data(self, d): 11 | self.fed.append(d) 12 | 13 | def get_data(self): 14 | return ''.join(self.fed) 15 | 16 | 17 | def strip_tags(html): 18 | s = HTMLStripper() 19 | s.feed(html) 20 | 21 | return s.get_data() 22 | 23 | 24 | class HTMLField(fields.Raw): 25 | def format(self, value): 26 | return strip_tags(str(value)) 27 | -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/static/.webassets-cache/49d7031c832760f1c8af0e8f1f9a1954: -------------------------------------------------------------------------------- 1 | S'331a10ae21d04e9646dd1280cfd734b1' 2 | p1 3 | . -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/static/.webassets-cache/592e4efb9c5f8cd91720dd6d646679e7: -------------------------------------------------------------------------------- 1 | S'1cbf25481f487566bb2ac19ee9816a46' 2 | p1 3 | . -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/static/.webassets-cache/677b6b8fc43f52ebf6307be93396d33b: -------------------------------------------------------------------------------- 1 | S'e5dc859d' 2 | p1 3 | . -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/static/.webassets-cache/efe2845331acfbfa19510a0d780942a5: -------------------------------------------------------------------------------- 1 | S'549042f1' 2 | p1 3 | . -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter12/chapter_12/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/templates/admin/custom.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/master.html' %} 2 | 3 | {% block body %} 4 | This is the custom view! 5 | 6 | Link 7 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/templates/admin/post_edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/model/edit.html' %} 2 | {% block tail %} 3 | {{ super() }} 4 | 5 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter12/chapter_12/webapp/templates/admin/second_page.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/master.html' %} 2 | 3 | {% block body %} 4 | This is the second page! 5 | 6 | Link 7 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Elastic Beanstalk Files 3 | .elasticbeanstalk/* 4 | !.elasticbeanstalk/*.cfg.yml 5 | !.elasticbeanstalk/*.global.yml 6 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-GZip/flask_gzip/__init__.py: -------------------------------------------------------------------------------- 1 | from gzip import GzipFile 2 | from io import BytesIO 3 | 4 | from flask import request 5 | 6 | 7 | class GZip(object): 8 | def __init__(self, app=None): 9 | self.app = app 10 | if app is not None: 11 | self.init_app(app) 12 | 13 | def init_app(self, app): 14 | app.after_request(self.after_request) 15 | 16 | def after_request(self, response): 17 | encoding = request.headers.get('Accept-Encoding') 18 | 19 | if 'gzip' not in encoding or \ 20 | not response.status_code == 200 or \ 21 | 'Content-Encoding' in response.headers: 22 | return response 23 | 24 | response.direct_passthrough = False 25 | 26 | gzip_buffer = BytesIO() 27 | with GzipFile(mode='wb', compresslevel=5, fileobj=gzip_buffer) as gzip_file: 28 | gzip_file.write(response.get_data()) 29 | 30 | response.set_data(bytes(gzip_buffer.getvalue())) 31 | 32 | response.headers['Content-Encoding'] = 'gzip' 33 | response.headers['Content-Length'] = response.content_length 34 | 35 | return response 36 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-GZip/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='Flask-GZip', 5 | version='0.1', 6 | license='MIT', 7 | description='Flask extension to allow easy GZip compressing of web pagess', 8 | author='Jack Stouffer', 9 | author_email='example@gmail.com', 10 | platforms='any', 11 | install_requires=['Flask'], 12 | packages=find_packages() 13 | ) 14 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/Flask_YouTube.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: Flask-YouTube 3 | Version: 0.1 4 | Summary: Flask extension to allow easy embedding of YouTube videos 5 | Home-page: UNKNOWN 6 | Author: Jack Stouffer 7 | Author-email: example@gmail.com 8 | License: MIT 9 | Description: UNKNOWN 10 | Platform: any 11 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/Flask_YouTube.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | setup.py 2 | Flask_YouTube.egg-info/PKG-INFO 3 | Flask_YouTube.egg-info/SOURCES.txt 4 | Flask_YouTube.egg-info/dependency_links.txt 5 | Flask_YouTube.egg-info/requires.txt 6 | Flask_YouTube.egg-info/top_level.txt 7 | flask_youtube/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/Flask_YouTube.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/Flask_YouTube.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/Flask_YouTube.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | flask_youtube 2 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/build/lib/flask_youtube/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import render_template, Blueprint, Markup 2 | 3 | 4 | class Video(object): 5 | def __init__(self, video_id, cls="youtube"): 6 | self.video_id = video_id 7 | self.cls = cls 8 | 9 | def render(self, *args, **kwargs): 10 | return render_template(*args, **kwargs) 11 | 12 | @property 13 | def html(self): 14 | return Markup(self.render('youtube/video.html', video=self)) 15 | 16 | 17 | def youtube(*args, **kwargs): 18 | video = Video(*args, **kwargs) 19 | return video.html 20 | 21 | 22 | class Youtube(object): 23 | def __init__(self, app=None, **kwargs): 24 | if app: 25 | self.init_app(app) 26 | 27 | def init_app(self, app): 28 | self.register_blueprint(app) 29 | app.add_template_global(youtube) 30 | 31 | def register_blueprint(self, app): 32 | module = Blueprint( 33 | "youtube", 34 | __name__, 35 | template_folder="templates" 36 | ) 37 | app.register_blueprint(module) 38 | return module 39 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/dist/Flask_YouTube-0.1-py2.7.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter13/Chapter 13/Flask-YouTube/dist/Flask_YouTube-0.1-py2.7.egg -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/flask_youtube/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import render_template, Blueprint, Markup 2 | 3 | 4 | class Video(object): 5 | def __init__(self, video_id, cls="youtube"): 6 | self.video_id = video_id 7 | self.cls = cls 8 | 9 | def render(self, *args, **kwargs): 10 | return render_template(*args, **kwargs) 11 | 12 | @property 13 | def html(self): 14 | return Markup(self.render('youtube/video.html', video=self)) 15 | 16 | 17 | def youtube(*args, **kwargs): 18 | video = Video(*args, **kwargs) 19 | return video.html 20 | 21 | 22 | class Youtube(object): 23 | def __init__(self, app=None, **kwargs): 24 | if app: 25 | self.init_app(app) 26 | 27 | def init_app(self, app): 28 | self.register_blueprint(app) 29 | app.add_template_global(youtube) 30 | 31 | def register_blueprint(self, app): 32 | module = Blueprint( 33 | "youtube", 34 | __name__, 35 | template_folder="templates" 36 | ) 37 | app.register_blueprint(module) 38 | return module 39 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/flask_youtube/templates/youtube/video.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Flask-YouTube/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='Flask-YouTube', 5 | version='0.1', 6 | license='MIT', 7 | description='Flask extension to allow easy embedding of YouTube videos', 8 | author='Jack Stouffer', 9 | author_email='example@gmail.com', 10 | platforms='any', 11 | install_requires=['Flask'], 12 | packages=find_packages() 13 | ) 14 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/Procfile: -------------------------------------------------------------------------------- 1 | web: uwsgi uwsgi.ini 2 | celery: celery worker -A celery_runner -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/application.py: -------------------------------------------------------------------------------- 1 | from webapp import create_app 2 | 3 | application = create_app("webapp.config.ProdConfig") 4 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/celery_runner.py: -------------------------------------------------------------------------------- 1 | import os 2 | from webapp import create_app 3 | from celery import Celery 4 | 5 | 6 | def make_celery(app): 7 | celery = Celery( 8 | app.import_name, 9 | broker=app.config['CELERY_BROKER_URL'], 10 | backend=app.config['CELERY_BACKEND_URL'] 11 | ) 12 | celery.conf.update(app.config) 13 | TaskBase = celery.Task 14 | 15 | class ContextTask(TaskBase): 16 | abstract = True 17 | 18 | def __call__(self, *args, **kwargs): 19 | with app.app_context(): 20 | return TaskBase.__call__(self, *args, **kwargs) 21 | 22 | celery.Task = ContextTask 23 | 24 | return celery 25 | 26 | env = os.environ.get('WEBAPP_ENV', 'dev') 27 | flask_app = create_app('webapp.config.%sConfig' % env.capitalize()) 28 | 29 | celery = make_celery(flask_app) 30 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/gserver.py: -------------------------------------------------------------------------------- 1 | from gevent.wsgi import WSGIServer 2 | from webapp import create_app 3 | 4 | app = create_app('webapp.config.ProdConfig') 5 | 6 | server = WSGIServer(('', 80), app) 7 | server.serve_forever() 8 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name your_domain_name; 4 | 5 | location / { 6 | include uwsgi_params; 7 | uwsgi_pass 127.0.0.1:8080; 8 | } 9 | 10 | location /static { 11 | alias /home/deploy/webapp/webapp/static; 12 | } 13 | } -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/requirements.txt: -------------------------------------------------------------------------------- 1 | alembic==0.7.6 2 | amqp==1.4.6 3 | celery==3.1.18 4 | coverage==3.7.1 5 | cssmin==0.2.0 6 | Fabric==1.10.2 7 | Flask==0.10.1 8 | Flask-Admin==1.1.0 9 | Flask-Assets==0.10 10 | Flask-Bcrypt==0.6.2 11 | Flask-Cache==0.13.1 12 | Flask-Celery-Helper==1.1.0 13 | Flask-DebugToolbar==0.10.0 14 | Flask-Login==0.2.11 15 | Flask-Mail==0.9.1 16 | Flask-Migrate==1.4.0 17 | flask-mongoengine==0.7.1 18 | Flask-OAuth==0.12 19 | Flask-OpenID==1.2.4 20 | Flask-Principal==0.4.0 21 | Flask-RESTful==0.3.3 22 | Flask-Script==2.0.5 23 | Flask-SQLAlchemy==2.0 24 | Flask-WTF==0.11 25 | Jinja2==2.7.3 26 | jsmin==2.1.1 27 | mongoengine==0.9.0 28 | python-openid==2.2.5 29 | selenium==2.46.0 30 | SQLAlchemy==1.0.4 31 | uWSGI==2.0.11 32 | webassets==0.10.1 33 | Werkzeug==0.10.4 34 | WTForms==2.0.2 35 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/run_test_server.py: -------------------------------------------------------------------------------- 1 | from webapp import create_app 2 | from webapp.models import db, User, Role 3 | 4 | app = create_app('webapp.config.TestConfig') 5 | 6 | db.app = app 7 | db.create_all() 8 | 9 | default = Role("default") 10 | poster = Role("poster") 11 | db.session.add(default) 12 | db.session.add(poster) 13 | db.session.commit() 14 | 15 | test_user = User("test") 16 | test_user.set_password("test") 17 | test_user.roles.append(poster) 18 | db.session.add(test_user) 19 | db.session.commit() 20 | 21 | app.run() 22 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/runtime.txt: -------------------------------------------------------------------------------- 1 | python-2.7.10 -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/supervisor.conf: -------------------------------------------------------------------------------- 1 | [program:webapp] 2 | command=python gserver.py 3 | directory=/home/deploy/webapp 4 | user=deploy 5 | 6 | [program:rabbitmq] 7 | command=rabbitmq-server 8 | user=deploy 9 | 10 | [program:celery] 11 | command=celery worker -A celery_runner 12 | directory=/home/deploy/webapp 13 | user=deploy 14 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter13/Chapter 13/tests/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/tserver.py: -------------------------------------------------------------------------------- 1 | from tornado.wsgi import WSGIContainer 2 | from tornado.httpserver import HTTPServer 3 | from tornado.ioloop import IOLoop 4 | from webapp import create_app 5 | 6 | app = WSGIContainer(create_app("webapp.config.ProdConfig")) 7 | http_server = HTTPServer(app) 8 | http_server.listen(80) 9 | IOLoop.instance().start() 10 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | http-socket = :$(PORT) 3 | die-on-term = true 4 | wsgi-file = wsgi.py 5 | callable = app 6 | processes = 4 7 | threads = 2 -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter13/Chapter 13/webapp/controllers/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/controllers/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter13/Chapter 13/webapp/controllers/rest/__init__.py -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/controllers/rest/auth.py: -------------------------------------------------------------------------------- 1 | from flask import abort, current_app 2 | from flask.ext.restful import Resource 3 | 4 | from webapp.models import User 5 | from .parsers import user_post_parser 6 | 7 | from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 8 | 9 | 10 | class AuthApi(Resource): 11 | def post(self): 12 | args = user_post_parser.parse_args() 13 | user = User.query.filter_by(username=args['username']).one() 14 | 15 | if user.check_password(args['password']): 16 | s = Serializer(current_app.config['SECRET_KEY'], expires_in=604800) 17 | return {"token": s.dumps({'id': user.id})} 18 | else: 19 | abort(401) 20 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/controllers/rest/fields.py: -------------------------------------------------------------------------------- 1 | from HTMLParser import HTMLParser 2 | from flask.ext.restful import fields 3 | 4 | 5 | class HTMLStripper(HTMLParser): 6 | def __init__(self): 7 | self.reset() 8 | self.fed = [] 9 | 10 | def handle_data(self, d): 11 | self.fed.append(d) 12 | 13 | def get_data(self): 14 | return ''.join(self.fed) 15 | 16 | 17 | def strip_tags(html): 18 | s = HTMLStripper() 19 | s.feed(html) 20 | 21 | return s.get_data() 22 | 23 | 24 | class HTMLField(fields.Raw): 25 | def format(self, value): 26 | return strip_tags(str(value)) 27 | -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/static/.webassets-cache/49d7031c832760f1c8af0e8f1f9a1954: -------------------------------------------------------------------------------- 1 | S'331a10ae21d04e9646dd1280cfd734b1' 2 | p1 3 | . -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/static/.webassets-cache/592e4efb9c5f8cd91720dd6d646679e7: -------------------------------------------------------------------------------- 1 | S'1cbf25481f487566bb2ac19ee9816a46' 2 | p1 3 | . -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/static/.webassets-cache/677b6b8fc43f52ebf6307be93396d33b: -------------------------------------------------------------------------------- 1 | S'e5dc859d' 2 | p1 3 | . -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/static/.webassets-cache/efe2845331acfbfa19510a0d780942a5: -------------------------------------------------------------------------------- 1 | S'549042f1' 2 | p1 3 | . -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter13/Chapter 13/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter13/Chapter 13/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter13/Chapter 13/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Chapter13/Chapter 13/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/templates/admin/custom.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/master.html' %} 2 | 3 | {% block body %} 4 | This is the custom view! 5 | 6 | Link 7 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/templates/admin/post_edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/model/edit.html' %} 2 | {% block tail %} 3 | {{ super() }} 4 | 5 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/webapp/templates/admin/second_page.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/master.html' %} 2 | 3 | {% block body %} 4 | This is the second page! 5 | 6 | Link 7 | {% endblock %} -------------------------------------------------------------------------------- /Module 3/Chapter13/Chapter 13/wsgi.py: -------------------------------------------------------------------------------- 1 | from webapp import create_app 2 | 3 | app = create_app("webapp.config.ProdConfig") 4 | -------------------------------------------------------------------------------- /Module 3/Software Hardware List.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Module 3/Software Hardware List.docx -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Flask-Building-Python-Web-Services/9c309b0f3721b27de4648d8d4b72dcc577eda39b/Readme.md --------------------------------------------------------------------------------