<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Happiness Nwosu]]></title><description><![CDATA[Writing about software engineering, system design, debugging, cloud architecture, career growth amongst other things]]></description><link>https://www.happinessnwosu.com</link><image><url>https://substackcdn.com/image/fetch/$s_!CP-b!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81bb4e77-51eb-4105-bf6c-75985e89f47d_144x144.png</url><title>Happiness Nwosu</title><link>https://www.happinessnwosu.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 13 May 2026 11:37:08 GMT</lastBuildDate><atom:link href="https://www.happinessnwosu.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Oriaku]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[happinessnwosu@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[happinessnwosu@substack.com]]></itunes:email><itunes:name><![CDATA[Happiness Nwosu]]></itunes:name></itunes:owner><itunes:author><![CDATA[Happiness Nwosu]]></itunes:author><googleplay:owner><![CDATA[happinessnwosu@substack.com]]></googleplay:owner><googleplay:email><![CDATA[happinessnwosu@substack.com]]></googleplay:email><googleplay:author><![CDATA[Happiness Nwosu]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Django management commands from admin interface]]></title><description><![CDATA[This need came up when during app deployment, needed to run some management commands without ssh-ing into the server or using the terminal.]]></description><link>https://www.happinessnwosu.com/p/call-management-commands-from-admin-interface-django</link><guid isPermaLink="false">https://www.happinessnwosu.com/p/call-management-commands-from-admin-interface-django</guid><dc:creator><![CDATA[Happiness Nwosu]]></dc:creator><pubDate>Thu, 26 Oct 2017 12:37:49 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ce32c64e-d66c-4152-904c-db8ad7e7cc73_1980x556.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This need came up when during app deployment, needed to run some management commands without ssh-ing into the server or using the terminal. Thankfully Django management command can be called anywhere using management.call_command()</p><p>This is a brief one, view code on GitHub here: <a href="https://github.com/NEbere/data-import/tree/master">https://github.com/NEbere/data-import/tree/master</a></p><p>You need to install the <strong>admin_plus</strong> package with pip, ensure your virtual environment is setup and activated if that's what you're using, in any case, ensure you have the right environment setup and running for your app before installing to avoid any issues :wink:</p><p>Install admin_plus: </p><pre><code>pip install django-adminplus</code></pre><p>Add <strong>adminplus</strong> to INSTALLED_APPS in your settings file</p><p><strong>If you&#8217;re using Django 1.7, you should also replace django.contrib.admin with django.contrib.admin.apps.SimpleAdminConfig in your installed apps, to disable the automatic auto-discovery:</strong></p><p>So update 'django.contrib.admin' to 'django.contrib.admin.apps.SimpleAdminConfig' in INSTALLED_APPS in your settings file</p><p>import <strong>AdminSitePlus</strong> in urls.py of your main package, the file where URL's from installed apps are registered <strong>hint:</strong> this is where you have the admin URL defined</p><p>In that same file, add this for the admin_plus </p><pre><code>admin.site = AdminSitePlus() admin.autodiscover() </code></pre><p>Now, head to the admin.py file in your app and call the command you want to execute.</p><pre><code>from django.contrib import admin
from .models import Movie
from django.core import management
from django.shortcuts import redirect


