diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ca57ec4d..f8ce6a5c6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+### 1.4.2
+  * f2230b6 - chore: Bundle Ruby standalones into dist artifact. (#256) (Taj Pereira, Sun Aug 22 19:53:53 2021 +0930)
+  * e370786 - chore: Releasing version 1.4.1 (Elliott Murray, Tue Aug 17 18:55:53 2021 +0100)
+  * 7dc8864 - fix: make uvicorn versions over 0.14 (#255) (Elliott Murray, Tue Aug 17 18:51:52 2021 +0100)
+  * da49cd7 - chore: Releasing version 1.4.0 (Elliott Murray, Sat Aug 7 10:17:26 2021 +0100)
+  * 0089937 - fix: issue originating from snyk with requests and urllib (#252) (Elliott Murray, Sat Jul 31 12:46:15 2021 +0100)
+  * 903371b - feat: added support for message provider (#251) (Fabio Pulvirenti, Sat Jul 31 13:24:19 2021 +0200)
+  * 2c81029 - chore(snyk): update fastapi (#239) (Elliott Murray, Fri Jun 11 09:12:38 2021 +0100)
+### 1.4.1
+  * 7dc8864 - fix: make uvicorn versions over 0.14 (#255) (Elliott Murray, Tue Aug 17 18:51:52 2021 +0100)
+### 1.4.0
+  * 0089937 - fix: issue originating from snyk with requests and urllib (#252) (Elliott Murray, Sat Jul 31 12:46:15 2021 +0100)
+  * 903371b - feat: added support for message provider (#251) (Fabio Pulvirenti, Sat Jul 31 13:24:19 2021 +0200)
+  * 2c81029 - chore(snyk): update fastapi (#239) (Elliott Murray, Fri Jun 11 09:12:38 2021 +0100)
 ### 1.3.9
   * 98d9a4b - chore(ruby): update ruby standalen (#233) (Elliott Murray, Thu May 13 20:21:10 2021 +0100)
   * 657e770 - fix: change default from empty string to empty list (#235) (Vasile Tofan, Thu May 13 22:20:47 2021 +0300)
diff --git a/MANIFEST.in b/MANIFEST.in
index 3bbaceac4..160e1d2d4 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,6 +1,6 @@
 include LICENSE
 include *.txt
 include *.md
+include pact/bin/*
 prune pact/test
-prune pact/bin
 prune e2e
diff --git a/README.md b/README.md
index b1c3d1587..2a73c6575 100644
--- a/README.md
+++ b/README.md
@@ -437,7 +437,7 @@ To setup a development environment:
 1. If you want to run tests for all Python versions, install 2.7, 3.3, 3.4, 3.5, and 3.6 from source or using a tool like [pyenv]
 2. Its recommended to create a Python [virtualenv] for the project
 
-The setup the environment, run tests, and package the application, run:
+To setup the environment, run tests, and package the application, run:
 `make release`
 
 If you are just interested in packaging pact-python so you can install it using pip:
@@ -449,6 +449,15 @@ From there you can use pip to install it:
 
 `pip install ./dist/pact-python-N.N.N.tar.gz`
 
+## Offline Installation of Standalone Packages
+
+Although all Ruby standalone applications are predownloaded into the wheel artifact, it may be useful, for development, purposes to install custom Ruby binaries. In which case, use the `bin-path` flag.
+```
+pip install pact-python --bin-path=/absolute/path/to/folder/containing/pact/binaries/for/your/os
+```
+
+Pact binaries can be found at [Pact Ruby Releases](https://github.com/pact-foundation/pact-ruby-standalone/releases).
+
 ## Testing
 
 This project has unit and end to end tests, which can both be run from make:
diff --git a/pact/__version__.py b/pact/__version__.py
index b24a26504..9a9109875 100644
--- a/pact/__version__.py
+++ b/pact/__version__.py
@@ -1,3 +1,3 @@
 """Pact version info."""
 
-__version__ = '1.3.9'
+__version__ = '1.4.2'
diff --git a/setup.py b/setup.py
index 5ae1bdb87..5ff027fcf 100644
--- a/setup.py
+++ b/setup.py
@@ -2,6 +2,7 @@
 
 import os
 import platform
+import shutil
 import sys
 import tarfile
 
@@ -10,11 +11,15 @@
 from setuptools import setup
 from setuptools.command.develop import develop
 from setuptools.command.install import install
+from distutils.command.sdist import sdist as sdist_orig
 
 
 IS_64 = sys.maxsize > 2 ** 32
 PACT_STANDALONE_VERSION = '1.88.51'
-
+PACT_STANDALONE_SUFFIXES = ['osx.tar.gz',
+                            'linux-x86_64.tar.gz',
+                            'linux-x86.tar.gz',
+                            'win32.zip']
 
 here = os.path.abspath(os.path.dirname(__file__))
 
@@ -22,6 +27,23 @@
 with open(os.path.join(here, "pact", "__version__.py")) as f:
     exec(f.read(), about)
 
+class sdist(sdist_orig):
+    """
+    Subclass sdist so that we can download all standalone ruby applications
+    into ./pact/bin so our users receive all the binaries on pip install.
+    """
+    def run(self):
+        package_bin_path = os.path.join(os.path.dirname(__file__), 'pact', 'bin')
+
+        if os.path.exists(package_bin_path):
+            shutil.rmtree(package_bin_path, ignore_errors=True)
+        os.mkdir(package_bin_path)
+
+        for suffix in PACT_STANDALONE_SUFFIXES:
+            filename = ('pact-{version}-{suffix}').format(version=PACT_STANDALONE_VERSION, suffix=suffix)
+            download_ruby_app_binary(package_bin_path, filename, suffix)
+        super().run()
+
 
 class PactPythonDevelopCommand(develop):
     """
@@ -35,11 +57,11 @@ class PactPythonDevelopCommand(develop):
     def run(self):
         """Install ruby command."""
         develop.run(self)
-        bin_path = os.path.join(os.path.dirname(__file__), 'pact', 'bin')
-        if not os.path.exists(bin_path):
-            os.mkdir(bin_path)
+        package_bin_path = os.path.join(os.path.dirname(__file__), 'pact', 'bin')
+        if not os.path.exists(package_bin_path):
+            os.mkdir(package_bin_path)
 
-        install_ruby_app(bin_path)
+        install_ruby_app(package_bin_path, download_bin_path=None)
 
 
 class PactPythonInstallCommand(install):
@@ -48,25 +70,66 @@ class PactPythonInstallCommand(install):
 
     Installs the Python package and unpacks the platform appropriate version
     of the Ruby mock service and provider verifier.
+
+    User Options:
+        --bin-path  An absolute folder path containing predownloaded pact binaries
+                    that should be used instead of fetching from the internet.
     """
 
+    user_options = install.user_options + [('bin-path=', None, None)]
+
+    def initialize_options(self):
+        """Load our preconfigured options"""
+        install.initialize_options(self)
+        self.bin_path = None
+
+    def finalize_options(self):
+        """Load provided CLI arguments into our options"""
+        install.finalize_options(self)
+
     def run(self):
         """Install python binary."""
         install.run(self)
-        bin_path = os.path.join(self.install_lib, 'pact', 'bin')
-        os.mkdir(bin_path)
-        install_ruby_app(bin_path)
+        package_bin_path = os.path.join(self.install_lib, 'pact', 'bin')
+        if not os.path.exists(package_bin_path):
+            os.mkdir(package_bin_path)
+        install_ruby_app(package_bin_path, self.bin_path)
 
 
-def install_ruby_app(bin_path):
+def install_ruby_app(package_bin_path, download_bin_path):
     """
-    Download a Ruby application and install it for use.
+    Installs the ruby standalone application for this OS.
 
-    :param bin_path: The path where binaries should be installed.
+    :param package_bin_path: The path where we want our pact binaries unarchived.
+    :param download_bin_path: An optional path containing pre-downloaded pact binaries.
+    """
+
+    binary = ruby_app_binary()
+    if download_bin_path is None:
+        download_bin_path = package_bin_path
+
+    path = os.path.join(download_bin_path, binary['filename'])
+
+    if os.path.isfile(path) is True:
+        extract_ruby_app_binary(download_bin_path, package_bin_path, binary['filename'])
+    else:
+        if download_bin_path is not None:
+            if os.path.isfile(path) is not True:
+                raise RuntimeError('Could not find {} binary.'.format(path))
+            extract_ruby_app_binary(download_bin_path, package_bin_path, binary['filename'])
+        else:
+            download_ruby_app_binary(package_bin_path, binary['filename'], binary['suffix'])
+            extract_ruby_app_binary(package_bin_path, package_bin_path, binary['filename'])
+
+def ruby_app_binary():
+    """
+    Determines the ruby app binary required for this OS.
+
+    :return A dictionary of type {'filename': string, 'version': string, 'suffix': string }
     """
     target_platform = platform.platform().lower()
-    uri = ('https://github.com/pact-foundation/pact-ruby-standalone/releases'
-           '/download/v{version}/pact-{version}-{suffix}')
+
+    binary = ('pact-{version}-{suffix}')
 
     if 'darwin' in target_platform or 'macos' in target_platform:
         suffix = 'osx.tar.gz'
@@ -82,12 +145,26 @@ def install_ruby_app(bin_path):
             platform.platform())
         raise Exception(msg)
 
+    binary = binary.format(version=PACT_STANDALONE_VERSION, suffix=suffix)
+    return {'filename': binary, 'version': PACT_STANDALONE_VERSION, 'suffix': suffix}
+
+def download_ruby_app_binary(path_to_download_to, filename, suffix):
+    """
+    Downloads `binary` into `path_to_download_to`.
+
+    :param path_to_download_to: The path where binaries should be downloaded.
+    :param filename: The filename that should be installed.
+    :param suffix: The suffix of the standalone app to install.
+    """
+    uri = ('https://github.com/pact-foundation/pact-ruby-standalone/releases'
+           '/download/v{version}/pact-{version}-{suffix}')
+
     if sys.version_info.major == 2:
         from urllib import urlopen
     else:
         from urllib.request import urlopen
 
-    path = os.path.join(bin_path, suffix)
+    path = os.path.join(path_to_download_to, filename)
     resp = urlopen(uri.format(version=PACT_STANDALONE_VERSION, suffix=suffix))
     with open(path, 'wb') as f:
         if resp.code == 200:
@@ -97,12 +174,21 @@ def install_ruby_app(bin_path):
                 'Received HTTP {} when downloading {}'.format(
                     resp.code, resp.url))
 
+def extract_ruby_app_binary(source, destination, binary):
+    """
+    Extracts the ruby app binary from `source` into `destination`.
+
+    :param source: The location of the binary to unarchive.
+    :param destination: The location to unarchive to.
+    :param binary: The binary that needs to be unarchived.
+    """
+    path = os.path.join(source, binary)
     if 'windows' in platform.platform().lower():
         with ZipFile(path) as f:
-            f.extractall(bin_path)
+            f.extractall(destination)
     else:
         with tarfile.open(path) as f:
-            f.extractall(bin_path)
+            f.extractall(destination)
 
 
 def read(filename):
@@ -117,16 +203,17 @@ def read(filename):
     'psutil>=2.0.0',
     'requests>=2.5.0',
     'six>=1.9.0',
-    'fastapi==0.67.0',
+    'fastapi>=0.67.0',
     'urllib3>=1.26.5',
-    'uvicorn==0.14.0'
+    'uvicorn>=0.14.0'
 ]
 
 if __name__ == '__main__':
     setup(
         cmdclass={
             'develop': PactPythonDevelopCommand,
-            'install': PactPythonInstallCommand},
+            'install': PactPythonInstallCommand,
+            'sdist': sdist},
         name='pact-python',
         version=about['__version__'],
         description=(
