Merge pull request #107 from dcwtx/issue#86

Added api cleaning tools.
This commit is contained in:
Cameron Yick
2018-04-30 22:48:27 -04:00
committed by GitHub
4 changed files with 118 additions and 0 deletions

View File

@@ -117,3 +117,12 @@ To regenerate fixture remove it from tests/fixtures and run tests again::
$ rm tests/fixtures/NAME.yaml
$ py.test
In order for py.test to run, you will have had to create an environment variable containing a valid tiingo API key so that the test runner can make a valid api call. One way to do that is to::
$ export TIINGO_API_KEY='...insert api key here...'
However, now this api key will become embedded in the test fixture file that is created per the prior procedure. In order to remove this api key from the new test fixtures, run the following from the top level directory::
$ ./tools/api_key_tool.py

View File

@@ -0,0 +1,51 @@
#
# Test setup based on https://gist.github.com/odyniec/d4ea0959d4e0ba17a980
#
import shutil, tempfile
from os import path
from unittest import TestCase
from tools.api_key_tool import remove_api_key, has_api_key
class TestAPIKeyTools(TestCase):
def setUp(self):
self.test_dir = tempfile.mkdtemp()
f = open(path.join(self.test_dir, 'test.yaml'), 'w')
txt = '''interactions:
- request:
body: null
headers:
Accept: ['*/*']
Accept-Encoding: ['gzip, deflate']
Authorization: [Token a00000000000000000000a00000000000000000a]
Connection: [keep-alive]
Content-Type: [application/json]
User-Agent: [tiingo-python-client 0.5.0]
method: GET
uri: https://api.tiingo.com/tiingo/daily/GOOGL/prices?format=json&resampleFreq=daily
response:
body: {string: '[{"adjClose":1037.29,"adjHigh":1044.65,"adjLow":1026.05,"adjOpen":1031.47,"adjVolume":1644794,"close":1037.29,"date":"2018-04-12T00:00:00+00:00","divCash":0.0,"high":1044.65,"low":1026.05,"open":1031.47,"splitFactor":1.0,"volume":1644794}]'}
headers:
Allow: ['GET, HEAD, OPTIONS']
Content-Length: ['239']
Content-Type: [application/json]
Date: ['Fri, 13 Apr 2018 02:42:05 GMT']
Server: [nginx/1.10.1]
Vary: ['Accept, Cookie']
X-Frame-Options: [SAMEORIGIN]
status: {code: 200, message: OK}
version: 1
'''
f.write(txt)
def tearDown(self):
shutil.rmtree(self.test_dir)
def test_key_detector(self):
assert has_api_key(path.join(self.test_dir, 'test.yaml')) is True
def test_key_remover(self):
remove_api_key(path.join(self.test_dir, 'test.yaml'))
assert has_api_key(path.join(self.test_dir, 'test.yaml')) is False

0
tools/__init__.py Normal file
View File

58
tools/api_key_tool.py Executable file
View File

@@ -0,0 +1,58 @@
#!/usr/bin/env python
from __future__ import print_function
import glob
import re
import argparse
fixtures_directory = 'tests/fixtures/'
zero_api_regex = r'(\[Token )0{40}(\])'
real_api_regex = r'(\[Token ).{40}(\])'
zero_token_string = '[Token ' + 40 * '0' + ']'
def has_api_key(file):
"""
Detect whether the file contains an api key in the Token object that is not 40*'0'.
See issue #86.
:param file: path-to-file to check
:return: boolean
"""
f = open(file, 'r')
text = f.read()
if re.search(real_api_regex, text) is not None and \
re.search(zero_api_regex, text) is None:
return True
return False
def remove_api_key(file):
"""
Change the api key in the Token object to 40*'0'. See issue #86.
:param file: path-to-file to change
"""
with open(file, 'r') as fp:
text = fp.read()
text = re.sub(real_api_regex, zero_token_string, text)
with open(file, 'w') as fp:
fp.write(text)
return
def main(path):
if path[-1] != '/':
raise ValueError('Final character in path must be /.')
n_files_changed = 0
for filename in glob.glob(path+'*.yaml'):
if has_api_key(filename):
remove_api_key(filename)
n_files_changed += 1
print("Changed {} files.".format(n_files_changed))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("path", help="path to test fixtures",
nargs='?', default=fixtures_directory)
args = parser.parse_args()
main(args.path)