file_encryptor-0.2.9/0000755000076500000240000000000012464071132014634 5ustar joshstaff00000000000000file_encryptor-0.2.9/file_encryptor/0000755000076500000240000000000012464071132017660 5ustar joshstaff00000000000000file_encryptor-0.2.9/file_encryptor/__init__.py0000644000076500000240000000230412432025574021774 0ustar joshstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # The MIT License (MIT) # # Copyright (c) 2014 Storj Labs # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from file_encryptor import (convergence, key_generators) file_encryptor-0.2.9/file_encryptor/convergence.py0000644000076500000240000000757312464067731022556 0ustar joshstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # The MIT License (MIT) # # Copyright (c) 2014 Storj Labs # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from Crypto.Cipher import AES from Crypto.Util import Counter from file_encryptor.settings import CHUNK_SIZE from file_encryptor import key_generators def encrypt_file_inline(filename, passphrase): """Encrypt file inline, with an optional passphrase. If you set the passphrase to None, a default is used. This will make you vulnerable to confirmation attacks and learn-partial-information attacks. :param filename: The name of the file to encrypt. :type filename: str :param passphrase: The passphrase used to decrypt the file. :type passphrase: str or None :returns: The key required to decrypt the file. :rtype: str """ key = key_generators.key_from_file(filename, passphrase) inline_transform(filename, key) return key def decrypt_file_inline(filename, key): """Decrypt file inline with given key. The given key must be the same that was returned by encrypt_file_inline. :param filename: The name of the file to decrypt. :type filename: str :param key: The key used to decrypt the file. :type key: str """ inline_transform(filename, key) def decrypt_generator(filename, key): """Stream decrypted file with given key. The given key must be the same that was returned by encrypt_file_inline. :param filename: The name of the file to decrypt. :type filename: str :param key: The key used to decrypt the file. :type key: str :returns: A generator that streams decrypted file chunks. :rtype: generator """ for chunk, _ in iter_transform(filename, key): yield chunk def inline_transform(filename, key): """Encrypt file inline. Encrypts a given file with the given key, and replaces it directly without any extra space requirement. :param filename: The name of the file to encrypt. :type filename: str :param key: The key used to encrypt the file. :type key: str """ pos = 0 for chunk, fp in iter_transform(filename, key): fp.seek(pos) fp.write(chunk) fp.flush() pos = fp.tell() def iter_transform(filename, key): """Generate encrypted file with given key. This generator function reads the file in chunks and encrypts them using AES-CTR, with the specified key. :param filename: The name of the file to encrypt. :type filename: str :param key: The key used to encrypt the file. :type key: str :returns: A generator that produces encrypted file chunks. :rtype: generator """ # We are not specifying the IV here. aes = AES.new(key, AES.MODE_CTR, counter=Counter.new(128)) with open(filename, 'rb+') as f: for chunk in iter(lambda: f.read(CHUNK_SIZE), b''): yield aes.encrypt(chunk), f file_encryptor-0.2.9/file_encryptor/key_generators.py0000644000076500000240000000552312464070004023255 0ustar joshstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # The MIT License (MIT) # # Copyright (c) 2014 Storj Labs # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import hashlib import hmac from file_encryptor.settings import CHUNK_SIZE, DEFAULT_HMAC_PASSPHRASE def sha256_file(path): """Calculate sha256 hex digest of a file. :param path: The path of the file you are calculating the digest of. :type path: str :returns: The sha256 hex digest of the specified file. :rtype: builtin_function_or_method """ h = hashlib.sha256() with open(path, 'rb') as f: for chunk in iter(lambda: f.read(CHUNK_SIZE), b''): h.update(chunk) return h.hexdigest() def key_from_file(filename, passphrase): """Calculate convergent encryption key. This takes a filename and an optional passphrase. If no passphrase is given, a default is used. Using the default passphrase means you will be vulnerable to confirmation attacks and learn-partial-information attacks. :param filename: The filename you want to create a key for. :type filename: str :param passphrase: The passphrase you want to use to encrypt the file. :type passphrase: str or None :returns: A convergent encryption key. :rtype: str """ hexdigest = sha256_file(filename) if passphrase is None: passphrase = DEFAULT_HMAC_PASSPHRASE return keyed_hash(hexdigest, passphrase) def keyed_hash(digest, passphrase): """Calculate a HMAC/keyed hash. :param digest: Digest used to create hash. :type digest: str :param passphrase: Passphrase used to generate the hash. :type passphrase: str :returns: HMAC/keyed hash. :rtype: str """ encodedPassphrase = passphrase.encode() encodedDigest = digest.encode() return hmac.new(encodedPassphrase, encodedDigest, hashlib.sha256).digest() file_encryptor-0.2.9/file_encryptor/settings.py0000644000076500000240000000253512431776077022115 0ustar joshstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # The MIT License (MIT) # # Copyright (c) 2014 Storj Labs # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # The default chunk size for files. # The current value is equivalent to 16 kb. CHUNK_SIZE = 2**14 # The default HMAC passphrase for encrypting files. DEFAULT_HMAC_PASSPHRASE = 'Something old, something new.' file_encryptor-0.2.9/file_encryptor.egg-info/0000755000076500000240000000000012464071132021352 5ustar joshstaff00000000000000file_encryptor-0.2.9/file_encryptor.egg-info/dependency_links.txt0000644000076500000240000000000112464071132025420 0ustar joshstaff00000000000000 file_encryptor-0.2.9/file_encryptor.egg-info/PKG-INFO0000644000076500000240000001123012464071132022444 0ustar joshstaff00000000000000Metadata-Version: 1.1 Name: file-encryptor Version: 0.2.9 Summary: Tool for convergently encrypting files used by MetaDisk. Home-page: https://github.com/Storj/file-encryptor Author: Storj Labs Author-email: hello@storj.io License: The MIT License (MIT) Copyright (c) 2014 Storj Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Download-URL: https://github.com/storj/file-encryptor/tarball/0.2.9 Description: File Encryptor ============== |Build Status| |Coverage Status| |PyPI version| This is a library used by MetaDisk to convergently encrypt and decrypt files. It contains helper methods to encrypt and decrypt files inline (without using extra space) and to stream decryption. Installation ------------ You can easily install ``file-encryptor`` using pip: :: pip install file_encryptor Usage ----- Here’s an example to encrypt a file inline using convergent encryption: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", None) You can also specify a passphrase: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", "rainbow dinosaur secret") To decrypt a file inline, you need the key that was returned by the encrypt method: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", "rainbow dinosaur secret") convergence.decrypt_inline_file("/path/to/file", key) The reason why you cannot use the passphrase directly is because the key is derived from both the passphrase and the SHA-256 of the original file. For streaming applications, you can decrypt a file with a generator: .. code:: python for chunk in convergence.decrypt_generator("/path/to/file", key): do_something_with_chunk(chunk) Cryptoconcerns -------------- The key generation mechanism is the following: .. code:: python key = HMAC-SHA256(passphrase, hex(SHA256(file-contents))) If no passphrase is given, a default is used. The file itself is encrypted using AES128-CTR, from pycrypto. We’re not specifying any IV, thinking that for convergent encryption that is the right thing to do. Testing ------- To run tests, execute the following command in the project root: :: python setup.py test -a "--doctest-modules --pep8 -v tests/" To run tests with detailed coverage output, execute: :: coverage run setup.py test -a "--doctest-modules --pep8 -v tests/" coverage report -m --include="file_encryptor/*" .. |Build Status| image:: https://travis-ci.org/Storj/file-encryptor.svg :target: https://travis-ci.org/Storj/file-encryptor .. |Coverage Status| image:: https://coveralls.io/repos/Storj/file-encryptor/badge.png?branch=master :target: https://coveralls.io/r/Storj/file-encryptor?branch=master .. |PyPI version| image:: https://badge.fury.io/py/file_encryptor.svg :target: http://badge.fury.io/py/file_encryptor Keywords: storj,metadisk,convergent encryption Platform: UNKNOWN file_encryptor-0.2.9/file_encryptor.egg-info/requires.txt0000644000076500000240000000002012464071132023742 0ustar joshstaff00000000000000pycrypto>=2.6.1 file_encryptor-0.2.9/file_encryptor.egg-info/SOURCES.txt0000644000076500000240000000054312464071132023240 0ustar joshstaff00000000000000LICENSE MANIFEST.in README.rst setup.cfg setup.py file_encryptor/__init__.py file_encryptor/convergence.py file_encryptor/key_generators.py file_encryptor/settings.py file_encryptor.egg-info/PKG-INFO file_encryptor.egg-info/SOURCES.txt file_encryptor.egg-info/dependency_links.txt file_encryptor.egg-info/requires.txt file_encryptor.egg-info/top_level.txtfile_encryptor-0.2.9/file_encryptor.egg-info/top_level.txt0000644000076500000240000000001712464071132024102 0ustar joshstaff00000000000000file_encryptor file_encryptor-0.2.9/LICENSE0000644000076500000240000000206412403730242015640 0ustar joshstaff00000000000000The MIT License (MIT) Copyright (c) 2014 Storj Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.file_encryptor-0.2.9/MANIFEST.in0000664000076500000240000000001712437572754016412 0ustar joshstaff00000000000000include LICENSEfile_encryptor-0.2.9/PKG-INFO0000644000076500000240000001123012464071132015726 0ustar joshstaff00000000000000Metadata-Version: 1.1 Name: file_encryptor Version: 0.2.9 Summary: Tool for convergently encrypting files used by MetaDisk. Home-page: https://github.com/Storj/file-encryptor Author: Storj Labs Author-email: hello@storj.io License: The MIT License (MIT) Copyright (c) 2014 Storj Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Download-URL: https://github.com/storj/file-encryptor/tarball/0.2.9 Description: File Encryptor ============== |Build Status| |Coverage Status| |PyPI version| This is a library used by MetaDisk to convergently encrypt and decrypt files. It contains helper methods to encrypt and decrypt files inline (without using extra space) and to stream decryption. Installation ------------ You can easily install ``file-encryptor`` using pip: :: pip install file_encryptor Usage ----- Here’s an example to encrypt a file inline using convergent encryption: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", None) You can also specify a passphrase: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", "rainbow dinosaur secret") To decrypt a file inline, you need the key that was returned by the encrypt method: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", "rainbow dinosaur secret") convergence.decrypt_inline_file("/path/to/file", key) The reason why you cannot use the passphrase directly is because the key is derived from both the passphrase and the SHA-256 of the original file. For streaming applications, you can decrypt a file with a generator: .. code:: python for chunk in convergence.decrypt_generator("/path/to/file", key): do_something_with_chunk(chunk) Cryptoconcerns -------------- The key generation mechanism is the following: .. code:: python key = HMAC-SHA256(passphrase, hex(SHA256(file-contents))) If no passphrase is given, a default is used. The file itself is encrypted using AES128-CTR, from pycrypto. We’re not specifying any IV, thinking that for convergent encryption that is the right thing to do. Testing ------- To run tests, execute the following command in the project root: :: python setup.py test -a "--doctest-modules --pep8 -v tests/" To run tests with detailed coverage output, execute: :: coverage run setup.py test -a "--doctest-modules --pep8 -v tests/" coverage report -m --include="file_encryptor/*" .. |Build Status| image:: https://travis-ci.org/Storj/file-encryptor.svg :target: https://travis-ci.org/Storj/file-encryptor .. |Coverage Status| image:: https://coveralls.io/repos/Storj/file-encryptor/badge.png?branch=master :target: https://coveralls.io/r/Storj/file-encryptor?branch=master .. |PyPI version| image:: https://badge.fury.io/py/file_encryptor.svg :target: http://badge.fury.io/py/file_encryptor Keywords: storj,metadisk,convergent encryption Platform: UNKNOWN file_encryptor-0.2.9/README.rst0000644000076500000240000000476012437147621016341 0ustar joshstaff00000000000000File Encryptor ============== |Build Status| |Coverage Status| |PyPI version| This is a library used by MetaDisk to convergently encrypt and decrypt files. It contains helper methods to encrypt and decrypt files inline (without using extra space) and to stream decryption. Installation ------------ You can easily install ``file-encryptor`` using pip: :: pip install file_encryptor Usage ----- Here’s an example to encrypt a file inline using convergent encryption: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", None) You can also specify a passphrase: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", "rainbow dinosaur secret") To decrypt a file inline, you need the key that was returned by the encrypt method: .. code:: python import file_encryptor.convergence key = convergence.encrypt_inline_file("/path/to/file", "rainbow dinosaur secret") convergence.decrypt_inline_file("/path/to/file", key) The reason why you cannot use the passphrase directly is because the key is derived from both the passphrase and the SHA-256 of the original file. For streaming applications, you can decrypt a file with a generator: .. code:: python for chunk in convergence.decrypt_generator("/path/to/file", key): do_something_with_chunk(chunk) Cryptoconcerns -------------- The key generation mechanism is the following: .. code:: python key = HMAC-SHA256(passphrase, hex(SHA256(file-contents))) If no passphrase is given, a default is used. The file itself is encrypted using AES128-CTR, from pycrypto. We’re not specifying any IV, thinking that for convergent encryption that is the right thing to do. Testing ------- To run tests, execute the following command in the project root: :: python setup.py test -a "--doctest-modules --pep8 -v tests/" To run tests with detailed coverage output, execute: :: coverage run setup.py test -a "--doctest-modules --pep8 -v tests/" coverage report -m --include="file_encryptor/*" .. |Build Status| image:: https://travis-ci.org/Storj/file-encryptor.svg :target: https://travis-ci.org/Storj/file-encryptor .. |Coverage Status| image:: https://coveralls.io/repos/Storj/file-encryptor/badge.png?branch=master :target: https://coveralls.io/r/Storj/file-encryptor?branch=master .. |PyPI version| image:: https://badge.fury.io/py/file_encryptor.svg :target: http://badge.fury.io/py/file_encryptorfile_encryptor-0.2.9/setup.cfg0000644000076500000240000000033412464071132016455 0ustar joshstaff00000000000000[metadata] description-file = README.rst [build_sphinx] source-dir = docs build-dir = docs/_build all_files = 1 [upload_sphinx] upload-dir = docs/_build/html [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 file_encryptor-0.2.9/setup.py0000644000076500000240000000507512464071102016352 0ustar joshstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # The MIT License (MIT) # # Copyright (c) 2014-2015 Storj Labs # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from setuptools import setup from setuptools.command.test import test as TestCommand LONG_DESCRIPTION = open('README.rst').read() VERSION = '0.2.9' install_requirements = [ 'pycrypto>=2.6.1' ] test_requirements = [ 'pytest', 'pytest-pep8', 'pytest-cache', 'coveralls' ] class PyTest(TestCommand): user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")] def initialize_options(self): TestCommand.initialize_options(self) self.pytest_args = [] def finalize_options(self): TestCommand.finalize_options(self) self.test_args = [] self.test_suite = True def run_tests(self): # Import PyTest here because outside, the eggs are not loaded. import pytest import sys errno = pytest.main(self.pytest_args) sys.exit(errno) setup( name='file_encryptor', version=VERSION, url='https://github.com/Storj/file-encryptor', download_url='https://github.com/storj/file-encryptor/tarball/' + VERSION, license=open('LICENSE').read(), author='Storj Labs', author_email='hello@storj.io', description='Tool for convergently encrypting files used by MetaDisk.', long_description=LONG_DESCRIPTION, packages=['file_encryptor'], cmdclass={'test': PyTest}, install_requires=install_requirements, tests_require=test_requirements, keywords=['storj', 'metadisk', 'convergent encryption'] )