tornadoweb / tornadoweb/tornado

autoreload: Pre-reload file change hook (syntax checking, etc)

Open
#1,239 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autoreload
Dominant language
Python
Stars
22.2k
Forks
5.6k
Avg merge
3h 42m
Merged PRs (30d)
16

Description

not sure how to add this to code. maybe someone to add this to project.
this is the first time i wrote python

import os
import tornado.ioloop
import tornado.web
import tornado.autoreload
import time
from datetime import datetime
import json

compileerr=""

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        global compileerr
        if compileerr!="":
            self.write("<pre>Compile error:\n"+compileerr);
            #self.render("index.html")
        else:
            try:
                with open(os.path.join(os.path.dirname(__file__), 'index.html')) as f:
                    self.write(f.read())
            except IOError as e:
                self.write("404: Not Found")

es_empty_result={ "hits": {"hits": [], "total": 0, "max_score": None}, "_shards": {"successful": 5, "failed": 0, "total": 5 }, "took": 3, "timed_out": False }

#some apis
class List1Handler(tornado.web.RequestHandler):
    def get(self):
        global es_empty_result
        id=self.get_argument("id", default=None, strip=False)
        user=self.get_argument("user", default=None, strip=False)
        self.write(json.dumps(es_empty_result, sort_keys = False, indent = 4))

class List2Handler(tornado.web.RequestHandler):
    def get(self):
        global es_empty_result
        id=self.get_argument("id", default=None, strip=False)
        user=self.get_argument("user", default=None, strip=False)
        self.write(json.dumps(es_empty_result, sort_keys = False, indent = 4))

application = tornado.web.Application([
(r"/$", MainHandler),
(r"/list1$", List1Handler),
(r"/list2$", List2Handler),
(r"/.*\.py$", MainHandler),# don't serve python as static files 
(r"/(.*)$", tornado.web.StaticFileHandler, dict(path=os.path.dirname(__file__))),
 ])

if __name__ == "__main__":
    import py_compile
    import logging
    from threading import Timer

    def ontimer_reload(prev_mtime,filepath,mainfile): # wait for file to stop changing, than check syntax,than reload
        global compileerr
        statinfo=os.stat(filepath)

        if statinfo.st_size>0 and statinfo.st_ctime==statinfo.st_mtime and statinfo.st_mtime-prev_mtime==0: 
            compiled=False 
            try:
                py_compile.compile(mainfile,doraise=True)
                compiled=True
            except py_compile.PyCompileError as e:
                compileerr=str(e)
                print "reloading: compile error..." 
                print e;
            if compiled:
                logging.info("%s modified; restarting server", filepath)
                tornado.autoreload._reload()
        else:
            print "reloading: waiting for file upload complete."
            Timer(0.3, ontimer_reload,(statinfo.st_mtime,filepath,mainfile)).start()
    #usage:Timer(0.3, ontimer_reload,(path,__file__)).start()

    def new_check_file(modify_times, filepath):
        try:
            modified = os.stat(filepath).st_mtime
        except Exception:
            return
        if filepath not in modify_times:
            modify_times[filepath] = modified
            return
        if modify_times[filepath] != modified:
            modify_times[filepath] = modified
            Timer(0.3, ontimer_reload,(modified, filepath,__file__)).start()
            #monkey patch tornado reload class
    tornado.autoreload._check_file = new_check_file

    print "server start"
    application.listen(8888)

    #def beforereloading():
    #   print "reloading: exiting..."

    #tornado.autoreload.add_reload_hook(beforereloading)
    #tornado.autoreload.watch(os.path.abspath('./file')) #additional file to watch
    tornado.autoreload.start()
    tornado.ioloop.IOLoop.instance().start()
    tornado.autoreload.wait()

"""
paste large text here to test like duplicate the folowing text until 1000 lines

HOWTO'S AND FAQ'    Difference between mtime, ctime and atime 

A common mistake is that ctime is the file creation time. This is not correct, it is the inode/file change time. mtime is the file modification time. A often heard question is What is the ctime, mtime and atime?.This is confusing so let me explain the difference between ctime, mtime and atime.
ctime
ctime is the inode or file change time. The ctime gets updated when the file attributes are changed, like changing the owner, changing the permission or moving the file to an other filesystem but will also be updated when you modify a file.

mtime
mtime is the file modify time. The mtime gets updated when you modify a file. Whenever you update content of a file or save a file the mtime gets updated.

Most of the times ctime and mtime will be the same, unless only the file attributes are updated. In that case only the ctime gets updated.

atime
atime is the file access time. The atime gets updated when you open a file but also when a file is used for other operations like grep, sort, cat, head, tail and so on.
"""

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the tornado.autoreload.start and _check_file entry points shown in the issue, along with the proposed ontimer_reload helper. Determine how a pre-reload hook should fit before the existing reload path; done should mean changed Python files can be syntax-checked and reload is prevented when compilation fails.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.