diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5cafb32204ae7034528820e802b071f72898b49b
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,22 @@
+beat.core
+django
+django-activity-stream
+django-guardian
+django-jsonfield
+django-post_office
+django-rest-swagger
+djangorestframework
+docopt
+docutils
+jinja2
+matplotlib
+nose
+psutil
+psycopg2-binary
+pytz
+setuptools
+simplejson
+sphinx
+sphinx-rtd-theme
+sphinxcontrib-httpdomain
+sphinxcontrib-programoutput
diff --git a/setup.py b/setup.py
index e348890803c7bef007515aecba57c9563458f326..578eee3bdbff2fde1d7088956e021af8fc02a9d5 100755
--- a/setup.py
+++ b/setup.py
@@ -26,7 +26,10 @@
 ###############################################################################
 
 from setuptools import setup, find_packages
-from io import open
+
+def load_requirements(f):
+  retval = [str(k.strip()) for k in open(f, 'rt')]
+  return [k for k in retval if k and k[0] not in ('#', '-')]
 
 # The only thing we do in this file is to call the setup() function with all
 # parameters that define our package.
@@ -45,35 +48,7 @@ setup(
     packages=find_packages(),
     include_package_data=True,
     zip_safe=False,
-
-    namespace_packages=[
-        "beat",
-    ],
-
-    install_requires=[
-        "beat.core",
-        "django",
-        "django-activity-stream",
-        "django-jsonfield",
-        "django-guardian",
-        "djangorestframework",
-        "django-rest-swagger",
-        "django-post_office",
-        "docopt",
-        "docutils",
-        "Jinja2",
-        "nose",
-        "psycopg2-binary",
-        "pytz",
-        "psutil",
-        "setuptools",
-        "simplejson",
-        "sphinx",
-        "sphinxcontrib-programoutput",
-        "sphinxcontrib-httpdomain",
-        "sphinx-rtd-theme",
-        "matplotlib",
-    ],
+    install_requires=load_requirements('requirements.txt'),
 
     classifiers = [
       'Development Status :: 5 - Production/Stable',