mardi 26 janvier 2016

Python Torando No such file or directory:

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!




Aucun commentaire:

Enregistrer un commentaire