import cherrypy from sqlalchemy import create_engine from accounting.models import Base from accounting.api import AccountingAPI import os import json from config import DATABASE_URI def CORS(): cherrypy.response.headers["Access-Control-Allow-Origin"] = "*" cherrypy.response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS" cherrypy.response.headers["Access-Control-Allow-Headers"] = "Content-Type" # JSON Tools for response serialization class JSONEncoder(object): def __init__(self): self.json_encoder = json.JSONEncoder() def __call__(self, value): # Convert the Python object to a JSON string then to bytes return json.dumps(value).encode('utf-8') class Root: @cherrypy.expose def index(self): return open(os.path.join(os.path.dirname(__file__), 'accounting/templates/index.html')).read() @cherrypy.expose def favicon_ico(self): return cherrypy.lib.static.serve_file( os.path.join(os.path.dirname(__file__), 'static/favicon.ico'), content_type='image/x-icon' ) def setup_database(): engine = create_engine(DATABASE_URI) Base.metadata.create_all(engine) return engine def main(): # Database setup db_engine = setup_database() # Create static directory if it doesn't exist static_path = os.path.join(os.path.dirname(__file__), 'static') if not os.path.exists(static_path): os.makedirs(static_path) # Register tools cherrypy.tools.CORS = cherrypy.Tool('before_handler', CORS) # Root application config root_conf = { '/': { 'tools.sessions.on': True, 'tools.staticdir.root': os.path.abspath(os.path.dirname(__file__)), 'tools.CORS.on': True }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'static', } } # API application config api_conf = { '/': { 'request.dispatch': cherrypy.dispatch.MethodDispatcher(), 'tools.CORS.on': True, 'tools.json_out.on': True, # Use the built-in JSON serializer 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8', # Process JSON request bodies 'request.body.processors': { 'application/json': cherrypy.lib.jsontools.json_processor } } } # Create and mount Root application root = Root() cherrypy.tree.mount(root, '/', root_conf) # Create and mount API as a separate application api = AccountingAPI(db_engine) cherrypy.tree.mount(api, '/api', api_conf) # Start server cherrypy.config.update({ 'server.socket_host': '0.0.0.0', 'server.socket_port': 8080, 'log.screen': True, 'engine.autoreload.on': True }) print("Starting accounting system...") cherrypy.engine.start() cherrypy.engine.block() if __name__ == '__main__': main()