Skip to content

Commit 1f5edc9

Browse files
committed
Merge pull request #121 from plotly/andrew-lock-file-read-write
Add a lock for folks using threading. Mucho helpful.
2 parents 8978802 + 2e25dba commit 1f5edc9

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

Diff for: plotly/tools.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,8 @@ def check_file_permissions():
7272
def ensure_local_plotly_files():
7373
"""Ensure that filesystem is setup/filled out in a valid way"""
7474
if _file_permissions:
75-
if not os.path.isdir(PLOTLY_DIR):
76-
os.mkdir(PLOTLY_DIR)
7775
for fn in [CREDENTIALS_FILE, CONFIG_FILE]:
76+
utils.ensure_file_exists(fn)
7877
contents = utils.load_json_dict(fn)
7978
for key, val in list(_FILE_CONTENT[fn].items()):
8079
# TODO: removed type checking below, may want to revisit
@@ -134,8 +133,7 @@ def get_credentials_file(*args):
134133

135134
def reset_credentials_file():
136135
ensure_local_plotly_files() # make sure what's there is OK
137-
f = open(CREDENTIALS_FILE, 'w')
138-
f.close()
136+
utils.save_json_dict(CREDENTIALS_FILE, {})
139137
ensure_local_plotly_files() # put the defaults back
140138

141139

Diff for: plotly/utils.py

+30-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
import json
1010
import os.path
1111
import sys
12+
import threading
13+
14+
### incase people are using threadig, we lock file reads
15+
lock = threading.Lock()
1216

1317

1418
### general file setup tools ###
@@ -17,13 +21,15 @@ def load_json_dict(filename, *args):
1721
"""Checks if file exists. Returns {} if something fails."""
1822
data = {}
1923
if os.path.exists(filename):
24+
lock.acquire()
2025
with open(filename, "r") as f:
2126
try:
2227
data = json.load(f)
2328
if not isinstance(data, dict):
2429
data = {}
2530
except:
26-
pass # TODO: issue a warning and bubble it up
31+
data = {} # TODO: issue a warning and bubble it up
32+
lock.release()
2733
if args:
2834
d = dict()
2935
for key in args:
@@ -36,13 +42,32 @@ def load_json_dict(filename, *args):
3642

3743

3844
def save_json_dict(filename, json_dict):
39-
"""Will error if filename is not appropriate, but it's checked elsewhere.
40-
"""
45+
"""Save json to file. Error if path DNE, not a dict, or invalid json."""
4146
if isinstance(json_dict, dict):
47+
# this will raise a TypeError if something goes wrong
48+
json_string = json.dumps(json_dict, indent=4)
49+
lock.acquire()
4250
with open(filename, "w") as f:
43-
f.write(json.dumps(json_dict, indent=4))
51+
f.write(json_string)
52+
lock.release()
4453
else:
45-
raise TypeError("json_dict was not a dictionay. couldn't save.")
54+
raise TypeError("json_dict was not a dictionary. not saving.")
55+
56+
57+
def ensure_file_exists(filename):
58+
"""Given a valid filename, make sure it exists (will create if DNE)."""
59+
if not os.path.exists(filename):
60+
head, tail = os.path.split(filename)
61+
ensure_dir_exists(head)
62+
with open(filename, 'w') as f:
63+
pass # just create the file
64+
65+
66+
def ensure_dir_exists(directory):
67+
"""Given a valid directory path, make sure it exists."""
68+
if dir:
69+
if not os.path.isdir(directory):
70+
os.makedirs(directory)
4671

4772

4873
### Custom JSON encoders ###

0 commit comments

Comments
 (0)