<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Andrey Zhukov&#39;s Tech Blog</title>
    <link>https://blog.sneawo.com/</link>
    <description>Recent content on Andrey Zhukov&#39;s Tech Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 03 Aug 2024 09:30:00 +0000</lastBuildDate>
    <atom:link href="https://blog.sneawo.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>I&#39;m moving to Substack</title>
      <link>https://blog.sneawo.com/blog/2024/08/03/im-moving-to-substack/</link>
      <pubDate>Sat, 03 Aug 2024 09:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/08/03/im-moving-to-substack/</guid>
      <description>&lt;p&gt;You can subscribe &lt;a href=&#34;https://azhukov.substack.com/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Technical posts with code examples stays on this site.&lt;/p&gt;</description>
    </item>
    <item>
      <title>5 reasons I&#39;m not buying the new iPad Pro M4 (2024)</title>
      <link>https://blog.sneawo.com/blog/2024/06/22/5-reasons-im-not-buying-the-new-ipad-pro-m4-2024/</link>
      <pubDate>Sat, 22 Jun 2024 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/06/22/5-reasons-im-not-buying-the-new-ipad-pro-m4-2024/</guid>
      <description>&lt;p&gt;I have &lt;a href=&#34;https://blog.sneawo.com/blog/2021/06/27/my-5-use-cases-for-ipad/&#34;&gt;iPad Pro 11&amp;quot;&lt;/a&gt; since 2020.&#xA;I use it daily. Here is why I don&amp;rsquo;t upgrade to the &lt;a href=&#34;https://amzn.to/4bKrWQO&#34;&gt;new M4 version&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>3 upstream errors in Nginx ingress with Gunicorn/Flask as backend in Kubernetes environment</title>
      <link>https://blog.sneawo.com/blog/2024/05/28/3-upstream-errors-in-nginx-ingress-with-gunicorn/flask-as-backend-in-kubernetes-environment/</link>
      <pubDate>Tue, 28 May 2024 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/05/28/3-upstream-errors-in-nginx-ingress-with-gunicorn/flask-as-backend-in-kubernetes-environment/</guid>
      <description>&lt;p&gt;Recently I faced 3 types of upsteam errors. It was like 2% of all requests, but it was quite annoying.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to plan a day as Indie Developer</title>
      <link>https://blog.sneawo.com/blog/2024/05/14/how-to-plan-a-day-as-indie-developer/</link>
      <pubDate>Tue, 14 May 2024 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/05/14/how-to-plan-a-day-as-indie-developer/</guid>
      <description>&lt;p&gt;This year 1st May was Wednesday. I took another 2 days from my 9-5 job and 2 days from the weekend. The goal was to build a schedule as if I were an indie developer. The main project was to develop an idea for a new iOS app.&lt;/p&gt;</description>
    </item>
    <item>
      <title>8 macOS productivity apps in 2024</title>
      <link>https://blog.sneawo.com/blog/2024/04/28/8-macos-productivity-apps-in-2024/</link>
      <pubDate>Sun, 28 Apr 2024 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/04/28/8-macos-productivity-apps-in-2024/</guid>
      <description>&lt;p&gt;Several apps that help to be more focused and organized.&lt;/p&gt;</description>
    </item>
    <item>
      <title>12-Week Review - Q1/2024</title>
      <link>https://blog.sneawo.com/blog/2024/04/14/12-week-review-q1/2024/</link>
      <pubDate>Sun, 14 Apr 2024 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/04/14/12-week-review-q1/2024/</guid>
      <description>&lt;p&gt;For accountability, I decided to publish 12-week reviews. In a month there is not always something big happening, so I start with a year quarter. Maybe I&amp;rsquo;ll transform it into a newsletter later.&#xA;I&amp;rsquo;ll publish it as a YouTube video too.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Protocol buffers organization in Python microservices</title>
      <link>https://blog.sneawo.com/blog/2024/03/20/protocol-buffers-organization-in-python-microservices/</link>
      <pubDate>Wed, 20 Mar 2024 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/03/20/protocol-buffers-organization-in-python-microservices/</guid>
      <description>&lt;p&gt;In this post one of the approaches to organizing Protobuf files in microservices architecture using gRPC.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to move to a new Mac without Migration Assistant</title>
      <link>https://blog.sneawo.com/blog/2024/03/07/how-to-move-to-a-new-mac-without-migration-assistant/</link>
      <pubDate>Thu, 07 Mar 2024 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/03/07/how-to-move-to-a-new-mac-without-migration-assistant/</guid>
      <description>&lt;p&gt;Last summer I got a new MacBook Pro M2 and decided to go with a fresh install. With my previous MacBooks, I used Migration Assistant and it worked well. But this time it was a switch from Intel and I wanted to clean unnecessary files, applications, and settings.&lt;/p&gt;&#xA;&lt;p&gt;Here is the list of files I moved and apps I installed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Overcome Procrastination: A Mindset Shift for Productivity</title>
      <link>https://blog.sneawo.com/blog/2024/02/09/how-to-overcome-procrastination-a-mindset-shift-for-productivity/</link>
      <pubDate>Fri, 09 Feb 2024 06:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/02/09/how-to-overcome-procrastination-a-mindset-shift-for-productivity/</guid>
      <description>&lt;p&gt;As responsible individuals, we often find ourselves prioritizing others over our own goals. If you’ve ever struggled to make progress on a personal project, this mindset change might be the key to unlocking your productivity.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Essential Python tools for writing quality code</title>
      <link>https://blog.sneawo.com/blog/2024/01/27/essential-python-tools-for-writing-quality-code/</link>
      <pubDate>Sat, 27 Jan 2024 06:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/01/27/essential-python-tools-for-writing-quality-code/</guid>
      <description>&lt;p&gt;Writing quality code is essential for both personal and team projects. It helps to reduce the number of bugs, makes the code more readable and maintainable, and improves the overall quality of the project.&lt;/p&gt;&#xA;&lt;p&gt;In this article some basic libraries that I use in everyday life.&lt;/p&gt;</description>
    </item>
    <item>
      <title>2023 Achievements</title>
      <link>https://blog.sneawo.com/blog/2024/01/11/2023-achievements/</link>
      <pubDate>Thu, 11 Jan 2024 06:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2024/01/11/2023-achievements/</guid>
      <description>&lt;p&gt;This blog has been on hold since 2020, and every year I’m thinking of restarting it. This year is no exception.&lt;/p&gt;&#xA;&lt;p&gt;The stopping factor was that it’s the technical blog. Yet, I write a lot during journaling and when preparing YouTube videos.&#xA;I don’t know if I’ll be able to transform them into blog posts, but I’ll try.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to replace azure-storage</title>
      <link>https://blog.sneawo.com/blog/2023/01/25/how-to-replace-azure-storage/</link>
      <pubDate>Wed, 25 Jan 2023 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2023/01/25/how-to-replace-azure-storage/</guid>
      <description>&lt;p&gt;Continue of previous task.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#xA;from azure.storage.blob import BlockBlobService, ContentSettings, PublicAccess&#xA;BlockBlobService(&#xA;                account_name=cluster_config[&amp;#34;config&amp;#34;][&amp;#34;AZURE_STORAGE_ACCOUNT&amp;#34;],&#xA;                account_key=cluster_config[&amp;#34;config&amp;#34;][&amp;#34;AZURE_STORAGE_KEY&amp;#34;],&#xA;            )&#xA;storage.create_container(container_name, public_access=PublicAccess.Blob)&#xA;        storage.create_blob_from_bytes(&#xA;            container_name, blob_name, content, content_settings=ContentSettings(content_type=content_type) &#xA;block_blob_service.create_blob_from_stream(&#xA;                folder_name, filename, content, content_settings=ContentSettings(content_type=mimetype)&#xA;            )                       &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#xA;from azure.storage.blob import ContainerClient, ContentSettings, PublicAccess&#xA;account_name = cluster_config[&amp;#34;config&amp;#34;][&amp;#34;AZURE_STORAGE_ACCOUNT&amp;#34;]&#xA;        account_key = cluster_config[&amp;#34;config&amp;#34;][&amp;#34;AZURE_STORAGE_KEY&amp;#34;]&#xA;        account_url = f&amp;#34;https://{account_name}.blob.core.windows.net&amp;#34;&#xA;        container_clients.append(&#xA;            ContainerClient(account_url=account_url, credential=account_key, container_name=container_name)&#xA;if not container_client.exists():&#xA;            container_client.create_container(public_access=PublicAccess.Blob)  # exception, or overwrite true&#xA;        container_client.get_blob_client(blob_name).upload_blob(&#xA;            content, content_settings=ContentSettings(content_type=content_type)            , overwrite=Tru&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>How to replace oauth2client with google-auth and google-auth-oauthlib</title>
      <link>https://blog.sneawo.com/blog/2023/01/17/how-to-replace-oauth2client-with-google-auth-and-google-auth-oauthlib/</link>
      <pubDate>Tue, 17 Jan 2023 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2023/01/17/how-to-replace-oauth2client-with-google-auth-and-google-auth-oauthlib/</guid>
      <description>&lt;p&gt;Recently I made an update for some legacy code and one of the tasks was to replace &lt;a href=&#34;https://github.com/googleapis/oauth2client&#34;&gt;oauth2client&lt;/a&gt;.&#xA;This library used to interact with OAuth2-protected resources related to Google API and deprecated since September 2018.&#xA;The recomendation is to use &lt;a href=&#34;https://google-auth.readthedocs.io/en/master/&#34;&gt;google-auth&lt;/a&gt; and for OAuth 2 flow &lt;a href=&#34;https://github.com/googleapis/google-auth-library-python-oauthlib&#34;&gt;google-auth-oauthlib&lt;/a&gt;. The changes are simple.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to use asyncio gRPC in AioHTTP microservices</title>
      <link>https://blog.sneawo.com/blog/2022/01/23/how-to-use-asyncio-grpc-in-aiohttp-microservices/</link>
      <pubDate>Sun, 23 Jan 2022 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2022/01/23/how-to-use-asyncio-grpc-in-aiohttp-microservices/</guid>
      <description>&lt;p&gt;Usually I have a lot of microservices and they communicate using REST API.&#xA;For communication with frontend I still need REST, but between microservices &lt;a href=&#34;https://grpc.io/about/&#34;&gt;gRPC&lt;/a&gt; looks more promising.&lt;/p&gt;&#xA;&lt;p&gt;Some benefits of it:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;is built on HTTP2, using multiplexed streams - better connection management&lt;/li&gt;&#xA;&lt;li&gt;performance benefits because of Protobuf binary format&lt;/li&gt;&#xA;&lt;li&gt;code generation for a multilingual environment&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Here is my first attempt to use gRPC in AioHTTP applications with some explanations.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Celery queues monitoring in Datadog</title>
      <link>https://blog.sneawo.com/blog/2021/09/07/celery-queues-monitoring-in-datadog/</link>
      <pubDate>Tue, 07 Sep 2021 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2021/09/07/celery-queues-monitoring-in-datadog/</guid>
      <description>&lt;p&gt;If you have Redis integration in &lt;a href=&#34;https://www.datadoghq.com&#34;&gt;Datadog&lt;/a&gt;, there is an easy way to add monitoring for celery queues.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to send celery task from async code</title>
      <link>https://blog.sneawo.com/blog/2021/08/16/how-to-send-celery-task-from-async-code/</link>
      <pubDate>Mon, 16 Aug 2021 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2021/08/16/how-to-send-celery-task-from-async-code/</guid>
      <description>&lt;p&gt;The more simple way is to add an endpoint to the service with celery.&#xA;Here is an example of a low level way based on &lt;a href=&#34;https://docs.celeryproject.org/en/stable/internals/protocol.html&#34;&gt;Message Protocol&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>IQUNIX A80 mechanichal keyboard - first impressions</title>
      <link>https://blog.sneawo.com/blog/2021/07/06/iqunix-a80-mechanichal-keyboard-first-impressions/</link>
      <pubDate>Tue, 06 Jul 2021 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2021/07/06/iqunix-a80-mechanichal-keyboard-first-impressions/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s my first mechanical keyboard and it&amp;rsquo;s about a year that I&amp;rsquo;m interesting to try it. I like my apple keyboard, but there are so many reviews for the mechanical ones,&#xA;so finally I gave up and bought this IQUNIX A80.&lt;/p&gt;</description>
    </item>
    <item>
      <title>My 5 use cases for iPad</title>
      <link>https://blog.sneawo.com/blog/2021/06/27/my-5-use-cases-for-ipad/</link>
      <pubDate>Sun, 27 Jun 2021 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2021/06/27/my-5-use-cases-for-ipad/</guid>
      <description>&lt;p&gt;I bought &lt;a href=&#34;https://amzn.to/3wzIeY5&#34;&gt;iPad 11&amp;quot;&lt;/a&gt; one year ago and I had a lot of doubts about it usefulness, it&amp;rsquo;s not one of the cheapest devices.&#xA;If you are in the same position, maybe this post will help you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to replace celery banner with one log line</title>
      <link>https://blog.sneawo.com/blog/2021/06/17/how-to-replace-celery-banner-with-one-log-line/</link>
      <pubDate>Thu, 17 Jun 2021 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2021/06/17/how-to-replace-celery-banner-with-one-log-line/</guid>
      <description>&lt;p&gt;If you, like me, suffer from celery banner in your logs, but still want to see useful information from it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Blog performance after a year of inactivity</title>
      <link>https://blog.sneawo.com/blog/2021/06/09/blog-performance-after-a-year-of-inactivity/</link>
      <pubDate>Wed, 09 Jun 2021 06:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2021/06/09/blog-performance-after-a-year-of-inactivity/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s almost a year that I did not post anything to this blog and here is a chart from Google Analytics.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to update a script with azcopy v7 to v10</title>
      <link>https://blog.sneawo.com/blog/2020/07/02/how-to-update-a-script-with-azcopy-v7-to-v10/</link>
      <pubDate>Thu, 02 Jul 2020 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2020/07/02/how-to-update-a-script-with-azcopy-v7-to-v10/</guid>
      <description>Here is the previous version of the script to transfer containers between storages.&#xA;AzCopy v10 has totally different parameters, in fact, it&amp;rsquo;s another utility that does the same thing. Instead of --source, --dest parameters, it now requires a SAS token.&#xA;#!/bin/bash CONTAINER_NAME=$1 SOURCE_STORAGE_NAME=$2 SOURCE_STORAGE_KEY=$3 TARGET_STORAGE_NAME=$4 TARGET_STORAGE_KEY=$5 source_exists=$(az storage container exists --name $CONTAINER_NAME --account-name $SOURCE_STORAGE_NAME --account-key $SOURCE_STORAGE_KEY --output tsv) if [ $source_exists != &amp;#34;True&amp;#34; ]; then echo &amp;#34;Source container does not exist.</description>
    </item>
    <item>
      <title>Calling python async function from sync code</title>
      <link>https://blog.sneawo.com/blog/2020/06/06/calling-python-async-function-from-sync-code/</link>
      <pubDate>Sat, 06 Jun 2020 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2020/06/06/calling-python-async-function-from-sync-code/</guid>
      <description>&lt;p&gt;This is an example of how to transform sequential requests to parallel in some legacy code with asyncio loop when the refactoring is not an option.&lt;/p&gt;&#xA;&lt;p&gt;To show the idea I&amp;rsquo;m using a simplified version of microsoft graph api requests to &lt;a href=&#34;https://docs.microsoft.com/en-us/graph/api/user-list-manager?view=graph-rest-beta&#34;&gt;get user manager&lt;/a&gt; by user ids.&lt;/p&gt;</description>
    </item>
    <item>
      <title>VSCode settings and plugins</title>
      <link>https://blog.sneawo.com/blog/2020/05/30/vscode-settings-and-plugins/</link>
      <pubDate>Sat, 30 May 2020 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2020/05/30/vscode-settings-and-plugins/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s almost two years when I switched to VSCode from IntelliJ IDEA. The last license expired in September 2018.&#xA;Sometimes I switched back to IDEA when there were problems with Python Language Server or pytests discovering,&#xA;but it did not last long. The IDEA is good, it works well, but it&amp;rsquo;s too heavy for me, even if I do not restart it often.&#xA;With VSCode I still have sometimes problems with &amp;ldquo;Go to Definition&amp;rdquo;, but most of the time it solves with&#xA;a simple reload, which takes just several seconds.&lt;/p&gt;&#xA;&lt;h2 id=&#34;settings&#34;&gt;Settings&lt;/h2&gt;&#xA;&lt;p&gt;Mostly I&amp;rsquo;m using the settings by default, here are some changes:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to set environment variables for pytest in VSCode</title>
      <link>https://blog.sneawo.com/blog/2020/05/23/how-to-set-environment-variables-for-pytest-in-vscode/</link>
      <pubDate>Sat, 23 May 2020 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2020/05/23/how-to-set-environment-variables-for-pytest-in-vscode/</guid>
      <description>To run tests I usually use database with tmpfs volume, sometimes it makes them more than twice faster. To achieve this I run the database on another port and use env variable in application config, like this&#xA;docker run -d --name=mongo_test -p 27018:27017 --tmpfs /data/db mongo:4.2.3 MONGODB_URI=mongodb://localhost:27018/test_db pytest --cov=app tests The configuration for env variables in VSCode is simple, you need to place .env file into your project and add &amp;quot;python.</description>
    </item>
    <item>
      <title>RabbitMQ with AioHttp example</title>
      <link>https://blog.sneawo.com/blog/2020/05/17/rabbitmq-with-aiohttp-example/</link>
      <pubDate>Sun, 17 May 2020 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2020/05/17/rabbitmq-with-aiohttp-example/</guid>
      <description>&lt;p&gt;In this example I have two services:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;auth which sends an event that user is authenticated&lt;/li&gt;&#xA;&lt;li&gt;users which listen for this event and update user&amp;rsquo;s last online time.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;These services use &lt;a href=&#34;https://aio-pika.readthedocs.io/en/latest/&#34;&gt;aio_pika&lt;/a&gt; library for async RabbitMQ connection&#xA;and &lt;a href=&#34;https://www.rabbitmq.com/tutorials/tutorial-five-python.html&#34;&gt;topic&lt;/a&gt; exchange for the message routing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to run several docker-compose projects with their traefik in each on the same server</title>
      <link>https://blog.sneawo.com/blog/2020/04/22/how-to-run-several-docker-compose-projects-with-their-traefik-in-each-on-the-same-server/</link>
      <pubDate>Wed, 22 Apr 2020 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2020/04/22/how-to-run-several-docker-compose-projects-with-their-traefik-in-each-on-the-same-server/</guid>
      <description>The configuration is simple, for each project a docker-compose project name and port should be defined. It can be done with .env files.&#xA;COMPOSE_PROJECT_NAME=project1 PORT=8081 Docker compose will use COMPOSE_PROJECT_NAME variable as a prefix for the names of the containers.&#xA;Then in docker-compose.yml, these variables can be used to define the port mapping and the traefik constraints.&#xA;services: traefik: image: &amp;#34;traefik:v2.1.7&amp;#34; command: ... - &amp;#34;--providers.docker.constraints=Label(`com.docker.compose.project`, `${COMPOSE_PROJECT_NAME}`)&amp;#34; ports: ... - &amp;#34;${PORT}:80&amp;#34; This can be used to run different projects or several instances of one project to test different branches.</description>
    </item>
    <item>
      <title>Traefik dashboard on another port and with authentication</title>
      <link>https://blog.sneawo.com/blog/2020/04/14/traefik-dashboard-on-another-port-and-with-authentication/</link>
      <pubDate>Tue, 14 Apr 2020 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2020/04/14/traefik-dashboard-on-another-port-and-with-authentication/</guid>
      <description>Here is an example for Traefik dashbord on port 9090 and with basic auth middleware.&#xA;To generate password:&#xA;echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g For services routers it&amp;rsquo;s important to set entryPoints with correct port: &amp;quot;traefik.http.routers.ui.entryPoints=web&amp;quot;.&#xA;version: &amp;#39;3.3&amp;#39; services: ui: image: &amp;#34;ui:v1.0.0&amp;#34; restart: always labels: - &amp;#34;traefik.enable=true&amp;#34; - &amp;#34;traefik.http.routers.ui.entryPoints=web&amp;#34; - &amp;#34;traefik.http.routers.ui.rule=Host(`${HOST_NAME}`)&amp;#34; - &amp;#34;traefik.http.services.ui.loadbalancer.server.port=8080&amp;#34; - &amp;#34;traefik.http.services.ui.loadbalancer.server.scheme=http&amp;#34; traefik: image: &amp;#34;traefik:v2.1.7&amp;#34; restart: always command: - &amp;#34;--providers.docker=true&amp;#34; - &amp;#34;--providers.docker.exposedbydefault=false&amp;#34; - &amp;#34;--entrypoints.web.address=:80&amp;#34; - &amp;#34;--entrypoints.</description>
    </item>
    <item>
      <title>How to clone MongoDB collection indexes from one server to another</title>
      <link>https://blog.sneawo.com/blog/2020/03/23/how-to-clone-mongodb-collection-indexes-from-one-server-to-another/</link>
      <pubDate>Mon, 23 Mar 2020 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2020/03/23/how-to-clone-mongodb-collection-indexes-from-one-server-to-another/</guid>
      <description>from pymongo import MongoClient def clean_indexes(indexes): &amp;#34;&amp;#34;&amp;#34;Remove index for id and clean ns attribute.&amp;#34;&amp;#34;&amp;#34; for index in indexes: if index[&amp;#39;name&amp;#39;] == &amp;#39;_id_&amp;#39;: continue index.pop(&amp;#39;ns&amp;#39;, None) yield index def get_indexes(db): &amp;#34;&amp;#34;&amp;#34;Get map collection name -&amp;gt; list of cleaned indexes.&amp;#34;&amp;#34;&amp;#34; coll_indexes_map = {} for coll in db_source.list_collections(): coll_name = coll[&amp;#39;name&amp;#39;] coll_indexes_map[coll_name] = list(clean_indexes(list(db[coll_name].list_indexes()))) return coll_indexes_map def create_indexes(db, coll_indexes_map): for coll_name, indexes in coll_indexes_map.items(): if indexes: db.command(&amp;#39;createIndexes&amp;#39;, coll_name, indexes=indexes) def clone_indexes(source_uri, dest_uri): source_db = MongoClient(source_uri).</description>
    </item>
    <item>
      <title>A better Celery ping for Docker healthcheck</title>
      <link>https://blog.sneawo.com/blog/2019/12/13/a-better-celery-ping-for-docker-healthcheck/</link>
      <pubDate>Fri, 13 Dec 2019 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/12/13/a-better-celery-ping-for-docker-healthcheck/</guid>
      <description>In the previous post the command is celery inspect ping --app app.celeryapp -d worker@$$HOSTNAME, but it initialize the app on each ping and can be expensive.&#xA;The lightweight version is celery inspect ping -b &amp;quot;redis://redis:6379/0&amp;quot; -d worker@$$HOSTNAME.</description>
    </item>
    <item>
      <title>AsyncIO REST example with aiohttp, motor and umongo</title>
      <link>https://blog.sneawo.com/blog/2019/08/15/asyncio-rest-example-with-aiohttp-motor-and-umongo/</link>
      <pubDate>Thu, 15 Aug 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/08/15/asyncio-rest-example-with-aiohttp-motor-and-umongo/</guid>
      <description>&lt;p&gt;Not so long I started to use aiohttp to create small services, they are 2-5x times faster.&lt;br&gt;&#xA;Here is my example of such an application with CRUD operations for items stored in MongoDB: &lt;a href=&#34;https://github.com/sneawo/asyncio-rest-example&#34;&gt;https://github.com/sneawo/asyncio-rest-example&lt;/a&gt;. It&amp;rsquo;s not production-ready, but there is an example of how to run it with docker-compose.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mock aiohttp request in unittests</title>
      <link>https://blog.sneawo.com/blog/2019/05/22/mock-aiohttp-request-in-unittests/</link>
      <pubDate>Wed, 22 May 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/05/22/mock-aiohttp-request-in-unittests/</guid>
      <description>Here is an example for the python 3.7.3 and the next versions of libs&#xA;aiohttp==3.5.4 asynctest==0.12.3 from typing import Dict from aiohttp import ClientSession from aiohttp.web_exceptions import HTTPInternalServerError async def send_request() -&amp;gt; Dict: async with ClientSession() as session: async with session.get(&amp;#39;http://localhost&amp;#39;) as response: if response.status != 200: raise HTTPInternalServerError() return await response.json() from asynctest import patch, CoroutineMock from aiohttp import web from aiohttp.web_exceptions import HTTPInternalServerError from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop from .</description>
    </item>
    <item>
      <title>A script to wait for a service running in docker swarm</title>
      <link>https://blog.sneawo.com/blog/2019/04/30/a-script-to-wait-for-a-service-running-in-docker-swarm/</link>
      <pubDate>Tue, 30 Apr 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/04/30/a-script-to-wait-for-a-service-running-in-docker-swarm/</guid>
      <description>For docker stack deploy there is no option to wait while all services are in running state. With docker service ps it&amp;rsquo;s possible to find desired state and current state for one service for each node.&#xA;$ docker service ps redis ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 50qe8lfnxaxk redis.1 redis:3.0.6 manager1 Running Running 6 seconds ago ky2re9oz86r9 \_ redis.1 redis:3.0.5 manager1 Shutdown Shutdown 8 seconds ago 3s46te2nzl4i redis.</description>
    </item>
    <item>
      <title>Alfred workflow step with bash script in background</title>
      <link>https://blog.sneawo.com/blog/2019/04/21/alfred-workflow-step-with-bash-script-in-background/</link>
      <pubDate>Sun, 21 Apr 2019 08:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/04/21/alfred-workflow-step-with-bash-script-in-background/</guid>
      <description>I spent some time to find this answer, so I&amp;rsquo;ll share it also here.&#xA;&amp;lt;path&amp;gt;/script.sh &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp; Without the output redirections Alfred will wait for the background process to complete and the next steps will not happen.</description>
    </item>
    <item>
      <title>Nginx proxy with prefix</title>
      <link>https://blog.sneawo.com/blog/2019/03/29/nginx-proxy-with-prefix/</link>
      <pubDate>Fri, 29 Mar 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/03/29/nginx-proxy-with-prefix/</guid>
      <description>It can be done this way.&#xA;location /my_app { rewrite ^/also/?(.*)$ /$1 break; proxy_pass http://my_app_upstream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ... } Without rewrite it will pass /my_app to upstream, so prefix should be handled on my_app level.&#xA;location /my_app { proxy_pass http://my_app_upstream; And with / in upstream it will add an additional /, so urls in proxied service will look like //some-url&#xA;location /my_app { proxy_pass http://my_app_upstream/; </description>
    </item>
    <item>
      <title>How to connect to a service in docker swarm with docker</title>
      <link>https://blog.sneawo.com/blog/2019/03/15/how-to-connect-to-a-service-in-docker-swarm-with-docker/</link>
      <pubDate>Fri, 15 Mar 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/03/15/how-to-connect-to-a-service-in-docker-swarm-with-docker/</guid>
      <description>It&amp;rsquo;s a rare case, suppose there is a myapp swarm cluster with myapp_mongo database without published port and there is a need to run a command from some docker image with connection to this database.&#xA;By default docker stack deploy creates a non-attachable network, so docker run --network myapp_default will output Error response from daemon: Could not attach to network myapp_default: rpc error: code = PermissionDenied desc = network myapp_default not manually attachable.</description>
    </item>
    <item>
      <title>Get blinker signal&#39;s receivers names</title>
      <link>https://blog.sneawo.com/blog/2019/03/07/get-blinker-signals-receivers-names/</link>
      <pubDate>Thu, 07 Mar 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/03/07/get-blinker-signals-receivers-names/</guid>
      <description>from unittest import TestCase from app.main import init_app from app.signals import my_signal class SignalTests(TestCase): def setUp(self): init_app() def test_signal_is_connected_to_my_receiver(self) receivers = [r().__name__ for r in signal.receivers.values()] self.assertIn(&amp;#39;my_receiver&amp;#39;, receivers) </description>
    </item>
    <item>
      <title>MongoDB dump and restore with docker</title>
      <link>https://blog.sneawo.com/blog/2019/02/14/mongodb-dump-and-restore-with-docker/</link>
      <pubDate>Thu, 14 Feb 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/02/14/mongodb-dump-and-restore-with-docker/</guid>
      <description>Here are two commands to take a partial dump of the collection from production database and put it in dev mongo instance running through docker-compose.&#xA;docker run -v `pwd`/:/dump mongo mongodump --gzip --archive=/dump/my_collection.agz --host &amp;lt;connection url&amp;gt; --ssl --username &amp;lt;username&amp;gt; --password &amp;lt;password&amp;gt; --authenticationDatabase admin --db &amp;lt;prod_db&amp;gt; --collection my_collection --query &amp;#39;{date: {$gte: ISODate(&amp;#34;2019-02-01T00:00:00.000+0000&amp;#34;)}}&amp;#39; docker-compose run -v `pwd`/my_collection.agz:/my_collection.agz mongo mongorestore --gzip --archive=/my_collection.agz --host mongo --nsFrom &amp;lt;prod_db&amp;gt;.my_collection --nsTo &amp;lt;dev_db&amp;gt;.my_collection </description>
    </item>
    <item>
      <title>Easy charts in python app with plotly</title>
      <link>https://blog.sneawo.com/blog/2019/01/24/easy-charts-in-python-app-with-plotly/</link>
      <pubDate>Thu, 24 Jan 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/01/24/easy-charts-in-python-app-with-plotly/</guid>
      <description>An example how to add a chart to Flask app with plotly library:&#xA;def get_chart_data(): return mongo_db[&amp;#39;item&amp;#39;].aggregate([ {&amp;#39;$sort&amp;#39;: {&amp;#39;date&amp;#39;: 1}}, {&amp;#39;$group&amp;#39;: { &amp;#39;_id&amp;#39;: {&amp;#39;year&amp;#39;: {&amp;#39;$year&amp;#39;: &amp;#39;$date&amp;#39;}, &amp;#39;month&amp;#39;: {&amp;#39;$month&amp;#39;: &amp;#39;$date&amp;#39;}}, &amp;#39;num&amp;#39;: {&amp;#39;$sum&amp;#39;: 1} }}, {&amp;#39;$project&amp;#39;: { &amp;#39;date&amp;#39;: {&amp;#39;$dateFromParts&amp;#39; : {&amp;#39;year&amp;#39;: &amp;#39;$_id.year&amp;#39;, &amp;#39;month&amp;#39;: &amp;#39;$_id.month&amp;#39;}}, &amp;#39;num&amp;#39;: &amp;#39;$num&amp;#39; }}, {&amp;#39;$sort&amp;#39;: {&amp;#39;date&amp;#39;: 1}} ]) def get_chart(): data = list(get_chart_data()) layout = plotly.graph_objs.Layout(title=&amp;#39;Items by month&amp;#39;) scatter_data = [ plotly.graph_objs.Scatter( x=[d[&amp;#39;date&amp;#39;] for d in data], y=[d[&amp;#39;num&amp;#39;] for d in data] ) ] fig = plotly.</description>
    </item>
    <item>
      <title>Mongoengine as_pymongo performance</title>
      <link>https://blog.sneawo.com/blog/2019/01/18/mongoengine-as_pymongo-performance/</link>
      <pubDate>Fri, 18 Jan 2019 10:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/01/18/mongoengine-as_pymongo-performance/</guid>
      <description>When you need to get only several fields from the list of complex objects, it works much faster with as_pymongo function.&#xA;In my situation I have a 16x increase:&#xA;%timeit list(SomeObject.objects.scalar(&amp;#39;id&amp;#39;)[0:500]) # 129 ms ± 11 ms per loop %timeit list(o[&amp;#39;_id&amp;#39;] for o in SomeObject.objects.scalar(&amp;#39;id&amp;#39;)[0:500].as_pymongo()) # 7.98 ms ± 849 µs per loop </description>
    </item>
    <item>
      <title>Celery Execution Pools</title>
      <link>https://blog.sneawo.com/blog/2019/01/11/celery-execution-pools/</link>
      <pubDate>Fri, 11 Jan 2019 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/01/11/celery-execution-pools/</guid>
      <description>A good explanation is in this post Celery Execution Pools: What is it all about?.</description>
    </item>
    <item>
      <title>Blog Results 2018</title>
      <link>https://blog.sneawo.com/blog/2019/01/03/blog-results-2018/</link>
      <pubDate>Thu, 03 Jan 2019 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2019/01/03/blog-results-2018/</guid>
      <description>&lt;p&gt;The goal was the same as in &lt;a href=&#34;https://blog.sneawo.com/blog/2018/01/02/blog-results-2017/&#34;&gt;2017&lt;/a&gt; to write 52 posts, one per week.&#xA;It&amp;rsquo;s not achived, the are 32, less than 45 in 2017.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to find the document with maximum size in MongoDB collection</title>
      <link>https://blog.sneawo.com/blog/2018/12/28/how-to-find-the-document-with-maximum-size-in-mongodb-collection/</link>
      <pubDate>Fri, 28 Dec 2018 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/12/28/how-to-find-the-document-with-maximum-size-in-mongodb-collection/</guid>
      <description>The command to get document size is Object.bsonsize. The next query is to find the document in a small collection, cause it can be slow:&#xA;db.getCollection(&amp;#39;my_collection&amp;#39;).find({}).map(doc =&amp;gt; { return {_id: doc._id, size: Object.bsonsize(doc)}; }).reduce((a, b) =&amp;gt; a.size &amp;gt; b.size ? a : b) To do this faster with mongo mapReduce:&#xA;db.getCollection(&amp;#39;my_collection&amp;#39;).mapReduce( function() { emit(&amp;#39;size&amp;#39;, {_id: this._id, size: Object.bsonsize(this)}); }, function(key, values) { return values.reduce((a, b) =&amp;gt; a.size &amp;gt; b.size ? a : b); }, {out: {inline: 1}} ) </description>
    </item>
    <item>
      <title>How to find number of MongoDB connections</title>
      <link>https://blog.sneawo.com/blog/2018/12/18/how-to-find-number-of-mongodb-connections/</link>
      <pubDate>Tue, 18 Dec 2018 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/12/18/how-to-find-number-of-mongodb-connections/</guid>
      <description>From the MongoDB side the current connections can be found with db.currentOp() command. Then they can be grouped by client ip, counted and sorted.&#xA;var ips = db.currentOp(true).inprog.filter( d =&amp;gt; d.client ).map( d =&amp;gt; d.client.split(&amp;#39;:&amp;#39;)[0] ).reduce( (ips, ip) =&amp;gt; { if(!ips[ip]) { ips[ip] = 0; } ips[ip]++; return ips; }, {} ); Object.keys(ips).map( key =&amp;gt; { return {&amp;#34;ip&amp;#34;: key, &amp;#34;num&amp;#34;: ips[key]}; } ).sort( (a, b) =&amp;gt; b.num - a.num ); The result will be like this:</description>
    </item>
    <item>
      <title>Maximum number of client connections in Flask-SocketIO with Eventlet</title>
      <link>https://blog.sneawo.com/blog/2018/12/11/maximum-number-of-client-connections-in-flask-socketio-with-eventlet/</link>
      <pubDate>Tue, 11 Dec 2018 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/12/11/maximum-number-of-client-connections-in-flask-socketio-with-eventlet/</guid>
      <description>It&amp;rsquo;s not mentioned in the docs for Flask-SocketIO that Eventlet has an option max_size which by default limits the maximum number of client connections opened at any time to 1024. There is no way to pass it through flask run command, so the application should be run with socketio.run, for example:&#xA;... if __name__ == &amp;#39;__main__&amp;#39;: socketio.run(app, host=&amp;#39;0.0.0.0&amp;#39;, port=&amp;#39;8080&amp;#39;, max_size=int(os.environ.get(&amp;#39;EVENTLET_MAX_SIZE&amp;#39;, 1024))) </description>
    </item>
    <item>
      <title>How to split Celery tasks file</title>
      <link>https://blog.sneawo.com/blog/2018/12/05/how-to-split-celery-tasks-file/</link>
      <pubDate>Wed, 05 Dec 2018 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/12/05/how-to-split-celery-tasks-file/</guid>
      <description>Suppose there is a large tasks.py file, like this:&#xA;@celery.task() def task1(): ... @celery.task() def task2(): ... task1.delay() ... ... A good idea is to split it on the smaller files, but Celery auto_discover by default search tasks in package.tasks module, so one way to do this is to create a package tasks and import tasks from other files in __init__.py.&#xA;__init__.py&#xA;from .task1 import task1 from .task2 import task2 __all__ = [&amp;#39;task1&amp;#39;, &amp;#39;task2&amp;#39;] task1.</description>
    </item>
    <item>
      <title>CSRF exempt for Flask-RESTPlus API</title>
      <link>https://blog.sneawo.com/blog/2018/11/14/csrf-exempt-for-flask-restplus-api/</link>
      <pubDate>Wed, 14 Nov 2018 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/11/14/csrf-exempt-for-flask-restplus-api/</guid>
      <description>The @csrf.exempt method does not work with Resource methods or decorators, it should be done on Api level. Here is an example how to exclude resources from CSRF protection based on class:&#xA;def csrf_exempt_my_resource(view): if issubclass(view.view_class, MyResource): return csrf.exempt(view) return view api_blueprint = Blueprint(&amp;#39;api&amp;#39;, __name__) api = Api(api_blueprint, title=&amp;#39;My API&amp;#39;, decorators=[csrf_exempt_my_resource]) Or for all resources:&#xA;api_blueprint = Blueprint(&amp;#39;api&amp;#39;, __name__) api = Api(api_blueprint, title=&amp;#39;My Private API&amp;#39;, decorators=[csrf.exempt]) </description>
    </item>
    <item>
      <title>Function as model column in Flask Admin</title>
      <link>https://blog.sneawo.com/blog/2018/10/18/function-as-model-column-in-flask-admin/</link>
      <pubDate>Thu, 18 Oct 2018 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/10/18/function-as-model-column-in-flask-admin/</guid>
      <description>I like the idea about separation of business logic from models and views into services. There are more details in these slides from the EuroPython talk.&#xA;Usually in Flask-Admin for a new column a new method with @property decorator is added and the model becomes fat. Also it&amp;rsquo;s not good to put something with queries in property. Another way is to put this function to the services and use column formatter in Flask-Admin.</description>
    </item>
    <item>
      <title>Docker healthcheck for Flask app with Celery</title>
      <link>https://blog.sneawo.com/blog/2018/09/25/docker-healthcheck-for-flask-app-with-celery/</link>
      <pubDate>Tue, 25 Sep 2018 11:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/09/25/docker-healthcheck-for-flask-app-with-celery/</guid>
      <description>With docker-compose it can be done the next way&#xA;flask_app: ... healthcheck: test: wget --spider --quiet http://localhost:8080/-/health celery_worker: ... command: celery worker --app app.celeryapp -n worker@%h --loglevel INFO healthcheck: test: celery inspect ping --app app.celeryapp -d worker@$$HOSTNAME Where /-/health is just a simple route&#xA;@app.route(&amp;#34;/-/health&amp;#34;) def health(): return &amp;#39;ok&amp;#39; Update:&#xA;A better Celery ping for Docker healthcheck</description>
    </item>
    <item>
      <title>How to update docker service using a version from docker-compose</title>
      <link>https://blog.sneawo.com/blog/2018/09/18/how-to-update-docker-service-using-a-version-from-docker-compose/</link>
      <pubDate>Tue, 18 Sep 2018 10:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/09/18/how-to-update-docker-service-using-a-version-from-docker-compose/</guid>
      <description>Here is a small script which compares the version of the running service and the version in the docker-compose file, if they are different it runs an update.&#xA;REDIS_VERSION=$(docker service ls | grep &amp;#34;redis&amp;#34; | awk &amp;#39;{print $5}&amp;#39;) REDIS_NEW_VERSION=$(grep -Po &amp;#34;image:\s*\Kredis:.*&amp;#34; docker-compose.yml) if [ &amp;#34;$REDIS_VERSION&amp;#34; != &amp;#34;$REDIS_NEW_VERSION&amp;#34; ]; then echo &amp;#34;update $REDIS_VERSION -&amp;gt; $REDIS_NEW_VERSION&amp;#34; docker service update --image $REDIS_NEW_VERSION app_redis fi </description>
    </item>
    <item>
      <title>Gitlab CI configuration using Docker socket binding</title>
      <link>https://blog.sneawo.com/blog/2018/09/11/gitlab-ci-configuration-using-docker-socket-binding/</link>
      <pubDate>Tue, 11 Sep 2018 10:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/09/11/gitlab-ci-configuration-using-docker-socket-binding/</guid>
      <description>&lt;p&gt;To avoid rebuild of images on each run there is a possibility to use Docker socket binding.&#xA;It&amp;rsquo;s covered in the &lt;a href=&#34;https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-socket-binding&#34;&gt;documentation&lt;/a&gt;,&#xA;here is a more detailed example.&lt;/p&gt;</description>
    </item>
    <item>
      <title>EuroPython 2018</title>
      <link>https://blog.sneawo.com/blog/2018/08/08/europython-2018/</link>
      <pubDate>Wed, 08 Aug 2018 10:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/08/08/europython-2018/</guid>
      <description>This year I finally visited EuroPython, thanks to my company.&#xA;Here is a list of some interesting talks with the links to youtube:&#xA;Die Threads – video Reliability in distributed systems – video Trio: a pythonic way to do async programming – video What&amp;rsquo;s new in Python 3.7 – video AsyncIO in production – video When to use machine learning: tips, tricks and warnings – video Django structure for scale and longevity – video Debugging your code with data visualization – video Getting started with mypy and type checking – video Citizen science with Python – video Good features beat algorithms – video Domain-driven design patterns in Python – video </description>
    </item>
    <item>
      <title>Env variables for Vue.js in Nginx container</title>
      <link>https://blog.sneawo.com/blog/2018/07/27/env-variables-for-vue.js-in-nginx-container/</link>
      <pubDate>Fri, 27 Jul 2018 13:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/07/27/env-variables-for-vue.js-in-nginx-container/</guid>
      <description>The default approach for Vue.js is to use .env files during build stage. But I like more this one with envsubst. There is no need to rebuild image for each environment or when the configuration is changed.&#xA;Here is a small modification for entrypoint.sh, so it can replace all variables with VUE_APP_ prefix.&#xA;#!/bin/sh function join_by { local IFS=&amp;#34;$1&amp;#34;; shift; echo &amp;#34;$*&amp;#34;; } # Find vue env vars vars=$(env | grep VUE_APP_ | awk -F = &amp;#39;{print &amp;#34;$&amp;#34;$1}&amp;#39;) vars=$(join_by &amp;#39; &amp;#39; $vars) echo &amp;#34;Found variables $vars&amp;#34; for file in /dist/js/app.</description>
    </item>
    <item>
      <title>Auth0 authorization to a Python API with PyJWT</title>
      <link>https://blog.sneawo.com/blog/2018/07/17/auth0-authorization-to-a-python-api-with-pyjwt/</link>
      <pubDate>Tue, 17 Jul 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/07/17/auth0-authorization-to-a-python-api-with-pyjwt/</guid>
      <description>&lt;p&gt;There is an example in the Auth0 &lt;a href=&#34;https://auth0.com/docs/quickstart/backend/python/01-authorization&#34;&gt;quickstarts&lt;/a&gt;, but it uses &lt;a href=&#34;https://github.com/capless/python-jose-cryptodome&#34;&gt;python-jose-cryptodome&lt;/a&gt; and I already have &lt;a href=&#34;https://pyjwt.readthedocs.io/en/latest/&#34;&gt;PyJWT&lt;/a&gt; in the project.&lt;/p&gt;&#xA;&lt;p&gt;So here is a small modification of this example.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A script to transfer azure storage containers to another storage</title>
      <link>https://blog.sneawo.com/blog/2018/07/05/a-script-to-transfer-azure-storage-containers-to-another-storage/</link>
      <pubDate>Thu, 05 Jul 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/07/05/a-script-to-transfer-azure-storage-containers-to-another-storage/</guid>
      <description>Here is an example of a script to copy azure storage containers from one storage to another and keep public access level. It uses Azure CLI and AzCopy tools.&#xA;#!/bin/bash STORAGE_NAME_SOURCE=&amp;#34;&amp;lt;source_account_name&amp;gt;&amp;#34; STORAGE_KEY_SOURCE=&amp;#34;&amp;lt;source_account_key&amp;gt;&amp;#34; STORAGE_NAME_DEST=&amp;#34;&amp;lt;dest_account_name&amp;gt;&amp;#34; STORAGE_KEY_DEST=&amp;#34;&amp;lt;dest_account_key&amp;#34; CONNECTION_STRING_SOURCE=&amp;#34;DefaultEndpointsProtocol=https;AccountName=$STORAGE_NAME_SOURCE;AccountKey=$STORAGE_KEY_SOURCE&amp;#34; CONNECTION_STRING_DEST=&amp;#34;DefaultEndpointsProtocol=https;AccountName=$STORAGE_NAME_DEST;AccountKey=$STORAGE_KEY_DEST&amp;#34; containers=$(az storage container list --connection-string $CONNECTION_STRING_SOURCE --output tsv | awk &amp;#39;{print $2}&amp;#39;) for i in $containers; do docker run --rm incendonet/azcopy azcopy --source https://$STORAGE_NAME_SOURCE.blob.core.windows.net/$i --source-key $STORAGE_KEY_SOURCE --destination https://$STORAGE_NAME_DEST.blob.core.windows.net/$i --dest-key $STORAGE_KEY_DEST --recursive access_level=$(az storage container show-permission -n $i --connection-string $CONNECTION_STRING_SOURCE --output tsv) az storage container set-permission -n $i --connection-string $CONNECTION_STRING_DEST --public-access $access_level done </description>
    </item>
    <item>
      <title>Disable user loading for some routes for app using Flask-Security</title>
      <link>https://blog.sneawo.com/blog/2018/06/26/disable-user-loading-for-some-routes-for-app-using-flask-security/</link>
      <pubDate>Tue, 26 Jun 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/06/26/disable-user-loading-for-some-routes-for-app-using-flask-security/</guid>
      <description>&lt;p&gt;An application with &lt;a href=&#34;https://pythonhosted.org/Flask-Security/index.html&#34;&gt;Flask-Security&lt;/a&gt; makes a request to the database for the authenticated user for each route, but sometimes it&amp;rsquo;s not necessary. Here is a way how to disable it with a decorator and custom &lt;a href=&#34;https://pythonhosted.org/Flask-Security/api.html#datastores&#34;&gt;UserDatastore&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>MongoDB select fields after $lookup</title>
      <link>https://blog.sneawo.com/blog/2018/06/19/mongodb-select-fields-after-lookup/</link>
      <pubDate>Tue, 19 Jun 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/06/19/mongodb-select-fields-after-lookup/</guid>
      <description>When there is a $lookup stage to join a list of large documents, an error Total size of documents in ... matching ... exceeds maximum document size can arrive.&#xA;It&amp;rsquo;s possible to avoid this with $unwind stage right after $lookup. More explanations in the documentation. And then the documents can be regrouped with the required fields.&#xA;Order.objects.aggregate( { &amp;#39;$lookup&amp;#39;: { &amp;#39;from&amp;#39;: &amp;#39;item&amp;#39;, &amp;#39;localField&amp;#39;: &amp;#39;_id&amp;#39;, &amp;#39;foreignField&amp;#39;: &amp;#39;order_id&amp;#39;, &amp;#39;as&amp;#39;: &amp;#39;items&amp;#39; } }, { &amp;#34;$unwind&amp;#34;: &amp;#34;$items&amp;#34; }, { &amp;#34;$group&amp;#34;: { &amp;#34;_id&amp;#34;: &amp;#34;$_id&amp;#34;, &amp;#34;date&amp;#34;: {&amp;#34;$last&amp;#34;: &amp;#34;$date&amp;#34;}, &amp;#34;items&amp;#34;: { &amp;#34;$push&amp;#34;: { &amp;#34;name&amp;#34;: &amp;#34;$items.</description>
    </item>
    <item>
      <title>How to find a change for a field with MongoDB aggregation</title>
      <link>https://blog.sneawo.com/blog/2018/06/12/how-to-find-a-change-for-a-field-with-mongodb-aggregation/</link>
      <pubDate>Tue, 12 Jun 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/06/12/how-to-find-a-change-for-a-field-with-mongodb-aggregation/</guid>
      <description>&lt;p&gt;For example there is a collection &lt;code&gt;device_status&lt;/code&gt; which stores the different states for the devices.&#xA;The task is to find the devices which passed from off to on at least one time.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device1&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;on&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-07T17:05:29.340+0000&amp;#34;&lt;/span&gt;) }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device2&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;off&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-08T17:05:29.340+0000&amp;#34;&lt;/span&gt;) }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device3&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;on&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-09T17:05:29.340+0000&amp;#34;&lt;/span&gt;)}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device3&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;shutdown&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-09T18:05:29.340+0000&amp;#34;&lt;/span&gt;)}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device2&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;load&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-09T19:05:29.340+0000&amp;#34;&lt;/span&gt;) }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device2&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;on&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-10T17:05:29.340+0000&amp;#34;&lt;/span&gt;) }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device3&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;off&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-11T17:05:29.340+0000&amp;#34;&lt;/span&gt;) }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device1&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;idle&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-11T18:05:29.340+0000&amp;#34;&lt;/span&gt;) }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;device3&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;on&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;: ISODate(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#34;2018-06-12T17:05:29.340+0000&amp;#34;&lt;/span&gt;) }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first stage is to sort the data by device and date.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to decode a Flask session or a CSRF token</title>
      <link>https://blog.sneawo.com/blog/2018/06/07/how-to-decode-a-flask-session-or-a-csrf-token/</link>
      <pubDate>Thu, 07 Jun 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/06/07/how-to-decode-a-flask-session-or-a-csrf-token/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m using &lt;a href=&#34;https://gist.github.com/babldev/502364a3f7c9bafaa6db&#34;&gt;this example&lt;/a&gt;.&#xA;The only change I made is &lt;code&gt;return_timestamp=True&lt;/code&gt; parameter to find when the session was generated.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Remote model in Flask-Admin</title>
      <link>https://blog.sneawo.com/blog/2018/05/30/remote-model-in-flask-admin/</link>
      <pubDate>Wed, 30 May 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/05/30/remote-model-in-flask-admin/</guid>
      <description>&lt;p&gt;The task is to show a model from another application in Flask-Admin.&#xA;A way to do it is to overwrite &lt;code&gt;BaseModelView&lt;/code&gt; and get the data through HTTP request.&#xA;Here is a simple example for a sortable list with a pagination.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bullet Journaling vs Todoist</title>
      <link>https://blog.sneawo.com/blog/2018/04/30/bullet-journaling-vs-todoist/</link>
      <pubDate>Mon, 30 Apr 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/04/30/bullet-journaling-vs-todoist/</guid>
      <description>It&amp;rsquo;s about a year when I moved to Todoist from Wunderlist. And that was right, there are no new posts in the Wunderlist blog or in the Microsoft To-Do blog. On other side Todoist is updated regularly, my karma is growing and it works well. But there are some things, as for Wunderlist, that i&amp;rsquo;m missing:&#xA;the week/month plan overview of previous week/month tracking for the repeating tasks So two month ago I decided to try Bullet Journal system and it works well for me.</description>
    </item>
    <item>
      <title>Celery flower for several applications</title>
      <link>https://blog.sneawo.com/blog/2018/04/17/celery-flower-for-several-applications/</link>
      <pubDate>Tue, 17 Apr 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/04/17/celery-flower-for-several-applications/</guid>
      <description>If there is a need to monitor several applications, there are two ways:&#xA;run celery flower instance for each application celery flower --app app1.celeryapp --port=5555 celery flower --app app2.celeryapp --port=5556 run celery flower with broker option, there will be less options to control tasks celery flower --broker=redis://redis/0 </description>
    </item>
    <item>
      <title>Celery checklist</title>
      <link>https://blog.sneawo.com/blog/2018/04/13/celery-checklist/</link>
      <pubDate>Fri, 13 Apr 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/04/13/celery-checklist/</guid>
      <description>There is a good checklist to build great celery async tasks.&#xA;I want only to add how to autoreload celery worker in development mode. Before there was an --autoreload option, but now it&amp;rsquo;s removed. For this task I use watchdog.&#xA;pip install watchdog watchmedo auto-restart --recursive -d app -p &amp;#39;*.py&amp;#39; -i &amp;#39;*.pyc&amp;#39; -- celery worker --app app.celeryapp --queues my_query -n my_queue@%h --loglevel INFO </description>
    </item>
    <item>
      <title>Microsoft Graph Api UnknownError in batch request</title>
      <link>https://blog.sneawo.com/blog/2018/03/30/microsoft-graph-api-unknownerror-in-batch-request/</link>
      <pubDate>Fri, 30 Mar 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/03/30/microsoft-graph-api-unknownerror-in-batch-request/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s possible to optimize the usage of Microsoft Graph Api by &lt;a href=&#34;https://developer.microsoft.com/en-us/graph/docs/concepts/json_batching&#34;&gt;batching requests&lt;/a&gt;.&#xA;There is a limitation for 20 requests in one batch request.&lt;/p&gt;&#xA;&lt;p&gt;Here is a simplified examle:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to log user ip in Docker Swarm</title>
      <link>https://blog.sneawo.com/blog/2018/03/20/how-to-log-user-ip-in-docker-swarm/</link>
      <pubDate>Tue, 20 Mar 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/03/20/how-to-log-user-ip-in-docker-swarm/</guid>
      <description>&lt;p&gt;There is a &lt;a href=&#34;https://github.com/moby/moby/issues/25526&#34;&gt;long standing issue&lt;/a&gt; for this task.&#xA;The logs looks like:&#xA;&lt;strong&gt;10.255.0.2&lt;/strong&gt; - - [15/Mar/2018:15:32:15 +0000] &amp;ldquo;GET / HTTP/2.0&amp;rdquo; 200&lt;/p&gt;&#xA;&lt;p&gt;One of the solutions, from the issue&amp;rsquo;s comments, is to run a service in the host mode, the swarm load balancing for this service will not work. But if there is a load balancer behind the swarm cluster, it seems not a big problem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Google Adsense results</title>
      <link>https://blog.sneawo.com/blog/2018/03/06/google-adsense-results/</link>
      <pubDate>Tue, 06 Mar 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/03/06/google-adsense-results/</guid>
      <description>I added Adsense at the end of January. In February I got 1.6K users and €2.46 to my balance, a little more than expected.</description>
    </item>
    <item>
      <title>Export and import for MongoEngine model in Flask-Admin</title>
      <link>https://blog.sneawo.com/blog/2018/02/16/export-and-import-for-mongoengine-model-in-flask-admin/</link>
      <pubDate>Fri, 16 Feb 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/02/16/export-and-import-for-mongoengine-model-in-flask-admin/</guid>
      <description>&lt;p&gt;Another tip for Flask-Admin. The task&amp;rsquo;s requirements are:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;possibility to choose some model&amp;rsquo;s objects and download them in JSON&lt;/li&gt;&#xA;&lt;li&gt;possibility to upload them back&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;There is a ModelView property &lt;a href=&#34;http://flask-admin.readthedocs.io/en/latest/api/mod_model/#flask_admin.model.BaseModelView.can_export&#34;&gt;can_export&lt;/a&gt;, it adds an action to export in CSV or another format supported by &lt;a href=&#34;https://github.com/kennethreitz/tablib/&#34;&gt;tablib&lt;/a&gt;, but it does not allow to select records and there is no import. So for my task it&amp;rsquo;s not a solution.&lt;/p&gt;&#xA;&lt;p&gt;The export is easy to do with an &lt;a href=&#34;http://flask-admin.readthedocs.io/en/latest/advanced/#customizing-batch-actions&#34;&gt;action decorathor&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to disable field in MongoEngine subdocument in Flask-Admin</title>
      <link>https://blog.sneawo.com/blog/2018/02/08/how-to-disable-field-in-mongoengine-subdocument-in-flask-admin/</link>
      <pubDate>Thu, 08 Feb 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/02/08/how-to-disable-field-in-mongoengine-subdocument-in-flask-admin/</guid>
      <description>&lt;p&gt;In the documentation there is an information about &lt;a href=&#34;http://flask-admin.readthedocs.io/en/latest/api/mod_model/#flask_admin.model.BaseModelView.form_widget_args&#34;&gt;form_widget_args&lt;/a&gt; and &lt;a href=&#34;http://flask-admin.readthedocs.io/en/latest/api/mod_contrib_mongoengine/#flask_admin.contrib.mongoengine.ModelView.form_subdocuments&#34;&gt;form_subdocuments&lt;/a&gt; attributes of &lt;code&gt;ModelView&lt;/code&gt; class. To do this task they can be used together:&lt;/p&gt;</description>
    </item>
    <item>
      <title>An update for the productivity apps list</title>
      <link>https://blog.sneawo.com/blog/2018/02/06/an-update-for-the-productivity-apps-list/</link>
      <pubDate>Tue, 06 Feb 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/02/06/an-update-for-the-productivity-apps-list/</guid>
      <description>Several productivity apps I added to this list in the last month.&#xA;HazeOver - automatically highlights the front window by fading out all the background windows. Hazel - watches whatever folders you tell it to, automatically organizing your files according to the rules you create. Bartender - lets you organize your menu bar apps. iStatMenus - adds system monitor to your menu bar. For iTerm2 I failed to setup Automatic Profile Switching, but I found a good solution here - Change terminal color when SSH from OS-X.</description>
    </item>
    <item>
      <title>Notebook stand as a solution for the back pain</title>
      <link>https://blog.sneawo.com/blog/2018/02/01/notebook-stand-as-a-solution-for-the-back-pain/</link>
      <pubDate>Thu, 01 Feb 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/02/01/notebook-stand-as-a-solution-for-the-back-pain/</guid>
      <description>&lt;p&gt;The health is one of the most important part of our life and the programming work affects it a lot.&#xA;For the years I had a pain in my back, sometimes less, sometimes more, at the beginning it was a low back pain, now it&amp;rsquo;s upper back.&lt;/p&gt;&#xA;&lt;p&gt;The reasons in my case are:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Google Adsense and blog on subdomain</title>
      <link>https://blog.sneawo.com/blog/2018/01/26/google-adsense-and-blog-on-subdomain/</link>
      <pubDate>Fri, 26 Jan 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/01/26/google-adsense-and-blog-on-subdomain/</guid>
      <description>This month I decided to try Google Adsense, just as an experiment. I expect no more 1-2$ in the next month. The process of adding adsense is easy, but the problem is that it requires a primary domain and on the primary domain sneawo.com I had a redirect to blog.sneawo.com. So the first attempt failed after 2 days of waiting. For a second attempt I put an html with a short text on the primary domain.</description>
    </item>
    <item>
      <title>A bootstrap for a microservice based on Flask with MongoDB</title>
      <link>https://blog.sneawo.com/blog/2018/01/18/a-bootstrap-for-a-microservice-based-on-flask-with-mongodb/</link>
      <pubDate>Thu, 18 Jan 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/01/18/a-bootstrap-for-a-microservice-based-on-flask-with-mongodb/</guid>
      <description>Starting a new project is a common task in microservices architecture. To do this it&amp;rsquo;s better to have a some template. I put my version to the flask-mongoengine-bootstrap repository. The key point are:&#xA;very basic, only flask, flask-mongoengine and structlog in requirements configuration through environment variables configured logging in JSON format marking log records with request_id possibility to run development version make dev and tests make test through docker a template for Makefile examples of model, api route and tests If you&amp;rsquo;ll use it, do not forget to change SECRET_KEY.</description>
    </item>
    <item>
      <title>Subscription to the blog updates</title>
      <link>https://blog.sneawo.com/blog/2018/01/12/subscription-to-the-blog-updates/</link>
      <pubDate>Fri, 12 Jan 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/01/12/subscription-to-the-blog-updates/</guid>
      <description>This year I decided to spend some time on the blog marketing. I don&amp;rsquo;t know how to do it, but as a first step I&amp;rsquo;ve added a subscription to the monthly digest of updates. You can see it on the right.&#xA;I used MailChimp because:&#xA;it&amp;rsquo;s free up to 2,000 subscribers and 12,000 emails per month there is a subscription form builder there is an automatic campaign to send an email by schedule with the posts from RSS The only problem was to choose an physical address, it&amp;rsquo;s a requirement for FTC&amp;rsquo;s CAN-SPAM Act.</description>
    </item>
    <item>
      <title>Blog Results 2017</title>
      <link>https://blog.sneawo.com/blog/2018/01/02/blog-results-2017/</link>
      <pubDate>Tue, 02 Jan 2018 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2018/01/02/blog-results-2017/</guid>
      <description>&lt;p&gt;One of the goals for 2017 year was to reanimate the blog and write 52 posts, one per week.&lt;/p&gt;</description>
    </item>
    <item>
      <title>No-Cache headers in Flask</title>
      <link>https://blog.sneawo.com/blog/2017/12/20/no-cache-headers-in-flask/</link>
      <pubDate>Wed, 20 Dec 2017 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/12/20/no-cache-headers-in-flask/</guid>
      <description>The second line of &amp;ldquo;The Zen of Python&amp;rdquo; (try import this) says &amp;ldquo;Explicit is better than implicit.&amp;rdquo;. By default Flask response does not return any cache header and you can suppose that browsers will not cache, but some of them can decide for you. So it&amp;rsquo;s better to provide them, especially for API and it&amp;rsquo;s easy:&#xA;@app.after_request def set_response_headers(response): response.headers[&amp;#39;Cache-Control&amp;#39;] = &amp;#39;no-cache, no-store, must-revalidate&amp;#39; response.headers[&amp;#39;Pragma&amp;#39;] = &amp;#39;no-cache&amp;#39; response.headers[&amp;#39;Expires&amp;#39;] = &amp;#39;0&amp;#39; return response </description>
    </item>
    <item>
      <title>Flask-Admin authentication through oAuth</title>
      <link>https://blog.sneawo.com/blog/2017/12/13/flask-admin-authentication-through-oauth/</link>
      <pubDate>Wed, 13 Dec 2017 11:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/12/13/flask-admin-authentication-through-oauth/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://flask-admin.readthedocs.io/en/latest/introduction/#authorization-permissions&#34;&gt;Flask-Admin&lt;/a&gt; provides the examples of authentication with Flask-Login and Flask-Security.&#xA;Here is an example how to authenticate using Microsoft oAuth.&lt;/p&gt;&#xA;&lt;p&gt;Create an application in &lt;a href=&#34;https://apps.dev.microsoft.com/&#34;&gt;Microsoft Application Registration Portal&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Problems with Gmail in default Postfix configuration</title>
      <link>https://blog.sneawo.com/blog/2017/12/06/problems-with-gmail-in-default-postfix-configuration/</link>
      <pubDate>Wed, 06 Dec 2017 12:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/12/06/problems-with-gmail-in-default-postfix-configuration/</guid>
      <description>&lt;p&gt;Recently I moved some of the sites to a new hosting. The previous server had Ubuntu 12.04 with Exim4 and I forgot how to configure them.&lt;/p&gt;&#xA;&lt;p&gt;On a new server I installed Postfix with Ansible:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#1e90ff;font-weight:bold&#34;&gt;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Set up Postfix to relay mail&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#1e90ff;font-weight:bold&#34;&gt;debconf&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;name=postfix&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;               &lt;/span&gt;question=&amp;#39;{{ item.question }}&amp;#39;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;               &lt;/span&gt;value=&amp;#39;{{ item.value }}&amp;#39;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;               &lt;/span&gt;vtype=&amp;#39;{{ item.vtype }}&amp;#39;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#1e90ff;font-weight:bold&#34;&gt;with_items&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- {&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1e90ff;font-weight:bold&#34;&gt;question: &amp;#39;postfix/mailname&amp;#39;, value&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a50&#34;&gt;&amp;#39;{{ ansible_fqdn }}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#1e90ff;font-weight:bold&#34;&gt;, vtype&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a50&#34;&gt;&amp;#39;string&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- {&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#1e90ff;font-weight:bold&#34;&gt;question: &amp;#39;postfix/main_mailer_type&amp;#39;, value: &amp;#39;Internet Site&amp;#39;, vtype&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a50&#34;&gt;&amp;#39;string&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After that I started to receive the next delivery reports from Gmail:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Flask-BabelEx translations in a Celery task</title>
      <link>https://blog.sneawo.com/blog/2017/11/29/flask-babelex-translations-in-a-celery-task/</link>
      <pubDate>Wed, 29 Nov 2017 12:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/11/29/flask-babelex-translations-in-a-celery-task/</guid>
      <description>&lt;p&gt;The problem with translation in a Celery task is that there is no request context and &lt;code&gt;flask_babelex.get_locale&lt;/code&gt; returns &lt;code&gt;None&lt;/code&gt;. For Flask-Babel there is a &lt;a href=&#34;https://github.com/python-babel/flask-babel/blob/v0.11.2/flask_babel/__init__.py#L310&#34;&gt;force_locale&lt;/a&gt; context manager which solves this problem. But Flask-Security uses &lt;a href=&#34;https://github.com/mrjoes/flask-babelex&#34;&gt;Flask-BabelEx&lt;/a&gt; and it does not work well with Flask-Babel.&lt;/p&gt;&#xA;&lt;p&gt;Here is an example how to create a context manager which provides dummy request context.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Flask-RESTPlus similar resources for MongoEngine model</title>
      <link>https://blog.sneawo.com/blog/2017/11/21/flask-restplus-similar-resources-for-mongoengine-model/</link>
      <pubDate>Tue, 21 Nov 2017 12:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/11/21/flask-restplus-similar-resources-for-mongoengine-model/</guid>
      <description>&lt;p&gt;Suppose there are several similar MongoEngine models and there is a need to modify them through REST. Here is an example how to create a set of such similar resources.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Alfred Workflow to add an email from Mail.app to Todoist inbox</title>
      <link>https://blog.sneawo.com/blog/2017/11/16/alfred-workflow-to-add-an-email-from-mail.app-to-todoist-inbox/</link>
      <pubDate>Thu, 16 Nov 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/11/16/alfred-workflow-to-add-an-email-from-mail.app-to-todoist-inbox/</guid>
      <description>There is a way to add an email to Todoist by sending it to a special address, the only thing that annoing me, that it doesn&amp;rsquo;t keep a link to the message in Mail.app.&#xA;I created a simple Alfred workflow, which takes the selected messages in Mail.app, creates a Markdown links as [email subject](message://message_id) and send it to Todoist Inbox using its API.&#xA;You can find the details about installation and usage in sneawo/mailapp-to-todoist repository.</description>
    </item>
    <item>
      <title>Socket.IO in Docker Swarm</title>
      <link>https://blog.sneawo.com/blog/2017/11/07/socket.io-in-docker-swarm/</link>
      <pubDate>Tue, 07 Nov 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/11/07/socket.io-in-docker-swarm/</guid>
      <description>Socket.IO requires the sticky sessions, so when it&amp;rsquo;s runned in Docker Swarm environment, the Swarm load balancer can forward the request to any node where the service is launched and there will be the 400 errors. The solution is to limit the number of nodes for Socket.IO service to one or to use another load balancer like Traefik or HAProxy.</description>
    </item>
    <item>
      <title>Dump and restore commands for PostgreSQL in Docker</title>
      <link>https://blog.sneawo.com/blog/2017/11/03/dump-and-restore-commands-for-postgresql-in-docker/</link>
      <pubDate>Fri, 03 Nov 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/11/03/dump-and-restore-commands-for-postgresql-in-docker/</guid>
      <description>Sometimes during development it’s necessary to share the db dump with colleagues. In the previous article i provided the commands for MySQL, here is the same for PostgreSQL.&#xA;DATE = $(shell date +%Y-%m-%d) path ?= . help: ## show this help @echo &amp;#39;usage: make [target] ...&amp;#39; @echo &amp;#39;&amp;#39; @echo &amp;#39;targets:&amp;#39; @egrep &amp;#39;^(.+)\:\ .*##\ (.+)&amp;#39; ${MAKEFILE_LIST} | sed &amp;#39;s/:.*##/#/&amp;#39; | column -t -c 2 -s &amp;#39;#&amp;#39; dump: ## dump db, usage &amp;#39;make dump path=/path/to/dumps&amp;#39; docker-compose exec --user postgres db pg_dumpall --clean | gzip &amp;gt; $(path)/project-$(DATE).</description>
    </item>
    <item>
      <title>Django in Docker</title>
      <link>https://blog.sneawo.com/blog/2017/10/24/django-in-docker/</link>
      <pubDate>Tue, 24 Oct 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/10/24/django-in-docker/</guid>
      <description>&lt;p&gt;There are many instructions how to run &lt;a href=&#34;https://www.google.fr/search?q=django+in+docker&#34;&gt;Django in Docker&lt;/a&gt;. The base configuration of docker-compose usualy has&#xA;the next services: nginx, web (django), db (mysql, postgresql), cache (memcached, redis).&#xA;I&amp;rsquo;ll just add some notes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Azure Cosmos DB</title>
      <link>https://blog.sneawo.com/blog/2017/10/03/azure-cosmos-db/</link>
      <pubDate>Tue, 03 Oct 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/10/03/azure-cosmos-db/</guid>
      <description>If you look for a MongoDB-as-a-service and want to try Azure Cosmos DB, be careful, because not all mongo&amp;rsquo;s functions are supported. For example, there is a problem with aggregation and group by. I didn&amp;rsquo;t found the list about what else can be different.&#xA;Other solid solutions are MongoDB Atlas, it supports Azure from this summer, and mLab.</description>
    </item>
    <item>
      <title>StackOverflow changes from 2013 to 2017</title>
      <link>https://blog.sneawo.com/blog/2017/09/25/stackoverflow-changes-from-2013-to-2017/</link>
      <pubDate>Mon, 25 Sep 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/09/25/stackoverflow-changes-from-2013-to-2017/</guid>
      <description>&lt;p&gt;Here is an update for StackOverflow statistics for the users with a reputation more than 300. The last measure was made in &lt;a href=&#34;https://blog.sneawo.com/blog/2013/01/19/stackoverflow-charts/&#34;&gt;January 2013&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I almost stopped to answer from the beginning of 2014. At that time I had a reputation around 1600, now it&amp;rsquo;s 2630.&lt;/p&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;p&gt;The number of users growed more than 3 times, but the distribution by reputation is mostly the same.&lt;/p&gt;&#xA;&lt;!-- raw HTML omitted --&gt;</description>
    </item>
    <item>
      <title>EuroPython 2017</title>
      <link>https://blog.sneawo.com/blog/2017/09/12/europython-2017/</link>
      <pubDate>Tue, 12 Sep 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/09/12/europython-2017/</guid>
      <description>This year, as in previous, I missed the conference. This time I even bought the ticket, but had to return it. The refund process works well, but takes time. Fortunately, there are the live streams from all days, the only problem is to find a time to watch them.</description>
    </item>
    <item>
      <title>How to install pillow, psycopg, pylibmc packages in python:alpine image</title>
      <link>https://blog.sneawo.com/blog/2017/09/07/how-to-install-pillow-psycopg-pylibmc-packages-in-pythonalpine-image/</link>
      <pubDate>Thu, 07 Sep 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/09/07/how-to-install-pillow-psycopg-pylibmc-packages-in-pythonalpine-image/</guid>
      <description>Here is the examples how to install some packages in python:alpine image. Some dependencies should be installed permanently and some only for package build and removed after.&#xA;pillow RUN apk add --no-cache jpeg-dev zlib-dev psycopg RUN apk add --no-cache postgresql-dev pylibmc RUN apk add --no-cache libmemcached-dev zlib-dev Then to install:&#xA;RUN apk add --no-cache --virtual .build-deps build-base linux-headers \ &amp;amp;&amp;amp; pip3 install pip --upgrade \ &amp;amp;&amp;amp; pip3 install &amp;lt;packages list&amp;gt; \ &amp;amp;&amp;amp; apk del .</description>
    </item>
    <item>
      <title>Mailgun for emails in docker</title>
      <link>https://blog.sneawo.com/blog/2017/08/08/mailgun-for-emails-in-docker/</link>
      <pubDate>Tue, 08 Aug 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/08/08/mailgun-for-emails-in-docker/</guid>
      <description>&lt;p&gt;Usually, even a small web application should send some emails: errors, registration, restore password, invitations, etc.&lt;/p&gt;&#xA;&lt;p&gt;There are 3 solutions:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;use an existing account, like gmail: the main problem - you don&amp;rsquo;t know how many emails you can send before being marked as spam&lt;/li&gt;&#xA;&lt;li&gt;use own mail server: need to install, configure and support&lt;/li&gt;&#xA;&lt;li&gt;use email service, like &lt;a href=&#34;https://sendgrid.com&#34;&gt;sendgrid&lt;/a&gt;, &lt;a href=&#34;https://www.mailgun.com&#34;&gt;mailgun&lt;/a&gt;: easy to configure, provide statistics and logs, can use default http port.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;For some my small projects i choosed mailgun, it provides 10000 emails in month for free, for my needs it&amp;rsquo;s more than enough and after that it&amp;rsquo;s also not expensive. For django there is a email backend &lt;a href=&#34;https://pypi.python.org/pypi/django-mailgun&#34;&gt;django-mailgun&lt;/a&gt; and it takes two minutes to switch to it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Interesting articles 2</title>
      <link>https://blog.sneawo.com/blog/2017/08/01/interesting-articles-2/</link>
      <pubDate>Tue, 01 Aug 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/08/01/interesting-articles-2/</guid>
      <description>It&amp;rsquo;s good to know how things are done in the other companies.&#xA;The Stack That Helped Medium Scale To 2.6 Millennia Of Reading Time&#xA;How CircleCI Processes 4.5 Million Builds Per Month</description>
    </item>
    <item>
      <title>JSON logging in Python</title>
      <link>https://blog.sneawo.com/blog/2017/07/28/json-logging-in-python/</link>
      <pubDate>Fri, 28 Jul 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/07/28/json-logging-in-python/</guid>
      <description>&lt;p&gt;A lot of the log systems (&lt;a href=&#34;https://www.loggly.com&#34;&gt;loggly&lt;/a&gt;, &lt;a href=&#34;https://logentries.com&#34;&gt;logentries&lt;/a&gt;, &lt;a href=&#34;https://sematext.com&#34;&gt;sematext&lt;/a&gt;, kibana, etc.) can understand the JSON format. The benefits: it&amp;rsquo;s easier to search, filter and analize logs.&lt;/p&gt;&#xA;&lt;p&gt;Here is an example of configuration for Python with &lt;a href=&#34;http://structlog.readthedocs.io&#34;&gt;structlog library&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h3 id=&#34;install&#34;&gt;Install&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install structlog&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install python-json-logger&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>How to run Docker Swarm localy</title>
      <link>https://blog.sneawo.com/blog/2017/07/20/how-to-run-docker-swarm-localy/</link>
      <pubDate>Thu, 20 Jul 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/07/20/how-to-run-docker-swarm-localy/</guid>
      <description>&lt;p&gt;Suppose there is an application which uses &lt;code&gt;docker-compose&lt;/code&gt; to run&#xA;and you want to try it in swarm mode.&lt;/p&gt;&#xA;&lt;p&gt;First of all you need to initialize &lt;a href=&#34;https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/&#34;&gt;swarm nodes&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Interesting articles</title>
      <link>https://blog.sneawo.com/blog/2017/07/11/interesting-articles/</link>
      <pubDate>Tue, 11 Jul 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/07/11/interesting-articles/</guid>
      <description>Several interesting articles I found recently. Some of them I think from Dan Bader twitter.&#xA;Django vs Flask - a detailed comparison Django vs Flask.&#xA;In most cases I preferer Django.&#xA;It has better documentation There are better apps in core, with Flask you need to search for an app, compare alternatives and sometimes they are not updated for a long time You can choose which core apps to use I think it&amp;rsquo;s better developed and supported How the heck does async/await work in Python 3.</description>
    </item>
    <item>
      <title>Flask-RESTful migration to Flask-RESTPlus</title>
      <link>https://blog.sneawo.com/blog/2017/07/05/flask-restful-migration-to-flask-restplus/</link>
      <pubDate>Wed, 05 Jul 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/07/05/flask-restful-migration-to-flask-restplus/</guid>
      <description>&lt;p&gt;In a simple application with a several endpoints, it&amp;rsquo;s ok to use the default &lt;a href=&#34;http://flask.pocoo.org/docs/0.12/api/#flask.Flask.route&#34;&gt;Flask routes&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;@app.route&lt;/span&gt;(&lt;span style=&#34;color:#a50&#34;&gt;&amp;#39;/api/v1.0/users&amp;#39;&lt;/span&gt;, methods=[&lt;span style=&#34;color:#a50&#34;&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00a&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#0a0&#34;&gt;get_users&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00a&#34;&gt;return&lt;/span&gt; jsonify({&lt;span style=&#34;color:#a50&#34;&gt;&amp;#39;objects&amp;#39;&lt;/span&gt;: users})&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But when an application becomes bigger, it can be useful to use a some REST framework or split it on the smaller apps. The REST framework is used to:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;enforce best practices&lt;/li&gt;&#xA;&lt;li&gt;simplify: versioning, serialization, documentation, authenication&lt;/li&gt;&#xA;&lt;li&gt;provide browsable API&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>How to use Jupyter notebooks with Flask app</title>
      <link>https://blog.sneawo.com/blog/2017/06/27/how-to-use-jupyter-notebooks-with-flask-app/</link>
      <pubDate>Tue, 27 Jun 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/06/27/how-to-use-jupyter-notebooks-with-flask-app/</guid>
      <description>&lt;p&gt;The strong part of Python and other interpreted languages is an interactive shell.&#xA;But there is an even more powerful tool - &lt;a href=&#34;http://jupyter.org/about.html&#34;&gt;Jupyter notebook&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In a simple case it allows to:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;verify how some code works&lt;/li&gt;&#xA;&lt;li&gt;check hypothesis&lt;/li&gt;&#xA;&lt;li&gt;save these experiments and continue to work on them later&lt;/li&gt;&#xA;&lt;li&gt;share them with the colleagues&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Flask-Security 3.0.0 released</title>
      <link>https://blog.sneawo.com/blog/2017/06/20/flask-security-3.0.0-released/</link>
      <pubDate>Tue, 20 Jun 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/06/20/flask-security-3.0.0-released/</guid>
      <description>Finally it happened. The previous version 1.7.5 was released in December 2015. It&amp;rsquo;s not a big library but the useful one. There is a flask-security-fork, but it&amp;rsquo;s better to have a one official place for all issues and pull requests. Now it&amp;rsquo;s merged. Thanks to Jiri Kuncar for all the efforts.&#xA;The full list of changes is here.</description>
    </item>
    <item>
      <title>Mongoengine sanitized string field</title>
      <link>https://blog.sneawo.com/blog/2017/06/16/mongoengine-sanitized-string-field/</link>
      <pubDate>Fri, 16 Jun 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/06/16/mongoengine-sanitized-string-field/</guid>
      <description>&lt;p&gt;One of the rules to prevent XSS attack is to &lt;a href=&#34;https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.236_-_Sanitize_HTML_Markup_with_a_Library_Designed_for_the_Job&#34;&gt;sanitize HTML&lt;/a&gt;.&#xA;Here is an example how to do this with Mongoengine custom field and &lt;a href=&#34;https://pypi.python.org/pypi/bleach&#34;&gt;bleach&lt;/a&gt; library.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Makefile help target</title>
      <link>https://blog.sneawo.com/blog/2017/06/13/makefile-help-target/</link>
      <pubDate>Tue, 13 Jun 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/06/13/makefile-help-target/</guid>
      <description>In many projects to run complex commands or group of commands I use Makefile. To document it I add a help target.&#xA;Here is an exemple for dump and restore commands for PostgreSQL in docker-compose under alias db.&#xA;DATE = $(shell date +%d%m%Y) path ?= . help: ## show this help @echo &amp;#39;usage: make [target] ...&amp;#39; @echo &amp;#39;&amp;#39; @echo &amp;#39;targets:&amp;#39; @egrep &amp;#39;^(.+)\:\ .*##\ (.+)&amp;#39; ${MAKEFILE_LIST} | sed &amp;#39;s/:.*##/#/&amp;#39; | column -t -c 2 -s &amp;#39;#&amp;#39; dump: ## dump db, usage &amp;#39;make dump path=/path/to/dumps&amp;#39; docker-compose exec --user postgres db pg_dumpall --clean | gzip &amp;gt; $(path)/db_$(DATE).</description>
    </item>
    <item>
      <title>How to debug AngularJs 1.5 in browser console</title>
      <link>https://blog.sneawo.com/blog/2017/06/08/how-to-debug-angularjs-1.5-in-browser-console/</link>
      <pubDate>Thu, 08 Jun 2017 14:01:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/06/08/how-to-debug-angularjs-1.5-in-browser-console/</guid>
      <description>&lt;p&gt;Sometimes it&amp;rsquo;s useful to run service, controller function or view some scope directly in console.&#xA;Here are several examples how to get access to them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Nginx SSL configuration in Docker Swarm</title>
      <link>https://blog.sneawo.com/blog/2017/06/02/nginx-ssl-configuration-in-docker-swarm/</link>
      <pubDate>Fri, 02 Jun 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/06/02/nginx-ssl-configuration-in-docker-swarm/</guid>
      <description>&lt;p&gt;When you have several Nginx replicas in Docker Swarm and you need to share SSL certificate,&#xA;you can use &lt;a href=&#34;https://docs.docker.com/engine/swarm/secrets/&#34;&gt;secrets&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Here is a short extract:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Docker clean commands</title>
      <link>https://blog.sneawo.com/blog/2017/05/30/docker-clean-commands/</link>
      <pubDate>Tue, 30 May 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/05/30/docker-clean-commands/</guid>
      <description>When you start to use Docker, at some point there will be a question - where is all my space. Most of it is occupied by containers, images and dangling volumes.&#xA;An easy way to clean is to use Docker garbage collection by Spotify and docker volume rm commands. I have an alias for this.&#xA;alias docker-gc=&amp;#39;docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /etc:/etc -e GRACE_PERIOD_SECONDS=172800 spotify/docker-gc &amp;amp;&amp;amp; docker volume rm $(docker volume ls -qf dangling=true)&amp;#39; On mac sometimes it&amp;rsquo;s easier to remove all, for this you need to remove Docker.</description>
    </item>
    <item>
      <title>Nginx upstream problems in docker environment</title>
      <link>https://blog.sneawo.com/blog/2017/05/23/nginx-upstream-problems-in-docker-environment/</link>
      <pubDate>Tue, 23 May 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/05/23/nginx-upstream-problems-in-docker-environment/</guid>
      <description>&lt;p&gt;I have nginx as a proxy for a python application. To launch them I have a docker-compose.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to refresh access token for Microsoft Graph in Python</title>
      <link>https://blog.sneawo.com/blog/2017/05/18/how-to-refresh-access-token-for-microsoft-graph-in-python/</link>
      <pubDate>Thu, 18 May 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/05/18/how-to-refresh-access-token-for-microsoft-graph-in-python/</guid>
      <description>&lt;p&gt;The connection to &lt;a href=&#34;https://graph.microsoft.io/&#34;&gt;Microsoft Graph&lt;/a&gt; with &lt;a href=&#34;https://flask-oauthlib.readthedocs.io/en/latest/&#34;&gt;Flask-OAuthlib&lt;/a&gt; described well in this &lt;a href=&#34;https://developer.microsoft.com/en-us/graph/docs/concepts/python&#34;&gt;tutorial&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;One detail it&amp;rsquo;s missing - how to refresh the access token, because it expires in an hour.&#xA;In Flask-OAuthlib there is no method for this but it can be done easily with a &lt;code&gt;POST&lt;/code&gt; request.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AngularJs 1.5 controllers inheritance</title>
      <link>https://blog.sneawo.com/blog/2017/05/05/angularjs-1.5-controllers-inheritance/</link>
      <pubDate>Fri, 05 May 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/05/05/angularjs-1.5-controllers-inheritance/</guid>
      <description>&lt;p&gt;In the first place there is a good &lt;a href=&#34;https://github.com/johnpapa/angular-styleguide&#34;&gt;style guide for Angular&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;When you need to reuse the code of some controller and use &lt;a href=&#34;https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y031&#34;&gt;controllerAs syntax&lt;/a&gt;, you can use inheritance with the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call&#34;&gt;call() method&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>My current tools</title>
      <link>https://blog.sneawo.com/blog/2017/05/05/my-current-tools/</link>
      <pubDate>Fri, 05 May 2017 13:30:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/05/05/my-current-tools/</guid>
      <description>&lt;p&gt;Here is an update for the tools I&amp;rsquo;m using. &lt;a href=&#34;https://blog.sneawo.com/blog/2013/07/20/my-current-tools/&#34;&gt;The previous record&lt;/a&gt; was in 2013.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AppleScript to JavaScript</title>
      <link>https://blog.sneawo.com/blog/2017/04/28/applescript-to-javascript/</link>
      <pubDate>Fri, 28 Apr 2017 14:00:39 +0200</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/04/28/applescript-to-javascript/</guid>
      <description>A small example how to rewrite make call from AppleScript to JavaScript.&#xA;tell application &amp;#34;Microsoft Outlook&amp;#34; make new signature with properties {name: &amp;#34;Signature Name&amp;#34;, content: &amp;#34;Best regards, ...&amp;#34;} end tell Application(&amp;#34;Microsoft Outlook&amp;#34;).Signature({name: &amp;#34;Signature Name&amp;#34;, content: &amp;#39;Best regards, ...&amp;#39;}).make(); </description>
    </item>
    <item>
      <title>Microsoft killed Wunderlist</title>
      <link>https://blog.sneawo.com/blog/2017/04/25/microsoft-killed-wunderlist/</link>
      <pubDate>Tue, 25 Apr 2017 13:21:39 +0200</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/04/25/microsoft-killed-wunderlist/</guid>
      <description>Sadly, Microsoft is killing Wunderlist, more info in an official blog and on thenextweb.com. So it&amp;rsquo;s time to try something else, my requirements:&#xA;should work on any device possibility to share lists with my family sub projects, minimum two levels possibility to review next and previous weeks possibility to review all tasks developer API Some of these does not exists in Wunderlist, but covered by wunderweek.com, which I created at the end of 2016.</description>
    </item>
    <item>
      <title>Migrations for MongoEngine</title>
      <link>https://blog.sneawo.com/blog/2017/04/14/migrations-for-mongoengine/</link>
      <pubDate>Fri, 14 Apr 2017 13:39:48 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/04/14/migrations-for-mongoengine/</guid>
      <description>&lt;p&gt;A MongoDB collection does not have a strict schema, the documents in one collection can have different fields. But in MongoEngine the schema is provided on an application level and there is a validation. So if you&amp;rsquo;ll remove a field from the &lt;code&gt;Document&lt;/code&gt; and it&amp;rsquo;s still exists in the database, there will be a &lt;code&gt;mongoengine.errors.FieldDoesNotExist&lt;/code&gt; exception. If there is no need in the schema validation, a &lt;a href=&#34;https://mongoengine-odm.readthedocs.io/guide/defining-documents.html#defining-documents&#34;&gt;dynamic schema&lt;/a&gt; can be used.&lt;/p&gt;&#xA;&lt;p&gt;So when there is a strict schema, it&amp;rsquo;s good to have a tool to make an updates for the documents in the collection when something changes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to use multiple databases with Flask-MongoEngine</title>
      <link>https://blog.sneawo.com/blog/2017/04/11/how-to-use-multiple-databases-with-flask-mongoengine/</link>
      <pubDate>Tue, 11 Apr 2017 13:39:48 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/04/11/how-to-use-multiple-databases-with-flask-mongoengine/</guid>
      <description>&lt;p&gt;Sometimes it&amp;rsquo;s a good idea to use different databases for different parts of the application, they can have different requirements for performance and backup strategy or as a step to split a monolith to microservices.&lt;/p&gt;&#xA;&lt;p&gt;Here is an example of configuration for Flask and &lt;a href=&#34;https://mongoengine-odm.readthedocs.io/guide/connecting.html#multiple-databases&#34;&gt;MongoEngine&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sublime Text freeze</title>
      <link>https://blog.sneawo.com/blog/2017/03/30/sublime-text-freeze/</link>
      <pubDate>Thu, 30 Mar 2017 13:31:48 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/03/30/sublime-text-freeze/</guid>
      <description>Recently my Sublime Text has stopped running with freeze on start. I don&amp;rsquo;t know the cause, but removing of the last session helped.&#xA;cd &amp;#34;~/Library/Application Support/Sublime Text 3/Local&amp;#34; rm *.sublime_session </description>
    </item>
    <item>
      <title>How to build a dynamic query with mongoengine</title>
      <link>https://blog.sneawo.com/blog/2017/03/26/how-to-build-a-dynamic-query-with-mongoengine/</link>
      <pubDate>Sun, 26 Mar 2017 19:26:48 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/03/26/how-to-build-a-dynamic-query-with-mongoengine/</guid>
      <description>&lt;p&gt;An example of the use of the &lt;a href=&#34;https://mongoengine-odm.readthedocs.io/guide/querying.html#advanced-queries&#34;&gt;Q&lt;/a&gt; class to build the query.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Migration from http to https for hugo blog</title>
      <link>https://blog.sneawo.com/blog/2017/03/17/migration-from-http-to-https-for-hugo-blog/</link>
      <pubDate>Fri, 17 Mar 2017 13:36:48 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/03/17/migration-from-http-to-https-for-hugo-blog/</guid>
      <description>&lt;p&gt;This week I moved the blog from http to https. The reason - everything is moving to https and maybe it&amp;rsquo;s good for SEO. There were several steps.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Google App Engine limits and vendor locks</title>
      <link>https://blog.sneawo.com/blog/2017/03/03/google-app-engine-limits-and-vendor-locks/</link>
      <pubDate>Fri, 03 Mar 2017 13:36:48 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/03/03/google-app-engine-limits-and-vendor-locks/</guid>
      <description>&lt;p&gt;At the beginning of the 2015 I worked on a python application in Google App Engine. After all, because of some limitations and vendor locks, the app was moved to docker environment. Here is the list of these limitations. I did not check since then, maybe something changed, there is &lt;a href=&#34;https://cloud.google.com/appengine/docs/flexible/&#34;&gt;App Engine Flexible Environment&lt;/a&gt;, but it&amp;rsquo;s still in beta.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Celery background task with notifications through socket.io</title>
      <link>https://blog.sneawo.com/blog/2017/02/28/celery-background-task-with-notifications-through-socket.io/</link>
      <pubDate>Tue, 28 Feb 2017 13:36:26 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/02/28/celery-background-task-with-notifications-through-socket.io/</guid>
      <description>&lt;p&gt;If you have some long background tasks, sometimes it&amp;rsquo;s useful to notify a user about the progress.&#xA;In this article i put an example for &lt;a href=&#34;http://flask.pocoo.org&#34;&gt;flask&lt;/a&gt;, &lt;a href=&#34;http://www.celeryproject.org&#34;&gt;celery&lt;/a&gt; and &lt;a href=&#34;http://socket.io&#34;&gt;socket.io&lt;/a&gt;. In short form it&amp;rsquo;s described in &lt;a href=&#34;https://flask-socketio.readthedocs.io/en/latest/#emitting-from-an-external-process&#34;&gt;flask-socketio&lt;/a&gt; documentation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to create a test certificate to sign Electron application</title>
      <link>https://blog.sneawo.com/blog/2017/02/21/how-to-create-a-test-certificate-to-sign-electron-application/</link>
      <pubDate>Tue, 21 Feb 2017 13:36:26 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/02/21/how-to-create-a-test-certificate-to-sign-electron-application/</guid>
      <description>&lt;p&gt;If you use electron-builder and you need to &lt;a href=&#34;https://github.com/electron-userland/electron-builder/wiki/Code-Signing&#34;&gt;sign your app&lt;/a&gt; to test the update process, but you don&amp;rsquo;t have the Apple Developer account.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Flask-Admin formatters examples</title>
      <link>https://blog.sneawo.com/blog/2017/02/10/flask-admin-formatters-examples/</link>
      <pubDate>Fri, 10 Feb 2017 13:36:26 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/02/10/flask-admin-formatters-examples/</guid>
      <description>&lt;p&gt;To customize how the model&amp;rsquo;s columns are displayed in the list of objects in &lt;a href=&#34;https://flask-admin.readthedocs.io/en/latest/&#34;&gt;Flask-Admin&lt;/a&gt;, it requires column formatters.&#xA;Here are some examples.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Macbook Air 2012 upgrade to Macbook Pro 2016</title>
      <link>https://blog.sneawo.com/blog/2017/02/03/macbook-air-2012-upgrade-to-macbook-pro-2016/</link>
      <pubDate>Fri, 03 Feb 2017 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/02/03/macbook-air-2012-upgrade-to-macbook-pro-2016/</guid>
      <description>&lt;p&gt;The last 4 years I worked on Macbook Air Mid 2012 - 8 Gb,&#xA;now I have &lt;a href=&#34;https://www.amazon.com/gp/product/B01MPZIOMS/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B01MPZIOMS&amp;amp;linkCode=as2&amp;amp;tag=blogamazonref-20&amp;amp;linkId=3144ea7715cd6157b5fc087db762cdb1&#34;&gt;Macbook Pro 13.3&amp;quot; 2016&lt;/a&gt;&lt;!-- raw HTML omitted --&gt; - lowest model, no touchbar, but with 16 Gb.&#xA;Actually there is nothing to compare, the Macbook Pro is better in every aspect.&lt;/p&gt;&#xA;&lt;p&gt;The main result is that everything 1.5-2 times faster, some examples:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fast tests with in-memory MongoDB</title>
      <link>https://blog.sneawo.com/blog/2017/01/26/fast-tests-with-in-memory-mongodb/</link>
      <pubDate>Thu, 26 Jan 2017 17:11:00 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/01/26/fast-tests-with-in-memory-mongodb/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s always better to have a faster tests. For tests which use a database there are two ways to increase the speed:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;a mock library, like &lt;a href=&#34;https://github.com/mongomock/mongomock&#34;&gt;mongomock&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;in-memory database&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Achievments in 2016</title>
      <link>https://blog.sneawo.com/blog/2017/01/19/achievments-in-2016/</link>
      <pubDate>Thu, 19 Jan 2017 17:11:00 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/01/19/achievments-in-2016/</guid>
      <description>&lt;p&gt;A list of my most important achievments in 2016:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;started a new job at &lt;a href=&#34;http://mailinblack.com&#34;&gt;MailInBlack&lt;/a&gt; &amp;amp; &lt;a href=&#34;http://letsignit.com&#34;&gt;LetSignIt&lt;/a&gt;, like it.&lt;/li&gt;&#xA;&lt;li&gt;used a lot of different technologies: flask, celery, angular, mondodb, scala, docker, azure &amp;amp; google clouds, google app engine&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Migrate from octopress to hugo</title>
      <link>https://blog.sneawo.com/blog/2017/01/12/migrate-from-octopress-to-hugo/</link>
      <pubDate>Thu, 12 Jan 2017 13:55:34 +0100</pubDate>
      <guid>https://blog.sneawo.com/blog/2017/01/12/migrate-from-octopress-to-hugo/</guid>
      <description>&lt;p&gt;As usual at the beginning of the year I decided to continue the blog, but I was on a new macbook with a fresh system and also I forgot how to use octopress. So, why not to try something new.&lt;/p&gt;</description>
    </item>
    <item>
      <title>NGINX for static files for dev python server</title>
      <link>https://blog.sneawo.com/blog/2016/05/14/nginx-for-static-files-for-dev-python-server/</link>
      <pubDate>Sat, 14 May 2016 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2016/05/14/nginx-for-static-files-for-dev-python-server/</guid>
      <description>&lt;p&gt;When you work on the backend part of django or flask project and there are many static files, sometimes the development server becomes slow. In this case it&amp;rsquo;s possible to use nginx as reverse proxy to serve static. I&amp;rsquo;m using nginx in docker and the configuration is quite simple.&lt;/p&gt;</description>
    </item>
    <item>
      <title>strftime for datetime before 1900 year</title>
      <link>https://blog.sneawo.com/blog/2015/04/08/strftime-for-datetime-before-1900-year/</link>
      <pubDate>Wed, 08 Apr 2015 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2015/04/08/strftime-for-datetime-before-1900-year/</guid>
      <description>Recently I&amp;rsquo;ve got an error for birthdays before 1900 year&#xA;ValueError: year=1890 is before 1900; the datetime strftime() methods require year &amp;gt;= 1900 for this code:&#xA;import datetime datetime.date(1890,7,1).strftime(&amp;#39;%d.%m.%Y&amp;#39;) And it&amp;rsquo;s described in the documentation&#xA;The full set of format codes supported varies across platforms, because Python calls the platform C library’s strftime() function, and platform variations are common. To see the full set of format codes supported on your platform, consult the strftime(3) documentation.</description>
    </item>
    <item>
      <title>Test django view with cookies</title>
      <link>https://blog.sneawo.com/blog/2015/03/20/test-django-view-with-cookies/</link>
      <pubDate>Fri, 20 Mar 2015 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2015/03/20/test-django-view-with-cookies/</guid>
      <description>To test some view which use cookies:&#xA;from Cookie import SimpleCookie from django import test class SomeTest(test.TestCase): def test_some_view(self): self.client.cookies = SimpleCookie({&amp;#39;test_cookie&amp;#39;: &amp;#39;test_value&amp;#39;}) response = self.client.get(&amp;#39;/some-url/&amp;#39;) self.assertEqual(response.client.cookies[&amp;#39;test_cookie&amp;#39;].value, &amp;#39;test_value&amp;#39;) </description>
    </item>
    <item>
      <title>My current tools</title>
      <link>https://blog.sneawo.com/blog/2013/07/20/my-current-tools/</link>
      <pubDate>Sat, 20 Jul 2013 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2013/07/20/my-current-tools/</guid>
      <description>MacBook Air 13&amp;quot; instead of iMac 24&amp;quot; 2007&#xA;It&amp;rsquo;s faster and provides me mobility, but I&amp;rsquo;m lacking in screen size, I plan to solve this with external monitor.&#xA;Sublime Text3 with next packages:&#xA;package control djaneiro (django support) django-docsearch git (checkout branch python3) jsformat modific (highlighting lines changed since the last commit) sidebar enchancement sublimelinter (checkout sublime-text-3 branch) theme phoenix Before this I used PyCharm, it&amp;rsquo;s very good, but slower.</description>
    </item>
    <item>
      <title>Installing Django on Ubuntu memo</title>
      <link>https://blog.sneawo.com/blog/2013/05/14/installing-django-on-ubuntu-memo/</link>
      <pubDate>Tue, 14 May 2013 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2013/05/14/installing-django-on-ubuntu-memo/</guid>
      <description>&lt;p&gt;Here are a few notes and links after moving to the new Ubuntu server on &lt;a href=&#34;http://linode.com&#34;&gt;linode.com&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Some steps for security: &lt;a href=&#34;http://plusbryan.com/my-first-5-minutes-on-a-server-or-essential-security-for-linux-servers&#34;&gt;My First 5 Minutes On A Server&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Install packages:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install apache2 libapache2-mod-wsgi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install postgresql postgresql-server-dev-9.1 python-dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install mysql-server mysql-common mysql-client libmysqlclient-dev &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install git git-core&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Setup virtualenv:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install python-setuptools&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install python-pip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install virtualenv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;virtualenv --no-site-packages /path/to/venv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;http://jj.isgeek.net/2011/09/install-pil-with-jpeg-support-on-ubuntu-oneiric-64bits/&#34;&gt;Install PIL in virtualenv&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt-get install libjpeg libjpeg-dev libfreetype6 libfreetype6-dev zlib1g-dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ln -s /usr/lib/&lt;span style=&#34;color:#a50&#34;&gt;`&lt;/span&gt;uname -i&lt;span style=&#34;color:#a50&#34;&gt;`&lt;/span&gt;-linux-gnu/libfreetype.so /usr/lib/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ln -s /usr/lib/&lt;span style=&#34;color:#a50&#34;&gt;`&lt;/span&gt;uname -i&lt;span style=&#34;color:#a50&#34;&gt;`&lt;/span&gt;-linux-gnu/libjpeg.so /usr/lib/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ln -s /usr/lib/&lt;span style=&#34;color:#a50&#34;&gt;`&lt;/span&gt;uname -i&lt;span style=&#34;color:#a50&#34;&gt;`&lt;/span&gt;-linux-gnu/libz.so /usr/lib/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install PIL&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Real time messaging in Django using Node.js and Redis</title>
      <link>https://blog.sneawo.com/blog/2013/02/08/real-time-messaging-in-django-using-node-dot-js-and-redis/</link>
      <pubDate>Fri, 08 Feb 2013 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2013/02/08/real-time-messaging-in-django-using-node-dot-js-and-redis/</guid>
      <description>&lt;p&gt;Here, just a small example of this task.&#xA;Assume you have django comments system enabled.&lt;/p&gt;&#xA;&lt;p&gt;Then you need to add publishing of comments into redis. It can be done with &lt;a href=&#34;https://docs.djangoproject.com/en/1.4/ref/contrib/comments/signals/#comment-was-posted&#34;&gt;comment_was_posted&lt;/a&gt; signal.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to update Django user profile from ForeignKey to OneToOneField</title>
      <link>https://blog.sneawo.com/blog/2013/01/31/how-to-update-django-user-profile-from-foreignkey-to-onetoonefield/</link>
      <pubDate>Thu, 31 Jan 2013 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2013/01/31/how-to-update-django-user-profile-from-foreignkey-to-onetoonefield/</guid>
      <description>&lt;p&gt;In one of my projects for the user profile model was used ForeignKey field.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00a&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#0a0;text-decoration:underline&#34;&gt;UserProfile&lt;/span&gt;(models.Model):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    user = models.ForeignKey(User, unique=&lt;span style=&#34;color:#00a&#34;&gt;True&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This leads to a lot of unnecessary queries when you want to access to related data, like:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{% raw %}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{% for item in items %}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {{ item.user.get_profile.company }}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{% endfor %}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{% endraw %}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>StackOverflow Charts</title>
      <link>https://blog.sneawo.com/blog/2013/01/19/stackoverflow-charts/</link>
      <pubDate>Sat, 19 Jan 2013 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2013/01/19/stackoverflow-charts/</guid>
      <description>&lt;!-- raw HTML omitted --&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;!-- raw HTML omitted --&gt;&#xA;&lt;p&gt;A month ago I began to participate in &lt;a href=&#34;http://stackoverflow.com/users/1885757/sneawo&#34;&gt;StackOverflow&lt;/a&gt; process.&#xA;So I was interested to collect some statistics data and find where am I in this game. StackOverflow has a good &lt;a href=&#34;https://api.stackexchange.com&#34;&gt;API&lt;/a&gt; with limits for 300 requests/days for anonymous user and 10 000 requests/day for authorized. I created a simple bot on python, collected data to MongoDb and built these charts. With 10 000 requests and page size 100 I got users from highest reputation (524k) to 269. So I built these charts starting from reputation of 300.&lt;/p&gt;&#xA;&lt;p&gt;The number of users with reputation &amp;gt; 300 is 96 654. And total number of users is about 1 375 000. So the percent of active users is about 7%.&lt;/p&gt;&#xA;&lt;!-- raw HTML omitted --&gt;</description>
    </item>
    <item>
      <title>My version of django boilerplate</title>
      <link>https://blog.sneawo.com/blog/2013/01/13/my-version-of-django-boilerplate/</link>
      <pubDate>Sun, 13 Jan 2013 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2013/01/13/my-version-of-django-boilerplate/</guid>
      <description>django_boilerplate - it&amp;rsquo;s a template to fast start new Django project.&#xA;Based on:&#xA;django twitter bootstrap Used apps:&#xA;south - data migrations django-crispy-forms - for forms rendering django-allauth - for local and social registration, authorization django-debug-toolbar django-extensions It also includes example app with List, Create, Update, Delete views.&#xA;Install&#xA;pip install -r requirements.txt python manage.py syncdb </description>
    </item>
    <item>
      <title>A simple CRUD app with Django and Mongoengine</title>
      <link>https://blog.sneawo.com/blog/2013/01/05/a-simple-crud-app-with-django-and-mongoengine/</link>
      <pubDate>Sat, 05 Jan 2013 00:00:00 +0000</pubDate>
      <guid>https://blog.sneawo.com/blog/2013/01/05/a-simple-crud-app-with-django-and-mongoengine/</guid>
      <description>&lt;p&gt;There are several possibilities to use MongoDB in Django:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://api.mongodb.org/python/current/&#34;&gt;PyMongo&lt;/a&gt; as is&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://django-mongodb.org&#34;&gt;Django MongoDB Engine&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://mongoengine.org&#34;&gt;Mongoengine&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://namlook.github.com/mongokit/&#34;&gt;MongoKit&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Django MongoDB uses django-nonrel, which is a fork based on Django 1.3.&lt;br&gt;&#xA;I don&amp;rsquo;t like this idea, because now Django 1.5 is ready to out.&#xA;Beetween Mongoengine and MongoKit, I like more Mongoengine. There are several comparative articles:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://www.peterbe.com/plog/using-mongodb-in-your-django-app/django-mongodb-html5-slides/html5.html#slide1&#34;&gt;Using MongoDB in your Django app&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://www.quora.com/MongoDB/Whats-the-best-MongoDB-ORM-for-Python&#34;&gt;What&amp;rsquo;s the best MongoDB ORM for Python?&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;So I created a &lt;a href=&#34;https://github.com/sneawo/django_mongo_test&#34;&gt;simple CRUD app&lt;/a&gt; using Mongoengine.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