class MovieAdmin(admin.ModelAdmin):
    @admin.site.register_view(&#8217;import_movies_from_url&#8217;, &#8216;Import Movies from URL&#8217;)
    def import_movies_from_url(request):
        print(&#8217;import movies here&#8217;)
        try:
            management.call_command(&#8217;import_from_url&#8217;)
            message = &#8216;successfully imported data from URL&#8217;
        except Exception as ex:
            message = &#8216;Error importing from data from URL {}&#8217;.format(str(ex))
        admin.ModelAdmin.message_user(Movie, request, message)
        return redirect(&#8217;admin:index&#8217;)


admin.site.register(Movie, MovieAdmin)</code></pre><p>The command I am calling here is <strong>import_from_url</strong> and that name corresponds to the file where I defined the command (minus the file .py file extension)</p><p>This does two things: 1. Makes your Model available on the admin interface, you can create, update, delete models objects from the admin interface once your models are registered. 2. Provides a link that, when clicked, runs the management command defined to be run.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pNYr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pNYr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png 424w, https://substackcdn.com/image/fetch/$s_!pNYr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png 848w, https://substackcdn.com/image/fetch/$s_!pNYr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png 1272w, https://substackcdn.com/image/fetch/$s_!pNYr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pNYr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png" width="1980" height="556" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:556,&quot;width&quot;:1980,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Screen Shot 2017-10-26 at 1.36.02 PM&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Screen Shot 2017-10-26 at 1.36.02 PM" title="Screen Shot 2017-10-26 at 1.36.02 PM" srcset="https://substackcdn.com/image/fetch/$s_!pNYr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png 424w, https://substackcdn.com/image/fetch/$s_!pNYr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png 848w, https://substackcdn.com/image/fetch/$s_!pNYr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png 1272w, https://substackcdn.com/image/fetch/$s_!pNYr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7dad0296-2f07-4106-80c4-eea2bd0f4981_1980x556.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>More details on <a href="https://pypi.python.org/pypi/django-adminplus">admin_plus</a></p><p>Again, here is the GitHub repo with all the import scripts and sample files: <a href="https://github.com/NEbere/data-import/tree/master">https://github.com/NEbere/data-import/blob/call-management-command-from-admin/</a> </p><p>Happy coding :)</p>]]></content:encoded></item><item><title><![CDATA[Import data into database - django app]]></title><description><![CDATA[Steps to import data into your Django app]]></description><link>https://www.happinessnwosu.com/p/import-data-into-database-django-app</link><guid isPermaLink="false">https://www.happinessnwosu.com/p/import-data-into-database-django-app</guid><dc:creator><![CDATA[Happiness Nwosu]]></dc:creator><pubDate>Tue, 17 Oct 2017 17:01:22 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CP-b!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81bb4e77-51eb-4105-bf6c-75985e89f47d_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Steps to import data into your Django&nbsp;app</strong></p><p>So you have a Django app and want to load data from a URL, a CSV file or a JSON file, I got you :) First, create your models, make migrations, migrate and all that setup you have to do, but I'm sure you got all that covered :wink:</p><p><strong>See it on Github here:</strong> <a href="https://github.com/NEbere/data-import/tree/master">https://github.com/NEbere/data-import/tree/master</a></p><h4>Import from URL:</h4><p> This code gets data from a URL, be sure to have requests installed or any other HTTP library of choice.</p><pre><code>&#8220;&#8221;&#8220; Import json data from URL to Database &#8220;&#8221;&#8220;
import requests
import json
from import_data.models import Movie  # Import your model here
from django.core.management.base import BaseCommand
from datetime import datetime

IMPORT_URL = &#8216;https://jsonplaceholder.typicode.com/photos&#8217;  # URL to import from


class Command(BaseCommand):
    def import_movie(self, data):
        title = data.get(&#8217;title&#8217;, None)
        url = data.get(&#8217;url&#8217;, None)
        release_year = datetime.now()
        try:  # try and catch for saving the objects
            movie, created = Movie.objects.get_or_create(
                title=title,
                url=url,
                release_year=release_year
            )
            if created:
                movie.save()
                display_format = &#8220;\nMovie, {}, has been saved.&#8221;
                print(display_format.format(movie))
        except Exception as ex:
            print(str(ex))
            msg = &#8220;\n\nSomething went wrong saving this movie: {}\n{}&#8221;.format(title, str(ex))
            print(msg)

    def handle(self, *args, **options):
        &#8220;&#8221;&#8220;
        Makes a GET request to the API.
        &#8220;&#8221;&#8220;
        headers = {&#8217;Content-Type&#8217;: &#8216;application/json&#8217;}
        response = requests.get(
            url=IMPORT_URL,
            headers=headers,
        )
        response.raise_for_status()
        data = response.json()
        for data_object in data:
            self.import_movie(data_object) </code></pre><h4>Import from files (JSON):</h4><p> To import from a file, read the file location</p><pre><code>import os  # Add os import to the imports used above for URL

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # Define BASE_DIR or import of it is previously defined


class Command(BaseCommand):
    def import_movie_from_file(self):
        data_folder = os.path.join(BASE_DIR, &#8216;import_data&#8217;, &#8216;resources/json_file&#8217;)
        for data_file in os.listdir(data_folder):
            with open(os.path.join(data_folder, data_file), encoding=&#8217;utf-8&#8217;) as data_file:
                data = json.loads(data_file.read())
                for data_object in data:
                    title = data_object.get(&#8217;title&#8217;, None)
                    url = data_object.get(&#8217;url&#8217;, None)
                    release_year = datetime.now()
                    # Use the try and catch used above here as it&#8217;s the same model
                    try:
                        movie, created = Movie.objects.get_or_create(
                            title=title,
                            url=url,
                            release_year=release_year
                        )
                        if created:
                            movie.save()
                            display_format = &#8220;\nMovie, {}, has been saved.&#8221;
                            print(display_format.format(movie))
                    except Exception as ex:
                        print(str(ex))
                        msg = &#8220;\n\nSomething went wrong saving this movie: {}\n{}&#8221;.format(title, str(ex))
                        print(msg)

    def handle(self, *args, **options):
        &#8220;&#8221;&#8220;
        Call the function to import data
        &#8220;&#8221;&#8220;
        self.import_movie_from_file()  # call the import function in handle</code></pre><h4>Import from files (CSV):</h4><p> To import from a csv uses the same steps defined for JSON file import above with the difference been importing csv, and how the data is parsed.</p><pre><code>import csv  # Add csv import to the imports used above for JSON import

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # Define BASE_DIR or import of it is previously defined


class Command(BaseCommand):
    def import_movie_from_csv_file(self):
        data_folder = os.path.join(BASE_DIR, &#8216;import_data&#8217;, &#8216;resources/csv_file&#8217;)  # folder where csv file is stored
        for data_file in os.listdir(data_folder):
            with open(os.path.join(data_folder, data_file), encoding=&#8217;utf-8&#8217;) as data_file:
                data = csv.reader(data_file)
                next(data)  # Skip header row if present
                for data_object in data:
                    title = data_object[1]  # the value at index 0 is the ID and we dont need that here
                    url = data_object[2]
                    release_year = datetime.now()
                    # Use the try and catch used above here as it&#8217;s the same model
                    try:
                        movie, created = Movie.objects.get_or_create(
                            title=title,
                            url=url,
                            release_year=release_year
                        )
                        if created:
                            movie.save()
                            display_format = &#8220;\nMovie, {}, has been saved.&#8221;
                            print(display_format.format(movie))
                    except Exception as ex:
                        print(str(ex))
                        msg = &#8220;\n\nSomething went wrong saving this movie: {}\n{}&#8221;.format(title, str(ex))
                        print(msg)

    def handle(self, *args, **options):
        &#8220;&#8221;&#8220;
        Call the function to import data
        &#8220;&#8221;&#8220;
        self.import_movie_from_csv_file()  # call the import function in handle</code></pre><p>Run the import commands</p><pre><code>python manage.py import_from_url</code></pre><p>import_from_url is the name of the file where the command is defined without the extension, that is, .py</p><p>for more about requests <a href="http://docs.python-requests.org/en/master/">http://docs.python-requests.org/en/master/</a></p><p>Again, here is the GitHub repo with all the import scripts and sample files: <a href="https://github.com/NEbere/data-import/tree/master">https://github.com/NEbere/data-import/tree/master</a> Happy coding :smile:</p>]]></content:encoded></item><item><title><![CDATA[Bower install from a forked repository]]></title><description><![CDATA[If for any reason you need to fork a repo and want to install your forked version using Bower, follow these steps:]]></description><link>https://www.happinessnwosu.com/p/bower-install-from-a-forked-repository</link><guid isPermaLink="false">https://www.happinessnwosu.com/p/bower-install-from-a-forked-repository</guid><dc:creator><![CDATA[Happiness Nwosu]]></dc:creator><pubDate>Mon, 29 May 2017 15:17:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CP-b!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81bb4e77-51eb-4105-bf6c-75985e89f47d_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If for any reason you need to fork a repo and want to install your forked version using Bower, follow these steps:</p><ol><li><p>&nbsp;Fork the repository</p></li><li><p>Clone the forked repo on your computer</p></li><li><p>Make desired changes</p></li><li><p>Increment version number in bower.json (create one if none exists e.g. 4.0.1)</p></li><li><p>Commit and push</p></li><li><p>Create a new version tag higher than that of the forked repository. If version tag from respository is 4.0.1, increase it. e.g. 4.0.2 :</p></li></ol><pre><code>$ git tag "4.0.2"&nbsp;</code></pre><p>push tag </p><pre><code>$ git push --tag</code></pre><p>Install in your app using Bower:</p><pre><code>$ bower install https://github.com/yourName/forkedRepository.git#4.0.2</code></pre>]]></content:encoded></item><item><title><![CDATA[Update a model field - Django]]></title><description><![CDATA[I noticed a typo in a field name after running migrations, I followed these steps to update the field without loosing data.]]></description><link>https://www.happinessnwosu.com/p/update-a-model-field-django</link><guid isPermaLink="false">https://www.happinessnwosu.com/p/update-a-model-field-django</guid><dc:creator><![CDATA[Happiness Nwosu]]></dc:creator><pubDate>Wed, 03 May 2017 23:51:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CP-b!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81bb4e77-51eb-4105-bf6c-75985e89f47d_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I noticed a typo in a field name after running migrations, I followed these steps to update the field without loosing data.</p><ol><li><p>Update the filed name in the model with the desired name (taking note of the current name)</p></li><li><p>Create an empty migration. If you have previous migrations, this one must be named in such a way that it comes last in the migrations list. eg if you already have 001_users and 002_emails then this new migration needs to be named 003_new_name</p></li></ol><p> The new migration should look like this:</p><pre><code>from __future__ import unicode_literals
from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        (&#8217;django_app_name&#8217;, &#8216;last_previous_migration&#8217;),  # last_previous_migration is the migration immediately before this new empty migration without the .py extension
    ]

    operations = [
        migrations.RenameField(
            model_name=&#8217;model_name&#8217;,
            old_name=&#8217;old_filed_name&#8217;,  # that was taken note of from step one above
            new_name=&#8217;description&#8217;,  # the new/desired field name
        ),
    ]</code></pre><p>3. run migrations</p><pre><code>$ python manage.py migrate</code></pre><p>This will update the field.</p><p>Hope this saves someone some googling time</p>]]></content:encoded></item><item><title><![CDATA[virtualenv for python3]]></title><description><![CDATA[Simple steps to setup virtualenv for Python3]]></description><link>https://www.happinessnwosu.com/p/virtualenv-for-python3-ubuntu</link><guid isPermaLink="false">https://www.happinessnwosu.com/p/virtualenv-for-python3-ubuntu</guid><dc:creator><![CDATA[Happiness Nwosu]]></dc:creator><pubDate>Mon, 01 May 2017 21:02:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CP-b!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81bb4e77-51eb-4105-bf6c-75985e89f47d_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Simple steps to setup virtualenv for Python3</strong></p><p>To setup virtualenv for python3 for Django projects, create and cd into the desired folder for the Django project.</p><p>Create a folder for virtualenv, </p><pre><code>$ mkdir venv
$ cd venv </code></pre><p>Then run these&nbsp;commands worked for me in this order:</p><ul><li><p>setup virtualenv with Python in the current directory</p></li></ul><pre><code>$ virtualenv -p python3 . </code></pre><ul><li><p> activate virtualenv </p></li></ul><pre><code>$ source bin/activate </code></pre><p>At this point, checking Python version should give python3</p><ul><li><p>Install Django:</p></li></ul><pre><code>$ pip install django</code></pre><p>To see all installations run :</p><pre><code>$ pip freeze </code></pre><p>Django should be included in the list of installations</p><p>Start a Django project</p><pre><code>$ django-admin startproject --projectname</code></pre><p>cd into the created project and run:</p><pre><code>$ python manage.py runserver </code></pre><p><a href="https://www.python.org/dev/peps/pep-0405/">More on virtualenv</a></p>]]></content:encoded></item><item><title><![CDATA[Fix IOError: [Errno 2] No such file or directory error for appdirs]]></title><description><![CDATA[Appdirs is a small Python module for determining appropriate platform-specific dirs, e.g.]]></description><link>https://www.happinessnwosu.com/p/fix-ioerror-errno-2-no-such-file-or-directory-error-for-appdirs</link><guid isPermaLink="false">https://www.happinessnwosu.com/p/fix-ioerror-errno-2-no-such-file-or-directory-error-for-appdirs</guid><dc:creator><![CDATA[Happiness Nwosu]]></dc:creator><pubDate>Fri, 28 Apr 2017 09:20:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!CP-b!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81bb4e77-51eb-4105-bf6c-75985e89f47d_144x144.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Appdirs is a small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".</p><p>Github repo -&nbsp;https://github.com/ActiveState/appdirs</p><p>This error from my experience occurred when I updated my local branch from origin and ran pip install to get the latest installed packages.</p><p>pip tried to upgrade appdir but it failed for some unknown reasons, then the error came up:</p><pre><code>IOError: [Errno 2] No such file or directory: '/.local/lib/python2.7/site-packages/appdirs-1.4.0.dist-info/METADATA'</code></pre><p>What worked for me was running</p><pre><code>$ pip install appdirs --upgrade </code></pre><p>then:</p><pre><code>$ pip install -r requirements.txt --upgrade</code></pre><p>The issue was addressed here:</p><p>https://github.com/ActiveState/appdirs/issues/89</p>]]></content:encoded></item></channel></rss>