Archive
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:
- Doug Hellman’s virtualenvwrapper notes (BTW, he is the creator of virtualenvwrapper)
- official docs
- Getting Started with virtualenv and virtualenvwrapper in Python (Bob’s blog)
For more info, refer to Bob’s blog (last link above), where he gives a very nice summary about the usage of virtualenvwrapper.
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).
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()
PyScripter: a very nice small IDE for Windows
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.
imgur album downloader
This little script can download all the images in an imgur gallery.
Improving the sidebar of /r/python
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:
Update: I got a message from them.
Unicode box-drawing characters
I wanted to make a logo for my project PrimCom. Since it runs in the command line, I wanted to draw the logo with characters.
You can find a list of box-drawing characters here. I designed the logo on a paper, translated the box characters to normal characters (this way it was easier to type them in), then translated the characters back with a script.
Python source:
#!/usr/bin/env python
# encoding: utf-8
from __future__ import (absolute_import, division,
print_function, unicode_literals)
import sys
chars = {
'a': '┌',
'b': '┐',
'c': '┘',
'd': '└',
'e': '─',
'f': '│',
'g': '┴',
'h': '├',
'i': '┬',
'j': '┤',
'k': '╷',
'l': '┼',
}
logo = """
aeeb aeeb
fabf faec
fdcheiieejf aeeieeb
faejaljkkff fabfkkf
ff fffffffdejdcffff
dc dcdggggeegeegggc
"""
def main():
for c in logo:
if c in chars:
sys.stdout.write(chars[c])
else:
sys.stdout.write(c)
if __name__ == "__main__":
main()
Output:
┌─────┐ ┌─────┐ │ ┌─┐ │ │ ┌───┘ │ └─┘ ├───┬─┬─────┤ │ ┌─────┬─────┐ │ ┌───┤ ┌─┼─┤ ╷ ╷ │ │ │ ┌─┐ │ ╷ ╷ │ │ │ │ │ │ │ │ │ │ └───┤ └─┘ │ │ │ │ └─┘ └─┘ └─┴─┴─┴─┴─────┴─────┴─┴─┴─┘
Update (20140322)
If you want rainbow colors, check out the colout project.
get the command pip3
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.
installing pgmagick
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


You must be logged in to post a comment.