Archive

Author Archive

for / else and try / except / else

June 17, 2016 1 comment

Problem
What is that “else” in a for loop? And that “else” in an exception handler?

Solution
They can be confusing but in this thread I found a perfect way to remember what they mean. Asdayasman suggests that we should always annotate these “else” branches:

for _ in []:
    ...
else:  # nobreak
    ...

try:
    ...
except:
    ...
else:  # noexcept
    ...

To be honest, IMO it is best to avoid for / else completely.

Categories: python Tags: , , ,

email notification from a script

June 15, 2016 1 comment

Problem
You want to send an email to yourself from a script.

Solution
You can find here how to do it from a Bash script. That solution uses the mailx command.

Here is a simple Python wrapper for the mailx command:

#!/usr/bin/env python3
# coding: utf8

import os

DEBUG = True
# DEBUG = False

class NoSubjectError(Exception):
    pass

class NoRecipientError(Exception):
    pass

def send_email(to='', subject='', body=''):
    if not subject:
        raise NoSubjectError
    if not to:
        raise NoRecipientError
    #
    if not body:
        cmd = """mailx -s "{s}" < /dev/null "{to}" 2>/dev/null""".format(
            s=subject, to=to
        )
    else:
        cmd = """echo "{b}" | mailx -s "{s}" "{to}" 2>/dev/null""".format(
            b=body, s=subject, to=to
        )
    if DEBUG:
        print("#", cmd)
    #
    os.system(cmd)

def main():
    send_email(to="to@email.com",
               subject="subject")
    #
    send_email(to="to@email.com",
               subject="subject",
               body='this is the body of the email')

#############################################################################

if __name__ == "__main__":
    main()

You can also find this code as a gist.

Categories: python Tags: , ,

a simple GUI pomodoro timer

For managing my TODO lists, I use a sheet of paper where I make a list of tasks to do. A few days ago I started to use the pomodoro technique, which helps a lot to actually DO those tasks :)

As I don’t have a tomato-shaped kitchen timer (yet!), I wrote a simple GUI timer that you can find on github.

Update (20160608)
Here is an online timer: http://www.timeanddate.com/timer/. It can play a sound, and you can also launch several timers if you want. Thanks Jeszy for the link.

vulture is available in neomake

Recently I started to use neovim (here is my story). I mainly edit Python codes so I looked around and collected some useful plugins (here is my init.vim file). One of these plugins is neomake, an asynchronous :make using Neovim’s job-control functionality (it also works in ordinary vim, but without the asynchronous benefits).

I had a little contribution to neomake and that’s what I want to write about in this post. I sent a pull request to include vulture as a Python maker. Vulture finds unused classes, functions and variables in your code. Let’s see two screenshots without and with vulture:

Without vulture:
vulture_without

With vulture:
vulture_with

init.vim settings
Here is my corresponding settings that enables vulture too:

Plug 'neomake/neomake'
" {{{
    " neomake is async => it doesn't block the editor
    " It's a syntastic alternative. Syntastic was slow for me on python files.
    " $ sudo pip2/pip3 install flake8 -U
    " $ sudo pip2/pip3 install vulture -U
    let g:neomake_python_enabled_makers = ['flake8', 'pep8', 'vulture']
    " let g:neomake_python_enabled_makers = ['flake8', 'pep8']
    " E501 is line length of 80 characters
    let g:neomake_python_flake8_maker = { 'args': ['--ignore=E115,E266,E501'], }
    let g:neomake_python_pep8_maker = { 'args': ['--max-line-length=100', '--ignore=E115,E266'], }

    " run neomake on the current file on every write:
    autocmd! BufWritePost * Neomake
" }}}

Links
Pull requests #420 and #440.

Categories: python Tags: , , , ,

“import tkinter” fails

April 27, 2016 Leave a comment

Problem
Under Manjaro I wanted to use the turtle module but I got this error:

File "square.py", line 1, in <module>
    import turtle
  File "/usr/lib/python2.7/lib-tk/turtle.py", line 107, in <module>
    import Tkinter as TK
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 39, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory

Solution

sudo pacman -S tk
Categories: python Tags: , , ,

Installing a Flask webapp on a Digital Ocean (or Linode, etc.) Ubuntu box

March 26, 2016 Leave a comment

How to install a Flask webapp on a Digital Ocean VPS that has Ubuntu Linux on it: https://github.com/jabbalaci/DigitalOceanFlask.

This writing of mine appeared in Import Python Weekly Newsletter No. 65.

gunicorn from upstart fails to start

March 17, 2016 1 comment

Today I was trying to put together these: ubuntu + nginx + gunicorn + start gunicorn from upstart + flask + virtualenv. After a whole afternoon, I managed to do it. I will write a detailed post about it, but now I just want to concentrate on one part, which was the most problematic.

Problem
I wanted to start gunicorn from upstart. So I issued the following command:

$ sudo service gunicorn start 
gunicorn start/running, process 21415
$ sudo service gunicorn status
gunicorn stop/waiting

Each time I tried to launch it, it failed.

Solution
First of all, I didn’t know where the upstart log files were located. I know, it’s lame, but after a few hours I relized that it’d be a good idea to google it… So, the log files are in this folder:

/var/log/upstart

The log of gunicorn is here:

/var/log/upstart/gunicorn.log

Now, I started to monitor the end of this file in another terminal with “tail -f /var/log/upstart/gunicorn.log“. With this information I could easily find the error. I put here my solution and then I add some explanation:

# /etc/init/gunicorn.conf
#
description "Gunicorn daemon for a Flask project"

start on (local-filesystems and net-device-up IFACE=eth0)
stop on runlevel [!12345]

# If the process quits unexpectadly trigger a respawn
respawn

setuid demo
setgid demo

script
. "/home/demo/.virtualenvs/myproj/bin/activate"
cd /home/demo/projects/myproj/api
exec gunicorn --name="my project" --bind=127.0.0.1:9000 --config /etc/gunicorn.d/gunicorn.py api:app --pid=gunicorn_from_nginx.pid
end script

And you know what caused the problem? Instead of “.” I tried to use “source”. This is what I found in every tutorial. But as it turned out, this script is executed with “/bin/sh“, not with “/bin/bash“, and sh doesn’t know source. Geez…

The normal user on this machine is called “demo“. My Flask project is within a virtual environment. You can create a script block and the steps within are executed with “sh”. So first we “source” the virtual environment, then enter the directory where the Python script to be executed is located (here “api” is the name of the folder, and in there I have a file called “api.py“, which contains the “app” variable). gunicorn is also installed in the virtual environment! You don’t need to install it globally with “sudo“!

Nginx is listening on port 80 and every connection that arrives there are forwarded to this gunicorn instance on port 9000. But I’ll write about it a bit later.

Appendix
The content of “/etc/gunicorn.d/gunicorn.py“:

"""gunicorn WSGI server configuration."""
from multiprocessing import cpu_count
from os import environ


def max_workers():
    return cpu_count() * 2 + 1

max_requests = 1000
worker_class = 'gevent'
workers = max_workers()
Categories: flask, python Tags: , , , ,
Follow

Get every new post delivered to your Inbox.

Join 117 other followers