<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Python - Category - JMS Blog</title><link>/categories/python/</link><description>Python - Category - JMS Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 12 Aug 2020 00:00:00 +0000</lastBuildDate><atom:link href="/categories/python/" rel="self" type="application/rss+xml"/><item><title>Timezone lookup using latitude and longitud (part 2)</title><link>/posts/2020-08-12-timezone-finder-2/</link><pubDate>Wed, 12 Aug 2020 00:00:00 +0000</pubDate><author>jms</author><guid>/posts/2020-08-12-timezone-finder-2/</guid><description><![CDATA[<p>For the fastapi project we are going to use Sqlalchemy and postgresql
taking some reference from the fastapi documentation.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># create a virtualenv, with any tool: poetry, pipenv, virtualenv module, etc </span>
</span></span><span class="line"><span class="cl">pip install fastapi uvicorn aiofiles SQLAlchemy psycopg2-binary</span></span></code></pre></div></div>
<p>project structure</p>
<div class="code-block code-line-numbers" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">.
</span></span><span class="line"><span class="cl">├── Dockerfile
</span></span><span class="line"><span class="cl">├── LICENSE
</span></span><span class="line"><span class="cl">├── main.py
</span></span><span class="line"><span class="cl">├── README.md
</span></span><span class="line"><span class="cl">├── requirements.txt
</span></span><span class="line"><span class="cl">└── timezone_utils
</span></span><span class="line"><span class="cl">    ├── database.py
</span></span><span class="line"><span class="cl">    ├── __init__.py
</span></span><span class="line"><span class="cl">    ├── models.py
</span></span><span class="line"><span class="cl">    ├── schemas.py
</span></span><span class="line"><span class="cl">    └── utils.py
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="m">1</span> directory, <span class="m">10</span> files</span></span></code></pre></div></div>
<p>we define the models, schemas and engine for sqlalchemy and the api in the package <code>timezone_utils</code></p>]]></description></item><item><title>Timezone lookup using latitude and longitude (part 1)</title><link>/posts/2020-08-11-timezone-finder-1/</link><pubDate>Tue, 11 Aug 2020 00:00:00 +0000</pubDate><author>jms</author><guid>/posts/2020-08-11-timezone-finder-1/</guid><description><![CDATA[<p>First timezones are evil, but sometimes you need to work with them. Sometimes is easy to consume some third party api to get timezone information based on a given location using geocoding but there also exists some alternatives.</p>
<p>Then inspired on this <a href="https://github.com/evansiroky/timezone-boundary-builder" target="_blank" rel="noopener noreffer ">blog post</a> and the project <a href="https://github.com/evansiroky/timezone-boundary-builder" target="_blank" rel="noopener noreffer ">Timezone boundary builder</a> decided to create a test project using fastapi and postgis to do the timezone lookup using the latitude and longitude.</p>]]></description></item><item><title>Flask logging setup</title><link>/posts/2019-05-27-flask-logging/</link><pubDate>Mon, 27 May 2019 00:00:00 +0000</pubDate><author>jms</author><guid>/posts/2019-05-27-flask-logging/</guid><description><![CDATA[<p>Setup a python logging configuration with dictConfig</p>
<p>Logging configuration can be defined on different ways like a dict, ini file, yaml or json
somethimes is more flexible to do it on code with python, all depends on the use case.</p>
<p>This small example show how to setup the logging configuration using <code>dictConfig</code> method and how to add an user defined object to the logging filter.</p>
<div class="code-block code-line-numbers" style="counter-reset: code-block 0">
    <div class="code-header language-python">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">os</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">logging</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">socket</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">logging.config</span> <span class="kn">import</span> <span class="n">dictConfig</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ContextFilter</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">Filter</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">hostname</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">gethostname</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">record</span><span class="o">.</span><span class="n">hostname</span> <span class="o">=</span> <span class="n">ContextFilter</span><span class="o">.</span><span class="n">hostname</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">logging_configuration</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">version</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">disable_existing_loggers</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">formatters</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;default&#34;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;[</span><span class="si">%(hostname)s</span><span class="s2"> </span><span class="si">%(asctime)s</span><span class="s2">] </span><span class="si">%(levelname)s</span><span class="s2"> in </span><span class="si">%(module)s</span><span class="s2">: </span><span class="si">%(message)s</span><span class="s2">&#34;</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="n">filters</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;hostname_filter&#34;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&#34;()&#34;</span><span class="p">:</span> <span class="n">ContextFilter</span><span class="p">}},</span>
</span></span><span class="line"><span class="cl">    <span class="n">handlers</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;console&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;class&#34;</span><span class="p">:</span> <span class="s2">&#34;logging.StreamHandler&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;formatter&#34;</span><span class="p">:</span> <span class="s2">&#34;default&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;filters&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;hostname_filter&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="n">root</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;handlers&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;console&#34;</span><span class="p">],</span> <span class="s2">&#34;level&#34;</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&#34;LOG_LEVEL&#34;</span><span class="p">,</span> <span class="s2">&#34;INFO&#34;</span><span class="p">)},</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">dictConfig</span><span class="p">(</span><span class="n">logging_configuration</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@app.route</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">home</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&#34;debug message&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&#34;info message&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&#34;warning message&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&#34;error message&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">logger</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s2">&#34;critical error message&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s2">&#34;Hello World&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&#34;__main__&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">()</span></span></span></code></pre></div></div>
<p>The filter <code>hostname_filter</code> use the special key <code>&quot;()&quot;</code> which means that user-defined instantiation is wanted. <code>ContextFilter</code> subclass <code>logging.Filter</code> and overrides the <code>filter</code> method so when key <code>hostname</code> is found it will get his value from the <code>ContextFilter</code> class using <code>socket.gethostname()</code> and the application output will show:</p>]]></description></item><item><title>Checking and validating phone numbers</title><link>/posts/2015-06-09-checking-and-validating-phone-numbers/</link><pubDate>Tue, 09 Jun 2015 00:00:00 +0000</pubDate><author>jms</author><guid>/posts/2015-06-09-checking-and-validating-phone-numbers/</guid><description><![CDATA[<p>In applications sometimes is needed check and verify if a phone number is
valid or possible if the number have all required digits to be valid for this
purpose there are several options to tackle the problem like regular
expressions for example to validate <a href="http://en.wikipedia.org/wiki/E.164" target="_blank" rel="noopener noreffer ">E.164
format</a>, library like the [Google
libphonenumber](http://Google libphonenumber) and API like the <a href="https://www.twilio.com/lookup" target="_blank" rel="noopener noreffer ">Twillio
Lookup</a> for something more complete.</p>
<p>for this post i created a small app for test a demo purpose using the [python
port of the Google library](<a href="https://github.com/daviddrysdale/python-" target="_blank" rel="noopener noreffer ">https://github.com/daviddrysdale/python-</a>
phonenumbers)</p>]]></description></item></channel></rss>