Archive

Archive for the ‘python’ Category

virtualenvwrapper (Part 2)

Here I describe how I use virtualenvwrapper.

I keep my virtual environments in the default location (~/.virtualenvs folder). My Python projects are kept in Dropbox. If a project (call it “stuff” for instance) has a virtual env., then I add the suffix “_project” to the projects’s folder name (resulting “stuff_project” in this example). This way I can see it immediately (without entering the folder) that it has an attached venv.

In the stuff_project folder create a requirements.txt file that contains all the modules that you installed in your venv. This way you can re-create your venv on another machine and continue to work on yout project.

Let’s see a concrete example. Say I want to create a new Django project:

$ cd $HOME/Dropbox/python/webapps
$ mkdir stuff_project
# ^ every project file will be in this folder
$ cd stuff_project
$ django-admin.py startproject stuff
# ^ create the Django project
$ mkvirtualenv stuff_project
# ^ venv is created AND activated
$ pip install django
$ pip install django-extensions
# ^ useful extensions
$ pip freeze --local >requirements.txt
# ^ packages installed in the venv are listed in this file

Since I put the project folder in Dropbox, it will be synced on all my machines. What to do if I want to work on this project on another machine of mine (let’s call it “machine #2”)? The virtual environment will be missing. But there is no need to worry. We have a requirements.txt file and from this we can populate a newly created venv. Install virtualenvwrapper on machine #2 and create an empty venv for the project:

# actions to perform on machine #2:
$ cd $HOME/Dropbox/python/webapps/stuff_project
$ mkvirtualenv stuff_project
# ^ the venv is created and activated
$ pip install -r requirements.txt
# ^ packages are installed in the venv

When you are done with the project, deactivate the venv with the “deactivate” command. Since it’s too long, I put an alias on it:

alias off='deactivate'

If you install new packages in the venv, don’t forget to update the requirements.txt file ( pip freeze >requirements.txt )!

virtualenvwrapper (Part 1)

I use virtualenv but so far it’s been enough for me. However, the time has come to step on to the next level: virtualenvwrapper. Virtualenvwrapper is just a wrapper around virtualenv, but it makes working with virtualenv so much easier.

Problem
I keep all my Python projects in Dropbox. Every project is located in a dedicated folder. If I use virtualenv, inside a project folder I need to create a subfolder for the the virtual environment (typically called “venv”). However, this folder can be really huge. In the case of a Flask project it can be up to 50-60 MB. Keeping it in Dropbox is a luxury. It would be great to move the virtual environments outside of Dropbox. My first idea was to put a symbolic link on the venv folder from the project folder but Dropbox doesn’t support symlinks :(

Solution
Let’s use virtualenvwrapper! Virtualenvwrapper was created with this idea: collect virtual environments in a separated folder, outside of your projects. In addition, it’s very easy to switch between virtual environments.

Here are some great resources on virtualenvwrapper:

For more info, refer to Bob’s blog (last link above), where he gives a very nice summary about the usage of virtualenvwrapper.

Categories: python Tags: ,

An SQLite example

Here you will find a very basic program that stores data in SQLite. It is a simple example. If I need to write a program that needs sqlite, it can serve as a basis and I won’t need to write it from scratch.

Problem
Visit the page /r/earthporn, extract the image URLs and save the URLs of images stored on imgur in an sqlite table.

Solution
earthporn.py:

#!/usr/bin/env python
# encoding: utf-8

import requests
import database as db    # see below

subreddit = "earthporn"

def main():
    db.init()    # Important! It will connect to the DB.

    r = requests.get('http://www.reddit.com/r/{sr}/.json'.format(sr=subreddit))
    d = r.json()
    children = d["data"]["children"]
    for e in children:
        url = e["data"]["url"]
        if "imgur.com" in url:
#            print url
            db.add_image(url, subreddit)

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

if __name__ == "__main__":
    main()

database.py:

#!/usr/bin/env python

"""
Sqlite database handler.
"""

import os
import sqlite3
import atexit
import random
import termcolor

PATH = os.path.dirname(os.path.abspath(__file__))
SCHEMA = """
CREATE TABLE "images" (
    "url" TEXT PRIMARY KEY NOT NULL,
    "subreddit" TEXT,
    "insert_date" DEFAULT CURRENT_TIMESTAMP
)
"""
SQLITE_DB = PATH + '/images.sqlite'

conn = None

def get_random_image():
    query = "SELECT url FROM images"
    cursor = conn.cursor()
    cursor.execute(query)
    result = cursor.fetchall()
    return random.choice(result)[0]

def add_image(url, subreddit=None):
    try:
        if subreddit:
            query = "INSERT INTO images (url, subreddit) VALUES (?, ?)"
            conn.execute(query, (url, subreddit))
        else:
            query = "INSERT INTO images (url, subreddit) VALUES (?, NULL)"
            conn.execute(query, (url,))
        #
        print termcolor.colored("# {url} added to DB".format(url=url), "cyan")
    except sqlite3.IntegrityError:
        print termcolor.colored("# the image {0} is already in the DB...".format(url), "red")

def get_all_images():
    query = "SELECT url FROM images"
    cursor = conn.cursor()
    cursor.execute(query)
    result = cursor.fetchall()
    return result

def create_db():
    """
    Create the DB if not exists.
    """
    global conn
    conn = sqlite3.connect(SQLITE_DB)
    conn.executescript(SCHEMA)

def init(commit=True):
    """
    Initialize the DB.
    """
    global conn
    if commit:
        atexit.register(commit_and_close)
    else:
        atexit.register(close)

    if not os.path.exists(SQLITE_DB):
        create_db()
    if not conn:
        conn = sqlite3.connect(SQLITE_DB)

def commit():
    """
    Commit.
    """
    if conn:
        conn.commit()

def close():
    """
    Close.
    """
    if conn:
        conn.close()

def commit_and_close():
    """
    Commit and close DB connection.

    As I noticed, commit() must be called, otherwise changes
    are not committed automatically when the program terminates.
    """
    if conn:
        conn.commit()
        conn.close()

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

if __name__ == "__main__":
    init()

The module database.py is responsible for handling the database. When you need to work with the database, just include this file and call the appropriate function(s).

Categories: python Tags: , ,

Get an email notification when a site is up

Problem
Today I wanted to submit a paper to a conference but the site that manages submissions (EasyChair) is down for maintenance. I got this message:

EasyChair is Being Moved to a New Server

Quite unexpectedly, EasyChair had to be moved to a new server.

We are moving the system itself and restoring all data. We are sorry for any inconveniences caused.

The move is to be completed during Friday, May the 9th. We cannot give precise time at the moment. We are working hard to make it up and running as soon as possible.

I don’t want to check this site manually. How could I get notified when the site is up?

Solution
I wrote a simple script that regularly checks the site. When it’s up, it sends me an email notification and quits.

Here I reused some functions from my jabbapylib library. You can easily include those functions to make it standalone.

#!/usr/bin/env python
# encoding: utf-8

from __future__ import (absolute_import, division,
                        print_function, unicode_literals)

from time import sleep

import schedule

from jabbapylib.mail.gmail_send import mail_html
from jabbapylib.web.web import get_page, html_to_text
import sys

URL = 'http://www.easychair.org/'
USERNAME = "..."
PASSWORD = "..."
sender = {
    'gmail_user': USERNAME,
    'gmail_name': "PyChecker",
    'gmail_pwd': PASSWORD,
}
STOP = False

def is_down(url):
    """
    Check if the site is down.

    Return True if it's down. Otherwise, return False.
    """
    html = get_page(url)
    text = " ".join(html_to_text(html).split())
    return "We are sorry for any inconveniences caused." in text

def job():
    global STOP

    print()
    if is_down(URL):
        print("The site is still down.")
    else:
        print("The site is up.")
        mail_html(sender, "TO@gmail.com",
            "EasyChair is up!",
            "Send your paper: <a href='https://www.easychair.org'>EasyChair</a>.")
        print("E-mail notification was sent.")
        STOP = True

def main():
    schedule.every(5).minutes.do(job)

    print("Running...")

    while not STOP:
        schedule.run_pending()
        sleep(10)
        sys.stdout.write('.'); sys.stdout.flush()

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

if __name__ == "__main__":
    main()
Categories: python Tags: , , , ,

PyScripter: a very nice small IDE for Windows

April 8, 2014 Leave a comment

I found a very nice small Python IDE for Windows called PyScripter.

PyScripter is a free and open-source Python Integrated Development Environment (IDE) created with the ambition to become competitive in functionality with commercial Windows-based IDEs available for other languages. Being built in a compiled language is rather snappier than some of the other Python IDEs and provides an extensive blend of features that make it a productive Python development environment.” (source)

The install file is less than 5 MB and PyScripter provides all the features you want from a modern IDE: syntax highlight, run code and see the output, code completion, built-in Python shell, debugger, etc.

Here is a youtube video for beginners that shows first how to install Python on Windows, then presents PyScripter.

Categories: python, windows Tags: , ,

imgur album downloader

April 5, 2014 Leave a comment

This little script can download all the images in an imgur gallery.

Categories: python Tags: , ,

Improving the sidebar of /r/python

March 21, 2014 Leave a comment

In the sidebar of /r/python, there was a very unpythonic infinite loop for a long time:

while 1:
    # do something

Today I sent a message to the moderators and they changed it:

while

Update: I got a message from them.

Categories: python Tags: , , ,

get the command pip3

March 15, 2014 1 comment

Problem
You have Python 2 and Python 3 on the same machine. You want to install a package that requires Python 3. You cannot use the command “pip” because it will install the package as if it were written in Python 2. You want a “pip3” command.

Solution #1 (20140912)

sudo apt-get install python3-pip

Solution #2
I found the solution here.

Steps:

$ wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
$ sudo python3 get-pip.py

Now you have a “pip3” command that you can use to install Python 3 libraries.

Categories: python Tags: ,

installing pgmagick

March 4, 2014 Leave a comment

pgmagick is yet another boost.python based wrapper for GraphicsMagick.

GraphicsMagick is the swiss army knife of image processing. …it provides a robust and efficient collection of tools and libraries which support reading, writing, and manipulating an image in over 88 major formats including important formats like DPX, GIF, JPEG, JPEG-2000, PNG, PDF, PNM, and TIFF.” (source)

Here I found an interesting blog post on how to remove image backgrounds with a Python script (comments on it here). The script uses the pgmagick library.

Problem
How to install pgmagick and GraphicsMagick? That is, the following line shouldn’t drop any error :)

>>> import pgmagick
>>>

Solution
It may not be an optimal solution because it installed on my machine LOTS OF extra packages… However, it worked for me.

$ sudo add-apt-repository ppa:dhor/myway
$ sudo apt-get update
$ sudo apt-get install graphicsmagick

$ sudo apt-get install libmagick++-dev
$ sudo apt-get install libboost-python-dev
$ sudo pip install pgmagick -U

Usage example
scale example (copied from here):

>>> from pgmagick import Image, FilterTypes
>>> im = Image('input.jpg')
>>> im.quality(100)
>>> im.filterType(FilterTypes.SincFilter)
>>> im.scale('100x100')
>>> im.sharpen(1.0)
>>> im.write('output.jpg')

Links

Categories: python, ubuntu Tags: ,
Design a site like this with WordPress.com
Get started