Run a function once on bottle.py startup
Asked Answered
N

4

8

I have a bottle app that I eventually wan't to deploy on apache (just fyi in case that's important). Now I need to run a function once after the bottle app is started. I can't just put it into a routed function because it has to run even if no user has accessed the site yet.

Any best pratice to do this ?

The function starts a APScheduler Instance and adds a jobstore to it.

Nga answered 21/1, 2013 at 15:27 Comment(1)
The same question for FlaskHardandfast
A
1

Here's what I do.

def initialize():
    //init whatever you need.
if __name__ == '__main__':
    initialize()
    @bottle.run(port='8080', yatta yatta)
Archducal answered 19/5, 2013 at 15:13 Comment(1)
This only works if you're using the built-in server. Otherwise it won't run.Seka
C
1

Honestly your problem is simply a sync vs async issue. Use gevent to easily convert to microthreads, and then launch each separately. You can even add a delay either in your function or before with gevent.sleep if you want to wait for the web server to finish launching.

import gevent
from gevent import monkey, signal, spawn, joinall
monkey.patch_all()
from gevent.pywsgi import WSGIServer
from bottle import Bottle, get, post, request,  response, template, redirect, hook, abort
import bottle

@get('/')
def mainindex():
    return "Hello World"

def apScheduler():
    print "AFTER SERVER START"

if __name__ == "__main__":
    botapp = bottle.app()
    server = WSGIServer(("0.0.0.0", 80), botapp)
    threads = []
    threads.append(spawn(server.serve_forever))
    threads.append(spawn(apScheduler))
    joinall(threads)
Catercorner answered 4/9, 2019 at 14:53 Comment(0)
G
0

Create an APScheduler class.

Look at examples of object use and creation in this same site bacause it's too general to give an especific example to copy.

I don't know if this helps.

class Shed(object):
    def __init__(self): # this to start it
        # instruccions here

    def Newshed(self, data):
        # Call from bottle

    # more methods ...


...

# init
aps = Shed() # this activates Shed.__init__()

...

# in the @router
x = aps.Newshed(data)  # or whatever

Anyway I'm still learning this stuff and it's just an idea.

Gonion answered 21/1, 2013 at 15:44 Comment(3)
Actually it is a python script which would not disqualify your aproach but that script interacts with the bottle app itself. The thing is the functions that i need to schedule are also part of the bottle app so I can't run the sheduler isolated from that app.Nga
Create a class that you initialize when you start and then use at need.Gonion
I really appreciate your effort but this doesn't help me at all. I'm familiar with all that class and init stuff but what I still need to know is how to call anything (wether initiating something or just calling a function) AFTER the bottle run method without putting it into a routed function. It has to be in this order because the functions that i wan't to shedule are not defined before the server is started (don't know why that is actually)Nga
J
-2
import threading
import bottle

def init_app():
    def my_function_on_startup():
        # some code here
        pass
    app = bottle.app()
    t = threading.Thread(target=my_function_on_startup)
    t.daemon = True
    t.start()
    return app


app = init_app()

@app.route("/")
def hello():
    return "App is running"

if __name__ == "__main__":
    bottle.run(app, host='localhost', port=8080, debug=True)
Johannajohannah answered 30/8, 2019 at 12:10 Comment(1)
This makes no sense at all. It creates a thread, starts it which which will run "some code here" eventually. Then it sarts the bottle server with no connection to the prior.Oligoclase

© 2022 - 2024 — McMap. All rights reserved.