<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Packages | Haobin Tan</title><link>https://haobin-tan.netlify.app/tags/packages/</link><atom:link href="https://haobin-tan.netlify.app/tags/packages/index.xml" rel="self" type="application/rss+xml"/><description>Packages</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Thu, 16 Feb 2023 00:00:00 +0000</lastBuildDate><image><url>https://haobin-tan.netlify.app/media/icon_hu7d15bc7db65c8eaf7a4f66f5447d0b42_15095_512x512_fill_lanczos_center_3.png</url><title>Packages</title><link>https://haobin-tan.netlify.app/tags/packages/</link></image><item><title>argparse</title><link>https://haobin-tan.netlify.app/docs/coding/python/useful_packages/argparse/</link><pubDate>Wed, 04 Jan 2023 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/coding/python/useful_packages/argparse/</guid><description>&lt;h2 id="basic-usage">Basic usage&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">argparse&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">get_args_parser&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># set up a parser&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">argparse&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ArgumentParser&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">description&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">program_description&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># define parsing rules and operations for different arguments &lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># parser.add_argument()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">parser&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s1">&amp;#39;__main__&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_parser&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># parse command line &lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">parse_args&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># further operations based on parsed arguments&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="add_argument">&lt;code>add_argument()&lt;/code>&lt;/h2>
&lt;p>Parameters:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#name-or-flags">name or flags&lt;/a> - Either a name or a list of option strings, e.g. &lt;code>foo&lt;/code> or &lt;code>-f, --foo&lt;/code>.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#action">action&lt;/a> - The basic type of action to be taken when this argument is encountered at the command line.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#nargs">nargs&lt;/a> - The number of command-line arguments that should be consumed.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#const">const&lt;/a> - A constant value required by some &lt;a href="https://docs.python.org/3/library/argparse.html#action">action&lt;/a> and &lt;a href="https://docs.python.org/3/library/argparse.html#nargs">nargs&lt;/a> selections.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#default">default&lt;/a> - The value produced if the argument is absent from the command line.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#type">type&lt;/a> - The type to which the command-line argument should be converted.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#choices">choices&lt;/a> - A container of the allowable values for the argument.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#required">required&lt;/a> - Whether or not the command-line option may be omitted (optionals only).&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#help">help&lt;/a> - A brief description of what the argument does.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#metavar">metavar&lt;/a> - A name for the argument in usage messages.&lt;/li>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#dest">dest&lt;/a> - The name of the attribute to be added to the object returned by &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.parse_args">&lt;code>parse_args()&lt;/code>&lt;/a>.&lt;/li>
&lt;/ul>
&lt;h3 id="name-or-flags">name or flags&lt;/h3>
&lt;p>The &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a> method must know whether an &lt;strong>optional&lt;/strong> argument, or a &lt;strong>positional&lt;/strong> argument is expected. Therefore, the first arguments passed to &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a> must be either a series of flags, or a simple argument name.&lt;/p>
&lt;p>&lt;strong>When &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.parse_args">&lt;code>parse_args()&lt;/code>&lt;/a> is called, optional arguments will be identified by the &lt;code>-&lt;/code> prefix, and the remaining arguments will be assumed to be positional.&lt;/strong>&lt;/p>
&lt;p>For example, an optional argument could be created like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;-f&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;--foo&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A positional argument could be created like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;bar&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="action">action&lt;/h3>
&lt;ul>
&lt;li>
&lt;p>The &lt;code>action&lt;/code> keyword argument specifies how the command-line arguments should be&lt;/p>
&lt;/li>
&lt;li>
&lt;p>handled. The supplied actions are:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;code>'store'&lt;/code>&lt;/p>
&lt;p>This just stores the argument’s value.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>'store_const'&lt;/code>&lt;/p>
&lt;p>This stores the value specified by the &lt;a href="https://docs.python.org/3/library/argparse.html#const">const&lt;/a> keyword argument. The &lt;code>'store_const'&lt;/code> action is most commonly used with optional arguments that specify some sort of flag&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>'store_true'&lt;/code> and &lt;code>'store_false'&lt;/code>&lt;/p>
&lt;p>These are special cases of &lt;code>'store_const'&lt;/code> used for storing the values &lt;code>True&lt;/code> and &lt;code>False&lt;/code> respectively. In addition, they create default values of &lt;code>False&lt;/code> and &lt;code>True&lt;/code> respectively.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>'append'&lt;/code>&lt;/p>
&lt;p>This stores a list, and appends each argument value to the list. This is useful to allow an option to be specified multiple times.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>'append_const'&lt;/code>&lt;/p>
&lt;p>This stores a list, and appends the value specified by the &lt;a href="https://docs.python.org/3/library/argparse.html#const">const&lt;/a> keyword argument to the list.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>'count'&lt;/code>&lt;/p>
&lt;p>This counts the number of times a keyword argument occurs.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>'help'&lt;/code>&lt;/p>
&lt;p>This prints a complete help message for all the options in the current parser and then exits. By default a help action is automatically added to the parser.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>'version'&lt;/code>&lt;/p>
&lt;p>This expects a &lt;code>version=&lt;/code> keyword argument in the &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a> call, and prints version information and exits when invoked&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>'extend'&lt;/code>&lt;/p>
&lt;p>This stores a list, and extends each argument value to the list.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="nargs">nargs&lt;/h3>
&lt;p>The &lt;code>nargs&lt;/code> specifies the number of command-line arguments that should be consumed.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Supported value&lt;/th>
&lt;th>Meaning&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>N&lt;/code>&lt;/td>
&lt;td>The absolute number of arguments (e.g., &lt;code>3&lt;/code>).&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>?&lt;/code>&lt;/td>
&lt;td>0 or 1 argument&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>*&lt;/code>&lt;/td>
&lt;td>0 or all arguments&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>+&lt;/code>&lt;/td>
&lt;td>All, and at least one, argument&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="const">const&lt;/h3>
&lt;p>The &lt;code>const&lt;/code> argument of &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a> is used to hold constant values that are not read from the command line but are required for the various &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser">&lt;code>ArgumentParser&lt;/code>&lt;/a> actions.&lt;/p>
&lt;h3 id="default">default&lt;/h3>
&lt;p>All optional arguments and some positional arguments may be omitted at the command line. The &lt;code>default&lt;/code> keyword argument of &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a> specifies what value should be used if the command-line argument is not present.&lt;/p>
&lt;h3 id="type">type&lt;/h3>
&lt;p>By default, &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser">&lt;code>ArgumentParser&lt;/code>&lt;/a> objects read command-line arguments in as simple strings. The &lt;code>type&lt;/code> keyword argument of &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a> allows any necessary type-checking and type conversions to be performed.&lt;/p>
&lt;h3 id="choices">choices&lt;/h3>
&lt;ul>
&lt;li>Some command-line arguments should be selected from a restricted set of values.&lt;/li>
&lt;li>These can be handled by passing a container object as the &lt;em>choices&lt;/em> keyword argument to &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a>.&lt;/li>
&lt;li>When the command line is parsed, argument values will be checked, and an error message will be displayed if the argument was not one of the acceptable values&lt;/li>
&lt;/ul>
&lt;h3 id="required">required&lt;/h3>
&lt;p>An argument is made required with the &lt;code>required&lt;/code> option. If the required argument is not given, an error will be raised.&lt;/p>
&lt;h3 id="help">help&lt;/h3>
&lt;ul>
&lt;li>The &lt;code>help&lt;/code> value is a string containing a brief description of the argument.&lt;/li>
&lt;li>When a user requests help (usually by using &lt;code>-h&lt;/code> or &lt;code>--help&lt;/code> at the command line), these &lt;code>help&lt;/code> descriptions will be displayed with each argument:&lt;/li>
&lt;/ul>
&lt;h3 id="metavar">metavar&lt;/h3>
&lt;ul>
&lt;li>When &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser">&lt;code>ArgumentParser&lt;/code>&lt;/a> generates help messages, it needs some way to refer to each expected argument.&lt;/li>
&lt;li>By default
&lt;ul>
&lt;li>ArgumentParser objects use the &lt;a href="https://docs.python.org/3/library/argparse.html#dest">dest&lt;/a> value as the “name” of each object.&lt;/li>
&lt;li>for positional argument actions, the &lt;a href="https://docs.python.org/3/library/argparse.html#dest">dest&lt;/a> value is used directly
&lt;ul>
&lt;li>E.g. a single positional argument with &lt;code>dest='bar'&lt;/code> will be referred to as &lt;code>bar&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>for optional argument actions, the &lt;a href="https://docs.python.org/3/library/argparse.html#dest">dest&lt;/a> value is uppercased
&lt;ul>
&lt;li>E.g. A single optional argument &lt;code>--foo&lt;/code> that should be followed by a single command-line argument will be referred to as &lt;code>FOO&lt;/code>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>The &lt;code>metavar&lt;/code> option gives the argument a name to the expected value displayed in error and help outputs.&lt;/p>
&lt;h3 id="dest">dest&lt;/h3>
&lt;ul>
&lt;li>
&lt;p>Most &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser">&lt;code>ArgumentParser&lt;/code>&lt;/a> actions add some value as an attribute of the object returned by &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.parse_args">&lt;code>parse_args()&lt;/code>&lt;/a>. The name of this attribute is determined by the &lt;code>dest&lt;/code> keyword argument of &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a>.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>For positional argument actions, &lt;code>dest&lt;/code> is normally supplied as the first argument to &lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument">&lt;code>add_argument()&lt;/code>&lt;/a>&lt;/p>
&lt;p>E.g.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;bar&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The value of &lt;code>dest&lt;/code> is &lt;code>bar&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>For optional argument actions, the value of &lt;code>dest&lt;/code> is normally inferred from the option strings.&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser">&lt;code>ArgumentParser&lt;/code>&lt;/a> generates the value of &lt;code>dest&lt;/code> by taking the first long option string and stripping away the initial &lt;code>--&lt;/code> string.&lt;/li>
&lt;li>If no long option strings were supplied, &lt;code>dest&lt;/code> will be derived from the first short option string by stripping the initial &lt;code>-&lt;/code> character.&lt;/li>
&lt;li>Any internal &lt;code>-&lt;/code> characters will be converted to &lt;code>_&lt;/code> characters to make sure the string is a valid attribute name.&lt;/li>
&lt;/ul>
&lt;p>E.g.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;-n&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;--name&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nb">str&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">required&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Name of the person&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The value of &lt;code>dest&lt;/code> is &lt;code>name&lt;/code>. After calling&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">parse_args&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>we can use the argument with &lt;code>args.name&lt;/code>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="example">Example&lt;/h2>
&lt;p>Assume we have a python file &lt;em>&lt;strong>person-info.py&lt;/strong>&lt;/em>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">argparse&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">get_args_parser&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">argparse&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ArgumentParser&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">description&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Person info program&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;-n&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;--name&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nb">str&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">required&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Name of the person&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;-a&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;--age&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nb">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">required&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Age of the person&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;-g&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">metavar&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;gender&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dest&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;gender&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">default&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;male&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">choices&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;male, female&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Gender of the person. (male, female)&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;-s&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;--single&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">dest&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;is_single&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">action&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;store_true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Is the person single?&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;-i&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;--interests&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">metavar&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;interests&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">action&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;append&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Interests of the person&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;-e&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">metavar&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;education&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">dest&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;education&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">nargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;+&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;Educational experience of the person&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">parser&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_args_parser&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">parse_args&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Name: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Age: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">age&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Gender: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gender&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Is single?: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">is_single&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Interests: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">interests&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Education: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">education&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>Print the help information:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ python person-info.py -h
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">usage: person-info.py [-h] -n NAME -a AGE [-g gender] [-s] [-i interests]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [-e education [education ...]]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Person info program
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">optional arguments:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -h, --help show this help message and exit
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -n NAME, --name NAME Name of the person
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -a AGE, --age AGE Age of the person
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -g gender Gender of the person. (male, female)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -s, --single Is the person single?
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -i interests, --interests interests
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Interests of the person
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> -e education [education ...]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Educational experience of the person
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Run the script by given necesary arguments:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ python person-info.py -n Ecko -a &lt;span class="m">26&lt;/span> -s -i coding -e KIT KIT -i basketball -i fitness
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">Name: Ecko
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Age: 26
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Gender: male
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Is single?: True
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Interests: [&amp;#39;coding&amp;#39;, &amp;#39;basketball&amp;#39;, &amp;#39;fitness&amp;#39;]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Education: [&amp;#39;KIT&amp;#39;, &amp;#39;KIT&amp;#39;]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Violation by not given age arguement &lt;code>-a&lt;/code> :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">python person-info.py -n Ecko -s -i coding -e KIT KIT -i basketball -i fitness
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">usage: person-info.py [-h] -n NAME -a AGE [-g gender] [-s] [-i interests]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [-e education [education ...]]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">person-info.py: error: the following arguments are required: -a/--age
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;h2 id="reference">Reference&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>Python documentation: &lt;a href="https://docs.python.org/3/library/argparse.html#module-argparse">&lt;code>argparse&lt;/code>&lt;/a> — Parser for command-line options, arguments and sub-commands&lt;a href="https://docs.python.org/3/library/argparse.html#module-argparse">¶&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="http://zetcode.com/python/argparse/">Python argparse tutorial&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://vra.github.io/2017/12/02/argparse-usage/">argparse简要用法总结&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://pymotw.com/2/argparse/">argparse – Command line option and argument parsing&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul></description></item><item><title>Logging</title><link>https://haobin-tan.netlify.app/docs/coding/python/useful_packages/logging/</link><pubDate>Wed, 11 Jan 2023 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/coding/python/useful_packages/logging/</guid><description>&lt;p>Logging is a very useful tool in a programmer’s toolbox.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>It helps you develop a better understanding of the flow of a program&lt;/p>
&lt;/li>
&lt;li>
&lt;p>It helps you discover scenarios that you might not even have thought of while developing&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Logs&lt;/p>
&lt;ul>
&lt;li>
&lt;p>provide developers with an extra set of eyes that are constantly looking at the flow that an application is going through&lt;/p>
&lt;/li>
&lt;li>
&lt;p>can store information&lt;/p>
&lt;/li>
&lt;li>
&lt;p>If an error occurs, can provide more insights than a stack trace by telling you what the state of the program was before it arrived at the line of code where the error occurred.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="the-logging-module">The Logging Module&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>5 standard levels indicating the severity of events (in the increasing order)&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:left">Logging level&lt;/th>
&lt;th>Value&lt;/th>
&lt;th style="text-align:left">Usage&lt;/th>
&lt;th style="text-align:left">Possible message output&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:left">&lt;strong>Debug&lt;/strong>&lt;/td>
&lt;td>10&lt;/td>
&lt;td style="text-align:left">Problem diagnosis, very detailed&lt;/td>
&lt;td style="text-align:left">Unexpected indentation in line XY&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;strong>Info&lt;/strong>&lt;/td>
&lt;td>20&lt;/td>
&lt;td style="text-align:left">Gives feedback stating that the system is running properly&lt;/td>
&lt;td style="text-align:left">Function 1*1 is executed&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;strong>Warning&lt;/strong>&lt;/td>
&lt;td>30&lt;/td>
&lt;td style="text-align:left">The application is working properly to the greatest possible extent, but an unexpected situation has occurred or a warning has been issued about a future problem&lt;/td>
&lt;td style="text-align:left">Storage space becomes scarce&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;strong>Error&lt;/strong>&lt;/td>
&lt;td>40&lt;/td>
&lt;td style="text-align:left">A function could not be executed because a problem occurred&lt;/td>
&lt;td style="text-align:left">An error occurred and the action was canceled&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;strong>Critical&lt;/strong>&lt;/td>
&lt;td>50&lt;/td>
&lt;td style="text-align:left">A serious problem has occurred and the entire application may need to be stopped&lt;/td>
&lt;td style="text-align:left">Serious error: The program cannot access this service and must be terminated&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/1*aHKt_H9yzoU_gcSlfQgDpQ.png" alt="">&lt;/p>
&lt;p>Logging with default logger:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">debug&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This is a debug message&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">info&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This is an info message&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">warning&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This is a warning message&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This is an error message&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">critical&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This is a critical message&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Output:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">WARNING:root:This is a warning message
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ERROR:root:This is an error message
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">CRITICAL:root:This is a critical message
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>Default output format: evel, name, and message separated by a colon (&lt;code>:&lt;/code>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The &lt;code>debug()&lt;/code> and &lt;code>info()&lt;/code> messages didn’t get logged.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>By default, the logging module logs the messages with a severity level of &lt;code>WARNING&lt;/code> or above.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>You can change that by configuring the logging module to log events of all levels if you want.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="basic-configurations">Basic Configurations&lt;/h2>
&lt;p>You can use the &lt;code>basicConfig(**kwargs)&lt;/code> method to configure the logging. Some of the commonly used parameters for &lt;code>basicConfig()&lt;/code> are:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;code>level&lt;/code>: The root logger will be set to the specified severity level.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">basicConfig&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">level&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DEBUG&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">debug&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This will get logged&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">DEBUG:root:This will get logged
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>&lt;code>filename&lt;/code>: file where the log information will be output to&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>filemode&lt;/code>: If &lt;code>filename&lt;/code> is given, the file is opened in this mode. The default mode is &lt;code>a&lt;/code> (append).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>format&lt;/code>: format of the log message.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">basicConfig&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">filename&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;app.log&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">filemode&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;w&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">format&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span>&lt;span class="si">%(name)s&lt;/span>&lt;span class="s1"> - &lt;/span>&lt;span class="si">%(levelname)s&lt;/span>&lt;span class="s1"> - &lt;/span>&lt;span class="si">%(message)s&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># The log message will be ouput to `app.log`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">warning&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This will get logged to a file&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;p>More parameters can be found &lt;a href="https://docs.python.org/3/library/logging.html#logging.basicConfig">here&lt;/a>.&lt;/p>
&lt;p>Note: calling &lt;code>basicConfig()&lt;/code> to configure the root logger works only if the root logger has not been configured before. &lt;strong>Basically, this function can only be called once.&lt;/strong>&lt;/p>
&lt;h2 id="formatting-the-output">Formatting the Output&lt;/h2>
&lt;p>There are some basic elements that are already a part of the &lt;code>LogRecord&lt;/code> and can be easily added to the output format, e.g.,&lt;/p>
&lt;ul>
&lt;li>
&lt;p>asctime &lt;code>%(asctime)s&lt;/code>&lt;/p>
&lt;ul>
&lt;li>The format can be changed using the &lt;code>datefmt&lt;/code> attribute, which uses the same formatting language as the formatting functions in the datetime module&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>message &lt;code>%(message)s&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>name&lt;code>%(name)s&lt;/code>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>The entire list of available attributes can be found &lt;a href="https://docs.python.org/3/library/logging.html#logrecord-attributes">here&lt;/a>.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">basicConfig&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">level&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DEBUG&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">format&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;[%(asctime)s] - %(levelname)s - %(message)s&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">datefmt&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s2"> %H:%M:%S&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">info&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;User log in&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>2023-01-11 13:50:25&lt;span class="o">]&lt;/span> - INFO - User log in
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="logging-variable-data">Logging Variable Data&lt;/h3>
&lt;p>Logging methods take a string as an argument $\rightarrow$ We can format a string with variable data using f-string.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">user_name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;John&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">basicConfig&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">level&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DEBUG&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># filename=&amp;#34;test.log&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># filemode=&amp;#34;w&amp;#34;,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">format&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;[%(asctime)s] - %(levelname)s - %(message)s&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">datefmt&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s2"> %H:%M:%S&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">info&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">user_name&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> log in&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>2023-01-11 13:55:23&lt;span class="o">]&lt;/span> - INFO - John log in
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="capturing-stack-traces">Capturing Stack Traces&lt;/h3>
&lt;p>The logging module also allows you to capture the full stack traces in an application. &lt;a href="https://realpython.com/python-exceptions/">Exception information&lt;/a> can be captured if the &lt;code>exc_info&lt;/code> parameter is passed as &lt;code>True&lt;/code>.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">try&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">c&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">b&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">except&lt;/span> &lt;span class="ne">Exception&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Exception occurred&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">exc_info&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">ERROR:root:Exception occurred
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Traceback &lt;span class="o">(&lt;/span>most recent call last&lt;span class="o">)&lt;/span>:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> File &lt;span class="s2">&amp;#34;exceptions.py&amp;#34;&lt;/span>, line 6, in &amp;lt;module&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">c&lt;/span> &lt;span class="o">=&lt;/span> a / b
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ZeroDivisionError: division by zero
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If &lt;code>exc_info&lt;/code> is not set to &lt;code>True&lt;/code>, the output of the above program would not tell us anything about the exception.&lt;/p>
&lt;p>If you’re logging from an exception handler, use the &lt;code>logging.exception()&lt;/code> method, which logs a message with level &lt;code>ERROR&lt;/code> and adds exception information to the message. Calling &lt;code>logging.exception()&lt;/code> is like calling &lt;code>logging.error(exc_info=True)&lt;/code>, which always dumps exception information.&lt;/p>
&lt;h2 id="classes-and-functions">Classes and Functions&lt;/h2>
&lt;p>You can (and should) define your own logger by &lt;a href="https://realpython.com/python3-object-oriented-programming/">creating an object&lt;/a> of the &lt;code>Logger&lt;/code> class, especially if your application has multiple modules.&lt;/p>
&lt;p>The most commonly used classes defined in the logging module are:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>&lt;code>Logger&lt;/code>:&lt;/strong> the class whose objects will be used in the application code directly to call the functions.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>&lt;code>LogRecord&lt;/code>&lt;/strong>: Loggers automatically create &lt;code>LogRecord&lt;/code> objects that have all the information related to the event being logged, like the name of the logger, the function, the line number, the message, and more.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>&lt;code>Handler&lt;/code>:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Send the &lt;code>LogRecord&lt;/code> to the required output destination, like the console or a file.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>Handler&lt;/code> is a base for subclasses like &lt;code>StreamHandler&lt;/code>, &lt;code>FileHandler&lt;/code>, &lt;code>SMTPHandler&lt;/code>, &lt;code>HTTPHandler&lt;/code>, and more. These subclasses send the logging outputs to corresponding destinations.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>&lt;code>Formatter&lt;/code>:&lt;/strong> specify the format of the output by specifying a string format that lists out the attributes that the output should contain.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>&lt;code>Filters&lt;/code>&lt;/strong>: provide a finer grained facility for determining which log records to output.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>We mostly deal with the objects of the &lt;code>Logger&lt;/code> class, which are instantiated using the module-level function &lt;code>logging.getLogger(name)&lt;/code>. Multiple calls to &lt;code>getLogger()&lt;/code> with the same &lt;code>name&lt;/code> will return a reference to the same &lt;code>Logger&lt;/code> object, which saves us from passing the logger objects to every part where it’s needed.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getLogger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;example_logger&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This creates a custom logger named &lt;code>example_logger&lt;/code>.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Unlike the root logger, the name of a custom logger is not part of the default output format and has to be added to the configuration.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>a custom logger can’t be configured using &lt;code>basicConfig()&lt;/code>. You have to configure it using Handlers and Formatters.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="using-handlers">Using Handlers&lt;/h2>
&lt;p>Handlers are useful when you want to configure your own loggers and send the logs to multiple places when they are generated.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>A logger that you create can have more than one handler $\rightarrow$ you can set it up to be output to a standard output stream and saved to a log file as well.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>You can also set the severity level in handlers&lt;/p>
&lt;ul>
&lt;li>This is useful if you want to set multiple handlers for the same logger but want different severity levels for each of them. E.g., logs with level &lt;code>WARNING&lt;/code> and above to be logged to the console, but everything with level &lt;code>ERROR&lt;/code> and above should also be saved to a file&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="example">Example&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create a custom logger&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getLogger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="vm">__name__&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create handlers&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">console_handler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">StreamHandler&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">console_handler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">setLevel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">WARNING&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">file_handler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">FileHandler&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;file.log&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">file_handler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">setLevel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ERROR&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create formatters and add to handlers&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">date_format&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s2"> %H:%M:%S&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">console_format&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Formatter&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">%(asctime)s&lt;/span>&lt;span class="s2"> - &lt;/span>&lt;span class="si">%(name)s&lt;/span>&lt;span class="s2"> - &lt;/span>&lt;span class="si">%(levelname)s&lt;/span>&lt;span class="s2"> - &lt;/span>&lt;span class="si">%(message)s&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">datefmt&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">date_format&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">console_handler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">setFormatter&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">console_format&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">file_format&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Formatter&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">%(asctime)s&lt;/span>&lt;span class="s2"> - &lt;/span>&lt;span class="si">%(name)s&lt;/span>&lt;span class="s2"> - &lt;/span>&lt;span class="si">%(levelname)s&lt;/span>&lt;span class="s2"> - &lt;/span>&lt;span class="si">%(message)s&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">datefmt&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">date_format&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">file_handler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">setFormatter&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_format&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add handlers to the logger&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">addHandler&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">console_handler&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">addHandler&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_handler&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">warning&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This is a warning&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This is an error&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">2023-01-11 14:55:01 - __main__ - WARNING - This is a warning
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2023-01-11 14:55:01 - __main__ - ERROR - This is an error
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>file.log&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">2023-01-11 14:55:01 - __main__ - ERROR - This is an error
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Here, &lt;code>logger.warning()&lt;/code> is creating a &lt;code>LogRecord&lt;/code> that holds all the information of the event and passing it to all the Handlers: &lt;code>console_handler&lt;/code> and &lt;code>file_handler&lt;/code>.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;code>console_handler&lt;/code> is a &lt;code>StreamHandler&lt;/code> with level &lt;code>WARNING&lt;/code> and takes the info from the &lt;code>LogRecord&lt;/code> to generate an output in the format specified and prints it to the console.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>file_handler&lt;/code> is a &lt;code>FileHandler&lt;/code> with level &lt;code>ERROR&lt;/code>, and it ignores this &lt;code>LogRecord&lt;/code> as its level is &lt;code>WARNING&lt;/code>.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>When &lt;code>logger.error()&lt;/code> is called,&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;code>console_handler&lt;/code> behaves exactly as before&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>file_handler&lt;/code> gets a &lt;code>LogRecord&lt;/code> at the level of &lt;code>ERROR&lt;/code>, so it proceeds to generate an output and writes it to the specified file&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Note: The name of the logger corresponding to the &lt;code>__name__&lt;/code> variable is logged as &lt;code>__main__&lt;/code>, which is the name Python assigns to the module where execution starts. If this file is imported by some other module, then the &lt;code>__name__&lt;/code> variable would correspond to its name &lt;em>logging_example&lt;/em>.&lt;/p>
&lt;h2 id="other-configuration-methods">Other Configuration Methods&lt;/h2>
&lt;p>Except using the module and class functions to configure logging (as above), you can also configure logging by create a &lt;strong>config file&lt;/strong> or a **dictionary **and loading it using &lt;code>fileConfig()&lt;/code> or &lt;code>dictConfig()&lt;/code>, respectively.&lt;/p>
&lt;h3 id="file-configuration">File configuration&lt;/h3>
&lt;p>&lt;code>logging.conf&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">loggers&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">keys&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">root&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="nx">sampleLogger&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">handlers&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">keys&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">consoleHandler&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">formatters&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">keys&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">sampleFormatter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">logger_root&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">level&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">DEBUG&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">handlers&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">consoleHandler&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">logger_sampleLogger&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">level&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">DEBUG&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">handlers&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">consoleHandler&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">qualname&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">sampleLogger&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">propagate&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="mi">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">handler_consoleHandler&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">class&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">StreamHandler&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">level&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">DEBUG&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">formatter&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">sampleFormatter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">args&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="err">(&lt;/span>&lt;span class="nx">sys&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">stdout&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="err">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">formatter_sampleFormatter&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">format&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="err">%(&lt;/span>&lt;span class="nx">asctime&lt;/span>&lt;span class="err">)&lt;/span>&lt;span class="nx">s&lt;/span> &lt;span class="nx">-&lt;/span> &lt;span class="err">%(&lt;/span>&lt;span class="nx">name&lt;/span>&lt;span class="err">)&lt;/span>&lt;span class="nx">s&lt;/span> &lt;span class="nx">-&lt;/span> &lt;span class="err">%(&lt;/span>&lt;span class="nx">levelname&lt;/span>&lt;span class="err">)&lt;/span>&lt;span class="nx">s&lt;/span> &lt;span class="nx">-&lt;/span> &lt;span class="err">%(&lt;/span>&lt;span class="nx">message&lt;/span>&lt;span class="err">)&lt;/span>&lt;span class="nx">s&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>There are two loggers, one handler, and one formatter&lt;/p>
&lt;/li>
&lt;li>
&lt;p>After their names are defined, they are configured by adding the words logger, handler, and formatter before their names separated by an underscore.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Use &lt;code>fileConfig()&lt;/code> to load this config file&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging.config&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">pathlib&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Path&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging_conf_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Path&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="vm">__file__&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">parent&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">joinpath&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;logging.conf&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">assert&lt;/span> &lt;span class="n">logging_conf_path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exists&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fileConfig&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">fname&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">logging_conf_path&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">disable_existing_loggers&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getLogger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="vm">__name__&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">debug&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;This is a debug message.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="dictionary-configuration">Dictionary configuration&lt;/h3>
&lt;p>Same configuration in a &lt;a href="https://realpython.com/python-yaml/">YAML&lt;/a> format for the dictionary approach:&lt;/p>
&lt;p>To configure loggers or handlers, specify attributes as key-values pairs in yaml.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">handlers&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">console&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">class&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">logging.StreamHandler&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">level&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">DEBUG&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>is equivalent to&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">console_handler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">StreamHandler&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">console_handler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">setLevel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DEBUG&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="example-logging_configyaml">Example: &lt;code>logging_config.yaml&lt;/code>&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">formatters&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">simple&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">format&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;%(asctime)s - %(name)s - %(levelname)s - %(message)s&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">handlers&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">console&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">class&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">logging.StreamHandler&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">level&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">DEBUG&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">formatter&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">simple&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">stream&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ext://sys.stdout&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">loggers&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">sampleLogger&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">level&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">DEBUG&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">handlers&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">console]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">propagate&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">no&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">root&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">level&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">DEBUG&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">handlers&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="l">console]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">logging.config&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">yaml&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">pathlib&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Path&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">config_file_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Path&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="vm">__file__&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">parent&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">joinpath&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;logging_config.yaml&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">assert&lt;/span> &lt;span class="n">config_file_path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exists&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">with&lt;/span> &lt;span class="nb">open&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">config_file_path&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">yaml&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">safe_load&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">f&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dictConfig&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">config&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">logging&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getLogger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="vm">__name__&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">debug&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;This is a debug message&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="gotchas">Gotchas&lt;/h2>
&lt;h3 id="setlevel-is-being-ignored">&lt;code>setLevel()&lt;/code> is being ignored&lt;/h3>
&lt;p>In Python &lt;code>logging&lt;/code> package, there are two &lt;code>setLevel()&lt;/code> methods:&lt;/p>
&lt;ul>
&lt;li>The &lt;a href="https://docs.python.org/3/library/logging.html">&lt;code>setLevel()&lt;/code> of &lt;code>Logger&lt;/code>&lt;/a> determines which severity &lt;em>level&lt;/em> of messages it will pass to its handlers. Logging messages which are less severe than &lt;em>level&lt;/em> will be ignored.&lt;/li>
&lt;li>The &lt;code>setLevel()&lt;/code> of &lt;code>Logger&lt;/code> determines which level of messages that handler will send on.&lt;/li>
&lt;/ul>
&lt;p>Reference: &lt;a href="https://stackoverflow.com/questions/64783221/logging-level-is-info-but-only-warnings-are-shown-python-logging">Logging level is info, but only warnings are shown. Python logging - Stack Overflow&lt;/a>&lt;/p>
&lt;h2 id="reference">Reference&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://realpython.com/python-logging/#the-logging-module">Logging in Python – Real Python&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>loguru</title><link>https://haobin-tan.netlify.app/docs/coding/python/useful_packages/loguru/</link><pubDate>Thu, 16 Feb 2023 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/coding/python/useful_packages/loguru/</guid><description>&lt;p>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/logo.png" alt="GitHub - Delgan/loguru: Python logging made (stupidly) simple">&lt;/p>
&lt;p>&lt;strong>Loguru&lt;/strong> is a library which aims to bring enjoyable logging in Python. It is intended to make Python logging less painful by adding a bunch of useful functionalities that solve caveats of the standard loggers.&lt;/p>
&lt;h2 id="tutorial">Tutorial&lt;/h2>
&lt;p>See: &lt;a href="https://betterstack.com/community/guides/logging/loguru/">A Complete Guide to Logging in Python with Loguru&lt;/a>&lt;/p>
&lt;h2 id="loguru-vs-built-in-logging">&lt;code>loguru&lt;/code> vs. Built-in &lt;code>logging&lt;/code>&lt;/h2>
&lt;p>See&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://alimbekov.com/en/python-logging-vs-loguru/">Python logging HOWTO: logging vs loguru. Python Practice.&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Switch from standard &lt;code>logging&lt;/code> to &lt;code>loguru&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://loguru.readthedocs.io/en/stable/resources/migration.html">Switching from standard logging to loguru — loguru documentation&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://qxf2.com/blog/replace-python-standard-logging-with-loguru/">Replace Python standard logging mechanism with Loguru&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="issues-and-solutions">Issues and Solutions&lt;/h2>
&lt;h3 id="apply-default-level-color-in-custom-format">Apply default level color in custom format&lt;/h3>
&lt;p>Use the special tag &lt;code>&amp;lt;level&amp;gt;&lt;/code> in custom format.&lt;/p>
&lt;blockquote>
&lt;p>The special tag &lt;code>&amp;lt;level&amp;gt;&lt;/code> (abbreviated with &lt;code>&amp;lt;lvl&amp;gt;&lt;/code>) is transformed according to the configured color of the logged message level.&lt;/p>
&lt;/blockquote>
&lt;p>Reference&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://stackoverflow.com/questions/70977165/how-to-use-loguru-defaults-and-extra-information">python - How to use Loguru defaults + and extra information? - Stack Overflow&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://github.com/Delgan/loguru/issues/122">default message color · Issue #122 · Delgan/loguru · GitHub&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h3 id="integrate-richloggingrichhandler">Integrate &lt;code>rich.logging.RichHandler&lt;/code>&lt;/h3>
&lt;p>Use&lt;a href="https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.configure"> &lt;code>configure()&lt;/code> method&lt;/a> of &lt;code>loguru.logger&lt;/code>.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">rich.logging&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RichHandler&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">loguru&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">logger&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">rich_handler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RichHandler&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">logger&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">configure&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">handlers&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;sink&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">rich_handler&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;format&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{message}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="reference">Reference&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://loguru.readthedocs.io/en/stable/index.html">loguru documentation&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://betterstack.com/community/guides/logging/loguru/">A Complete Guide to Logging in Python with Loguru&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://qxf2.com/blog/replace-python-standard-logging-with-loguru/">Replace Python standard logging mechanism with Loguru&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://alimbekov.com/en/python-logging-vs-loguru/">Python logging HOWTO: logging vs loguru. Python Practice.&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul></description></item></channel></rss>