{"id":223,"date":"2013-01-25T21:50:13","date_gmt":"2013-01-26T03:50:13","guid":{"rendered":"http:\/\/www.crccheck.com\/blog\/?p=223"},"modified":"2015-10-11T22:28:44","modified_gmt":"2015-10-12T04:28:44","slug":"a-few-virtualenv-tips","status":"publish","type":"post","link":"https:\/\/www.crccheck.com\/blog\/a-few-virtualenv-tips\/","title":{"rendered":"A few virtualenv tips"},"content":{"rendered":"<p>If you&#8217;re doing any development in Python, odds are you&#8217;re using virtualenv. And if you&#8217;re using virtualenv, odds are you&#8217;re using virtualenvwrapper. I came up with a few tricks to make my life easier, and I thought I ought to share them. And as a disclaimer: although I am obsessed with discovering best practices, these are definitely not. So I&#8217;m adding a new category called &#8220;Meh Practices&#8221;.<\/p>\n<h2>Set an <code>$IPYTHONDIR<\/code> environment variable.<\/h2>\n<p>According to the <a href=\"http:\/\/ipython.org\/ipython-doc\/stable\/config\/overview.html#configuration-file-location\">IPython documentation<\/a>, IPython stores settings in a profile, and it looks for that profile in <code>$IPYTHONDIR<\/code>. So in my global virtualenv postactivate, I have:<\/p>\n<pre><code>export IPYTHONDIR=$VIRTUAL_ENV\/.ipython\n<\/code><\/pre>\n<p>Now why would anyone want a separate profile for every virtualenv? I do this so every virtual&#8217;s IPython gets its own history database. I also used to run IPython 0.10.X and 0.11.X side by side, and the two had incompatible profile formats. All my tools support the new IPython so this isn&#8217;t an issue for me anymore, but I still do it for the separate history.<\/p>\n<h2>Maintain the same IPython configuration for every profile<\/h2>\n<p>Because now I&#8217;m running around with N IPython profiles with N configurations when I really only want 1 configuration, I symlink all the profile configurations from a master one I keep in source control. The gist of it looks like:<\/p>\n<pre><code>DST=$IPYTHONDIR\/profile_default\nSRC=$HOME\/.dotfiles\/.ipython\/ipython_config.py\nmkdir -p $DST\ncd $DST\nln -s -f $SRC\n<\/code><\/pre>\n<p>But my actual one currently looks <a href=\"https:\/\/github.com\/crccheck\/dotfiles\/blob\/master\/bin\/mkipythonconfig\">like this<\/a> and I run it in my global postmkvirtualenv, which now looks like:<\/p>\n<pre><code>IPYTHONDIR=$VIRTUAL_ENV\/.ipython\nmkipythonconfig\n<\/code><\/pre>\n<p>Where <code>mkipythonconfig<\/code> is the snippet above.<\/p>\n<h2>Add an alias to maintain your environment variables<\/h2>\n<p>I got really sick of <code>cdvirtualenv<\/code> then <code>vi bin\/postactivate<\/code>, so in my postactivate, I have this line:<\/p>\n<pre><code>alias vivirtualenv=\"$VISUAL $VIRTUAL_ENV\/bin\/postactivate\"\n<\/code><\/pre>\n<p>in my virtualenv&#8217;s postactivate. Now when I need to edit my postactivate, it&#8217;s a few tab complete-able keystrokes away. I stole the naming convention from <code>visudo<\/code>, and I tried naming it <code>vipostactivate<\/code>, but I think <code>vivirtualenv<\/code> is just so catchy. Now if your immediately reaction is to make a comment telling me I should just use <a href=\"https:\/\/github.com\/kennethreitz\/autoenv\">autoenv<\/a>; too bad, I already thought about that. Right now, <a href=\"https:\/\/github.com\/kennethreitz\/autoenv\/issues\/28\">issue#28<\/a> is preventing me from adopting autoenv. I also can&#8217;t go around adding <code>.env<\/code> to the .gitignore of collaborated projects. And there&#8217;s one project I know of where the Procfile for foreman is not in the project root. #everythingisterrible<\/p>\n<h2>Use setvirtualenvproject<\/h2>\n<p>I don&#8217;t take advantage of virtualenvwrapper&#8217;s <code>mkproject<\/code>, nor do I really know what to do with them, but there is one thing I do use from that&#8230; <a href=\"http:\/\/virtualenvwrapper.readthedocs.org\/en\/latest\/command_ref.html#setvirtualenvproject\"><code>setvirtualenvproject<\/code><\/a>. I never use <code>mkproject<\/code> because I rarely name my projects and virtualenvs the same, and I haven&#8217;t bothered to set up any project templates. But I am lazy, and I like how if you tell virtualenv that your current working directory is the project root using <code>setvirtualenvproject<\/code>, every time you <code>workon<\/code> it, you&#8217;ll automatically cd into it. But what if you don&#8217;t want that to happen? You can jump back to the directory you were just in with <code>cd -<\/code>. For me, the extra time it takes to go back is more than made up by all the time saved not having to cd in.<\/p>\n<p>So putting everything together, I have a <a href=\"https:\/\/github.com\/crccheck\/dotfiles\/blob\/master\/Makefile\">makefile<\/a> for bootstrapping a new install so virtualenvwrapper and IPython are set up the way I like. It may seem like I have to do a lot of work to get up and running, but I&#8217;ve got it down to one <code>make<\/code> now.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;re doing any development in Python, odds are you&#8217;re using virtualenv. And if you&#8217;re using virtualenv, odds are you&#8217;re using virtualenvwrapper. I came up with a few tricks to make my life easier, and I thought I ought to share them. And as a disclaimer: although I am obsessed with discovering best practices, these&hellip;<\/p>\n <a href=\"https:\/\/www.crccheck.com\/blog\/a-few-virtualenv-tips\/\" title=\"A few virtualenv tips\" class=\"entry-more-link\"><span>Read More<\/span> <span class=\"screen-reader-text\">A few virtualenv tips<\/span><\/a>","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[47,4],"tags":[48,49],"class_list":["entry","author-showmewhatyougot","post-223","post","type-post","status-publish","format-standard","category-meh-practices","category-technical","tag-python","tag-virtualenv"],"_links":{"self":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/223","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/comments?post=223"}],"version-history":[{"count":11,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/223\/revisions"}],"predecessor-version":[{"id":757,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/223\/revisions\/757"}],"wp:attachment":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/media?parent=223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/categories?post=223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/tags?post=223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}