\documentclass[10pt,a4paper]{article} % Packages \usepackage{fancyhdr} % For header and footer \usepackage{multicol} % Allows multicols in tables \usepackage{tabularx} % Intelligent column widths \usepackage{tabulary} % Used in header and footer \usepackage{hhline} % Border under tables \usepackage{graphicx} % For images \usepackage{xcolor} % For hex colours %\usepackage[utf8x]{inputenc} % For unicode character support \usepackage[T1]{fontenc} % Without this we get weird character replacements \usepackage{colortbl} % For coloured tables \usepackage{setspace} % For line height \usepackage{lastpage} % Needed for total page number \usepackage{seqsplit} % Splits long words. %\usepackage{opensans} % Can't make this work so far. Shame. Would be lovely. \usepackage[normalem]{ulem} % For underlining links % Most of the following are not required for the majority % of cheat sheets but are needed for some symbol support. \usepackage{amsmath} % Symbols \usepackage{MnSymbol} % Symbols \usepackage{wasysym} % Symbols %\usepackage[english,german,french,spanish,italian]{babel} % Languages % Document Info \author{amicheletti} \pdfinfo{ /Title (python-flask.pdf) /Creator (Cheatography) /Author (amicheletti) /Subject (Python Flask Cheat Sheet) } % Lengths and widths \addtolength{\textwidth}{6cm} \addtolength{\textheight}{-1cm} \addtolength{\hoffset}{-3cm} \addtolength{\voffset}{-2cm} \setlength{\tabcolsep}{0.2cm} % Space between columns \setlength{\headsep}{-12pt} % Reduce space between header and content \setlength{\headheight}{85pt} % If less, LaTeX automatically increases it \renewcommand{\footrulewidth}{0pt} % Remove footer line \renewcommand{\headrulewidth}{0pt} % Remove header line \renewcommand{\seqinsert}{\ifmmode\allowbreak\else\-\fi} % Hyphens in seqsplit % This two commands together give roughly % the right line height in the tables \renewcommand{\arraystretch}{1.3} \onehalfspacing % Commands \newcommand{\SetRowColor}[1]{\noalign{\gdef\RowColorName{#1}}\rowcolor{\RowColorName}} % Shortcut for row colour \newcommand{\mymulticolumn}[3]{\multicolumn{#1}{>{\columncolor{\RowColorName}}#2}{#3}} % For coloured multi-cols \newcolumntype{x}[1]{>{\raggedright}p{#1}} % New column types for ragged-right paragraph columns \newcommand{\tn}{\tabularnewline} % Required as custom column type in use % Font and Colours \definecolor{HeadBackground}{HTML}{333333} \definecolor{FootBackground}{HTML}{666666} \definecolor{TextColor}{HTML}{333333} \definecolor{DarkBackground}{HTML}{852A24} \definecolor{LightBackground}{HTML}{F7F1F1} \renewcommand{\familydefault}{\sfdefault} \color{TextColor} % Header and Footer \pagestyle{fancy} \fancyhead{} % Set header to blank \fancyfoot{} % Set footer to blank \fancyhead[L]{ \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{C} \SetRowColor{DarkBackground} \vspace{-7pt} {\parbox{\dimexpr\textwidth-2\fboxsep\relax}{\noindent \hspace*{-6pt}\includegraphics[width=5.8cm]{/web/www.cheatography.com/public/images/cheatography_logo.pdf}} } \end{tabulary} \columnbreak \begin{tabulary}{11cm}{L} \vspace{-2pt}\large{\bf{\textcolor{DarkBackground}{\textrm{Python Flask Cheat Sheet}}}} \\ \normalsize{by \textcolor{DarkBackground}{amicheletti} via \textcolor{DarkBackground}{\uline{cheatography.com/39488/cs/12263/}}} \end{tabulary} \end{multicols}} \fancyfoot[L]{ \footnotesize \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{LL} \SetRowColor{FootBackground} \mymulticolumn{2}{p{5.377cm}}{\bf\textcolor{white}{Cheatographer}} \\ \vspace{-2pt}amicheletti \\ \uline{cheatography.com/amicheletti} \\ \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Cheat Sheet}} \\ \vspace{-2pt}Published 11th July, 2017.\\ Updated 18th July, 2017.\\ Page {\thepage} of \pageref{LastPage}. \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Sponsor}} \\ \SetRowColor{white} \vspace{-5pt} %\includegraphics[width=48px,height=48px]{dave.jpeg} Measure your website readability!\\ www.readability-score.com \end{tabulary} \end{multicols}} \begin{document} \raggedright \raggedcolumns % Set font size to small. Switch to any value % from this page to resize cheat sheet text: % www.emerson.emory.edu/services/latex/latex_169.html \footnotesize % Small font. \begin{multicols*}{2} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Routing}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{`route()` decorator is used to bind a `function` to a `URL` \newline % Row Count 2 (+ 2) Example: \newline % Row Count 3 (+ 1) `@app.route('/')` \newline % Row Count 4 (+ 1) By default a route only answers to GET requests, but you can provide the `methods` argument. \newline % Row Count 6 (+ 2) `@app.route('/login', methods={[}'GET', 'POST'{]})`% Row Count 7 (+ 1) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{flask-restful}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{\{\{fa-bolt\}\} With Flask-Restful you can create RESTful API with your Flask app \newline % Row Count 2 (+ 2) Create an Flask App \newline % Row Count 3 (+ 1) `app = Flask(\_\_name\_\_)` \newline % Row Count 4 (+ 1) Then create the Api object passing the App object \newline % Row Count 5 (+ 1) `api = Api(app)` \newline % Row Count 6 (+ 1) Then you can create `Resource`s and add them to the API \newline % Row Count 8 (+ 2) `class NewsFinder(Resource): pass` \newline % Row Count 9 (+ 1) \seqsplit{`api.add\_resouce(NewsFinder}, '/', '/news')` \newline % Row Count 10 (+ 1) You can implement each HTTP verb with functions named like the verb, but in lowercase. \newline % Row Count 12 (+ 2) Example: \newline % Row Count 13 (+ 1) `def get(self): pass` \newline % Row Count 14 (+ 1) `def put(self, id): pass` \newline % Row Count 15 (+ 1) To parse arguments passed by the url use \newline % Row Count 16 (+ 1) `parser = \seqsplit{reqparse.RequestParser()`} \newline % Row Count 17 (+ 1) You can pass \seqsplit{`parse\_args(strict=True)`} to throw an error if arguments that were not defined by you has been passed \newline % Row Count 20 (+ 3) Add the arguments with \seqsplit{`parser.add\_arguments('limit'}, type=int, help='Help Text', required=True)` \newline % Row Count 22 (+ 2) You can specify the location to look for this argument with \seqsplit{`add\_argument('User-Agent'}, location='headers')` \newline % Row Count 25 (+ 3) Example locations: form, args, headers, session, cookies, files \newline % Row Count 27 (+ 2) Then inside the function you can `args = parser.parse\_args()` to get the parsed args. This variable `args` will become a dictionary with the values, ccess via `args{[}'limit'{]}`% Row Count 31 (+ 4) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{Imports \newline `from flask\_restful import Api, Resource, reqparse`} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Flask\_jwt}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{from flask import Flask \newline from flask\_restful import Api, Resource \newline from flask\_jwt import JWT, jwt\_required, current\_identity \newline \newline app = Flask(\_\_name\_\_) \newline app.config{[}'SECRET\_KEY'{]} = 'my-secret' \newline \newline api = Api(app, prefix='/api/v1') \newline \newline USER\_DATA = \{ \newline "amicheletti": "coracaopeludo" \newline \} \newline \newline class User(object): \newline \newline def \_\_init\_\_(self, id): \newline self.id = id \newline \newline def \_\_str\_\_(self): \newline return "User (id=\{\})".format(self.id) \newline \newline \newline def verify(username, password): \newline if not (username and password): \newline return False \newline if \seqsplit{(USER\_DATA.get(username)} == password): \newline return User(id=123) \newline \newline \newline def identity(payload): \newline user\_id = payload{[}'identity'{]} \newline return \{ "uid": user\_id \} \newline \newline \newline jwt = JWT(app, verify, identity) \newline \newline \newline class \seqsplit{UltimateQuestion(Resource):} \newline \newline @jwt\_required() \newline def get(self): \newline return \{ "meaningoflife" : 42, "who\_asked" : dict(current\_identity) \} \newline \newline \newline api.add\_resource(UltimateQuestion, '/', '/life') \newline \newline \newline if \_\_name\_\_ == "\_\_main\_\_": \newline app.run(debug=True)} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{You must have an \seqsplit{`authentication\_handler()`} which takes 2 arguments and a `identity\_handler()` which takes 1 argument \newline \newline Authentication handler must return an Object that has an id attribute \newline Identity handler return what is going to be send to `'identity'` key of the JSON \newline \newline To get the token, curl POST to the `/auth` like this: \newline `curl -H "Content-type: application/json" -X POST -d '\{"username":"amicheletti","password":"coracaopeludo"\}' \seqsplit{http://127.0.0.1:5000/auth`}} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{URL Building}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{When routing some function to a URL, you can use function `url\_for()` to generate the URL to that function. \newline % Row Count 3 (+ 3) Example, if you have something like \newline % Row Count 4 (+ 1) `@app.route('/user/\textless{}username\textgreater{}') def profile(username): pass` you use `url\_for('profile', username="Andre")` to get the URL for that route. \newline % Row Count 7 (+ 3) That way you can avoid having to change the hardcoded URL everywhere in the code.% Row Count 9 (+ 2) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{File Uploads}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{To handle file uploads with Flask, the HTML form must be set with ` \seqsplit{enctype="multipart/form-data"`} \newline % Row Count 2 (+ 2) Then you can use it from a dictionary in `requests.files` \newline % Row Count 4 (+ 2) Example: \newline % Row Count 5 (+ 1) `f = request.files{[}'the\_file'{]} \seqsplit{f.save('/var/www/uploads/uploaded\_file.txt')`}% Row Count 7 (+ 2) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Redirects and Errors}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{`redirect('url')` Pass a URL to this function to redirect a user \newline % Row Count 2 (+ 2) `abort(401)` This will abort the request early with an error code \newline % Row Count 4 (+ 2) To customize the error page use `@app.errorhandler(404)`, but don't forget to pass the error code. Example: \newline % Row Count 7 (+ 3) `return \seqsplit{render\_template('page\_not\_found}.html'), 404`% Row Count 9 (+ 2) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{x{3.6 cm} x{4.4 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{8.4cm}}{\bf\textcolor{white}{virtualenv}} \tn % Row 0 \SetRowColor{LightBackground} `virtualenv my\_project` & Create environment named my\_project \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} `-p \seqsplit{/usr/bin/python3.5`} & Pass this argument to define Python to be used \tn % Row Count 5 (+ 3) % Row 2 \SetRowColor{LightBackground} `source \seqsplit{my\_project/bin/activate`} & Start using the environment \tn % Row Count 7 (+ 2) % Row 3 \SetRowColor{white} `deactivate` & To leave your environment \tn % Row Count 9 (+ 2) % Row 4 \SetRowColor{LightBackground} `pip freeze \textgreater{} requirements.txt` & Freeze your requirements to a file \tn % Row Count 11 (+ 2) % Row 5 \SetRowColor{white} `pip install -r requirements.txt` & Install using the requirements file \tn % Row Count 13 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Blueprint}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{Blueprints are objects similar to the Flask application object, but are not an actual application. They can record operations and endpoints routing and deliver resources, and then they are registered to the application (can be registered multiple times) under a specific URL. \newline % Row Count 6 (+ 6) Create a blueprint: \newline % Row Count 7 (+ 1) `feed\_blueprint = Blueprint('feed', \_\_name\_\_)` \newline % Row Count 8 (+ 1) Use blueprint like an Flask app object: \newline % Row Count 9 (+ 1) `@feed\_blueprint.route('\textbackslash{}')` \newline % Row Count 10 (+ 1) Register the blueprint to the real application \newline % Row Count 11 (+ 1) \seqsplit{`app.register\_blueprint(feed\_blueprint}, url\_prefix='/feed')` \newline % Row Count 13 (+ 2) Blueprint root folder \newline % Row Count 14 (+ 1) \seqsplit{`feed\_blueprint.root\_path`} \newline % Row Count 15 (+ 1) To build url for Blueprints, put the name used in the object creation before the function name: \newline % Row Count 17 (+ 2) `url\_for('feed.index')` \newline % Row Count 18 (+ 1) Also you can use the error handler just like the Flask object \newline % Row Count 20 (+ 2) \seqsplit{`@feed\_blueprint.errorhandler(404)`}% Row Count 21 (+ 1) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{JWT}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{JWT stands for JSON Web Token, that are used to securely transmit JSON information between two parties or authenticate \newline % Row Count 3 (+ 3) They consist in three parts: Header, Payload and Signature. These three parts are JSON object which are then `Base64URL` encoded and included to \newline % Row Count 6 (+ 3) the token \seqsplit{`header.payload.signature`} \newline % Row Count 7 (+ 1) {\bf{- Header}} \newline % Row Count 8 (+ 1) In Header, you generally have two information: \newline % Row Count 9 (+ 1) the type of the token and the algorithm used \newline % Row Count 10 (+ 1) `\{` \newline % Row Count 11 (+ 1) `"alg" : "HS256",` \newline % Row Count 12 (+ 1) ` "typ" : "JWT" ` \newline % Row Count 13 (+ 1) `\}` \newline % Row Count 14 (+ 1) {\bf{- Payload}} \newline % Row Count 15 (+ 1) In Payload you have "claims" about an Entity (the user for example) and other metadata. \newline % Row Count 17 (+ 2) Example: \newline % Row Count 18 (+ 1) `\{` \newline % Row Count 19 (+ 1) `"id": "1234567890",` \newline % Row Count 20 (+ 1) ` "name": "John Doe",` \newline % Row Count 21 (+ 1) ` "admin": true` \newline % Row Count 22 (+ 1) `\}` \newline % Row Count 23 (+ 1) There are Reserved Claims (predefined), Public Claims (defined by users at IANA JSON Web Token Registry) and Private Claims (custom claims agreed by both parties) \newline % Row Count 27 (+ 4) {\bf{- Signature}} \newline % Row Count 28 (+ 1) To generate the signature, take the encoded header and payload, a secret and encode all that with the algorithm used. \newline % Row Count 31 (+ 3) } \tn \end{tabularx} \par\addvspace{1.3em} \vfill \columnbreak \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{JWT (cont)}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{Example: `HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)` \newline % Row Count 2 (+ 2) {\bf{- Usage}} \newline % Row Count 3 (+ 1) Now when the user wants to access a protected route or resource, the user agent must send the JWT typically in the {\emph{Authorization header}}, using the {\emph{Bearer}} schema, like this: \newline % Row Count 7 (+ 4) `Authorization: {\emph{Bearer}} \textless{}token\textgreater{}`% Row Count 8 (+ 1) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{x{2.08 cm} x{5.92 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{8.4cm}}{\bf\textcolor{white}{Variable Rules}} \tn % Row 0 \SetRowColor{LightBackground} `\textless{}username\textgreater{}` & default for `\textless{}string:\textgreater{}` \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} `\textless{}string:\textgreater{}` & accepts any text without slash \tn % Row Count 4 (+ 2) % Row 2 \SetRowColor{LightBackground} `\textless{}int:\textgreater{}` & accepts integers \tn % Row Count 5 (+ 1) % Row 3 \SetRowColor{white} `\textless{}float:\textgreater{}` & floating point values \tn % Row Count 6 (+ 1) % Row 4 \SetRowColor{LightBackground} `\textless{}path:\textgreater{}` & like `\textless{}string:\textgreater{}` but accept slashes \tn % Row Count 8 (+ 2) % Row 5 \SetRowColor{white} `\textless{}any:\textgreater{}` & matches one of the items provided \tn % Row Count 10 (+ 2) % Row 6 \SetRowColor{LightBackground} `\textless{}uuid:\textgreater{}` & accepts UUID strings \tn % Row Count 11 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{8.4cm}}{Add variable parts to a URL. You can also specify a converter to the variable.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Request Object}} \tn \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{The request object is available when routing passing `method` argument. \newline % Row Count 2 (+ 2) `request.method` is the HTTP method (POST, GET...) \newline % Row Count 4 (+ 2) `request.fòrm` Use this to access the form data passed \newline % Row Count 6 (+ 2) `request.args.get('key', '')` Use this to access parameters passed by url `?key=value`% Row Count 8 (+ 2) } \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{`from flask import request`} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Logging}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{app.logger.debug('A value for debugging') \newline \newline app.logger.warning('A warning occurred (\%d apples)', 42) \newline \newline app.logger.error('An error occurred')} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} % That's all folks \end{multicols*} \end{document}