Skip to main content

Run your application

Reboot applications are defined using an instance of Application, and launched from the file configured as your --application in .rbtrc.

Application

Your entrypoint will construct an Application and then run it:

async def main():
await Application(
servicers=[HelloServicer],
initialize=initialize,
).run()


if __name__ == '__main__':
asyncio.run(main())

initialize functions

The optional initialize argument to the Application constructor is a function that runs every time your application starts up.

Initializers can be used to create any initial state that your application needs. In particular, they are usually where any singleton instances used by your application are created.

async def initialize(context: InitializeContext):
hello = Hello.ref(EXAMPLE_STATE_MACHINE_ID)

# Implicitly construct state machine upon first write.
await hello.send(
context,
message="Hello, World!",
)

If you have declared an initialize function, then you can additionally pass an initialize_bearer_token (initializeBearerToken in TypeScript) which the initialize method should use to authenticate itself to your application.

HTTP custom routes

Using a Reboot Application you can not only run your Reboot servicers but you can also provide custom HTTP route handlers for circumstances where you can't just call one of your data type's methods.

For Python, this is implemented using FastAPI. For TypeScript, this is implemented with Express.js.

important

Limitations of custom HTTP routes

  • Currently only GET and POST methods are supported.

  • The / route is currently used by Reboot itself to show a helpful page explaining that this is a Reboot application.

Please reach out to us at team@reboot.dev if you run into use cases for fixing these!

Here is an example of implementing a handler for an HTTP GET:

@application.http.get("/hello_world")
def hello_world():
return {"message": "Hello, world!"}

To simplify calling directly into your Reboot application from your application.http.get and application.http.post handlers we provide a context of type ExternalContext because you are still "external" to your application from an authorization perspective.

This context includes any bearer token from Authorization: Bearer <token> so that any calls into your Reboot application will be properly authorized. In TypeScript, we inject the context for every handler. In Python, we follow the FastAPI dependency injection strategy. If you want the context, you must explicitly add it to your arguments as shown in the following example:

@application.http.post("/hello_greeter")
async def hello_greeter(
request: Request,
context: ExternalContext = InjectExternalContext,
):
body = await request.json()
greeter, _ = await Greeter.create(
context,
title=body['title'],
name=body['name'],
adjective=body['adjective'],
)

response = await greeter.greet(context, name="You")

return {"message": response.message}