Sometimes it’s very useful to have listeners for requests, allowing you to implement features that need to be called whenever “something” happens in your application.

Two types of listeners have been added for this purpose.

Capture Listener

For example, imagine that every time a request to the ‘/logs’ route is made, my code performs a task that checks if the new logs differ from the old ones. Well, let’s see how this can be done:

import squarecloud as square
from squarecloud import Endpoint

@app.capture(endpoint=Endpoint.logs())
async def on_logs_request(before, after):
    if after != before:
        print(f'New logs!!! {after}')

async def main():
    client = square.Client('your api key')
    app = await client.app('application_id')

    await app.logs()  # True
    await app.logs()  # False

As seen above, by using the app.capture decorator on a function, this function will be called every time a request is made to the endpoint specified in the decorator. The accepted endpoints are APP_STATUS, LOGS, or BACKUP. This function should take two parameters:

  • before(represents the state after the request)
  • after(represents the state before the request)

The data type returned by before and after depends on which endpoint the listener is “listening” to. If it is the APP_STATUS route, it will receive a StatusData, LOGS will receive a LogsData, and BACKUP will receive a BackupData.

As you may have noticed in the example above, the first time the comparison between the logs occurs, after != before returns True. This happens precisely because after is equal to LogsData(logs=''), as there is still nothing stored in the cache internally.

You can use the avoid_listener=True parameter so that the application listener is not called.

Request Listener

The “request listeners” do pretty much the same thing. But here you use the Client, and the return of all endpoints is squarecloud.http.Response objects.

import squarecloud as square
from squarecloud import Endpoint

@client.on_request(endpoint=Endpoint.logs())
async def on_logs_request(response):
    print(1, response)

async def main():
    client = square.Client('your api key')
    await client.get_logs(app_id='application_id')  # 1, Response(success)

Passing extra arguments

You can pass to some methods keyword argument called extra, and this will be passed to your listener

import squarecloud as square
from squarecloud import Endpoint

@client.on_request(Endpoint.status())
async def get_extra_param(before, after, extra: dict[str, str]):
    print(extra)

async def main():
    client = square.Client('your api key')
    await client.app_status('application_id', extra={'name': 'robertinho'})

You can get some cool features in listeners using pydantic in your project, take a look at using pydantic

This implementation was inspired by a suggestion made by @Mudinho, thank you for contributing.