Reputation: 1036
I am using Tornado to create a website using python. I have a JSON file that contains a list of dictionaries (or not if the app is running for the first time) and I am trying to insert a new dictionary to it after running a query to the DB.
In summary, my problem is that I run a code that inserts the data to my json file and works perfectly when I test it by running my python file and calling the method at the end of it. However, when I run my Tornado server and call the method in my Tornado request handler by clicking un a button, I get this error "IOError: [Errno 2] No such file or directory". I am new to Tornado so I don't have a clue of what the problem may be. Here are the details:
My project has the following structure:
Project/
|-- connector/
| |-- DBConnector.py
|
|-- data/
| |-- history.json (does not exist when the app runs for the 1st time)
|
|-- web
| |-- css
| |-- fonts
| |-- js
| |-- views
|-- server.py
My history.json file can be empty or can contain a list of dictionaries as follows:
[
{"a":"a", "b":"b", "c":"c", "d":"d"},
{"e":"e", "f":"f", "g":"g", "h":"h"}
]
Now, I have the following method in my MyMySQLConnection class that is contained in my DBConnector.py file. This method executes a mysql select and insert query and then appends a dictionary that contains the selected values to my history.json JSON file:
class MyMySQLConnection():
def insert_history_data(self, s_id):
#MySQL Select occurs by s_id and result is used for insertion
#MySQL insert occurs. j, k ,l, m are the same values as inserted.
insert_dict = {"j":"j", "k":"k", "l":"l", "m":"m"
if(os.path.isfile("../data/history.json")):
try:
with open("../data/history.json", "r") as f:
json_file = json.load(f)
json_file.append(insert_dict)
f.close()
with open('../data/history.json', 'w') as f:
f.write(json.dumps(json_file, indent=4))
return True
except:
print "Something went wrong (history.json existed)."
return False
else:
try:
f = file("../data/history.json", "w")
f.close()
with open('../data/history.json', 'a+') as outfile:
arr = []
arr.append(insert_dict)
json.dump(arr, outfile, indent=4)
return True
except:
print "Something went wrong.(history.json did not existed)"
return False
At the end of my DBConnection file, I have the following code (I didn't included the DB connection methods or queries as I tested DB methods and they work fine):
my_con = MyMySQLConnection("user", "pwd")
result = my_con.insert_history_data()
So, when I run DBConnector.py as a python script, that is I simply use the run option over the DBConnector.py in my PyCharm IDE, It works perfectly fine. The first time I run it, the history.json file is created in the "'../data/history.json'" directory and the first dictionary is appended to it. The next times I run it, each dictionary is appended to the history.json file that exists in the '../data/history.json' path.
However, when I run my server and call the method by clicking a button in my web interface, I get the following error (I had to remove the try: except: tags in my code to get the error):
IOError: [Errno 2] No such file or directory: '../data/history.json'
The error is generated by the codeline that contains the line:
f = file("../data/history.json", "w")
When the file exists (I created it by running the DBConnector.py python file) and I call the method, I get the same error in the same line (so, the path should be the problem).
So, why I am getting this error if the code works perfectly fine by running the DBConnector.py class as a python script? My only guess is that Tornado has problems finding the path "../data/history.json" when calling my method on the MyMySQLConnector class instantiated in my Tornado server Handler, however, this does not make any sense to me as I all my files are contained in the same project.
This is how I Init my Tornado server:
if __name__ == "__main__":
logging.log(logging.INFO, 'Deploying service...')
app = tornado.web.Application([
(r"/", MainHandler),
(r"/add-translate", AddTransHandler),
(r"/static/(.*)", tornado.web.StaticFileHandler,{"path": settings["static_path"]})
], **settings)
app.listen("8888")
This are my settings:
settings = {"template_path": os.path.dirname(__file__),
"static_path": os.path.join(os.path.dirname(__file__),"web"),
"debug": True
}
And this is the Handler I am using where the :
class AddTransHandler(tornado.web.RequestHandler):
def get(self):
s_id= self.get_argument("s_id")
#my_con is a MyMySQLConnection instance that another method initializes.
global my_con
answer = []
if my_con is None:
answer.append([{"connection": "False"}])
else:
result = my_con.insert_history_data(s_id)
answer.append(result)
logging.log(logging.INFO, "Sending insert result...")
self.write(json.dumps(answer))
Thanks!
Upvotes: 0
Views: 1538
Reputation: 90
you should use absolute paths in your script, because when you Run the service, all the paths are relative to the server file.
So you could use the following path with OS library:
os.path.join(os.path.dirname(__file__),"../data/history.json")
Hope that helps!
Upvotes: 0
Reputation: 332
From the looks of the package structure, you're trying to grab history.json
from an upper directory outside the Project
directory.
f = file("data/history.json", "w")
Python will grab files like this from within the code's relative directory.
Either this method or the other one should work.
Upvotes: 0
Reputation: 2817
Try to use full path for your file. Add this to main directory:
CURRENT_ROOT = os.path.abspath(os.path.dirname(__file__))
And this to file where you use file('name_file'):
file_path = os.path.join(PROJECT_ROOT, 'data', 'history.json')
Upvotes: 1