Desktop app with App Server

Hi,

I am pleasantly surprised by open sourced App Server. This was quite a change which started my thinkering about changing the development platform for many of my projects.

Did anybody tried to develop a desktop app with this approach? The app should start the local App Server, possibly reusing the existing one, start a browser for the user, and destroy all objects/processes safely after it finishes.

Best wishes
Tomaž

I am not too sure the app server can run on windows, but mang people have use it for kind of desktop apps in raspberry 4

@Tony.Nguyen, Windows is mentioned in the Getting Started docs.

Edited for clarity.

Sure it can run on Windows, this is not the issue. I was thinking of something similar to

or a solution with threading and/or subprocesses since it is clear that some controlling program should tie both parts - client and server - together, to have a final GUI effect similar to, let’s say, Postgres pgAdmin.

Thanks @p.colbert and @tomaz.turk for the information. I read the doc many times but miss the information.

I just run the app in Windows without much issue (git and virtualenv need to be installed)

pip install virtualenv
.\env\Scripts\activate

https://docs.python.org/3/library/venv.html

After some research I found a possible solution of how to “mimic” a desktop app with Anvil App Server (AAS). It’s crude, it is written for Windows, and only partially tested. The goal is to have a solution which would on application run:

  • start up the AAS with our Anvil App
  • after the AAS is up and running, open the default web browser and present the main page to the user.

When the user closes the app (i. e. closes the browser), it would be convenient if the AAS terminates.

I explored various options, and finally decided to do it in Anvil way as much as possible :slight_smile: The most difficult question is how to signal the AAS to close when user closes the browser, so I decided to have a control app MainApp,py, a relatively short program in Python with these responsibilities:

  • it starts the AAS
  • if successful, it waits for the server to be up and running (it waits for the server to respond “HTTP Server running”)
  • after that, it establishes the uplink with the AAS and starts the default web browser
  • listens for a signal via uplink to terminate AAS and itself.

The termination signal is implemented via uplink by @anvil.server.callable function in MainApp.py, so the AAS can terminate when it receives the command to do so from our app like

anvil.server.call('shutdown_me')

This can be hooked to an Exit/Quit button, or even better to onbeforeunload javascript event.

Here’s the code. As I said, it is prepared for Windows, and since os, signal and subprocess libraries behave differently on different platforms, this should be revised for Linux and Mac. I still have to re-check if the AAS really closes gracefully. There are a couple of print() statements if you need to test it on console.

import os
import signal
import sys
import subprocess
import webbrowser
import anvil.server

@anvil.server.callable
def shutdown_me():
    global process
    #print('AAS WILL TERMINATE')
    os.kill(process.pid, signal.CTRL_C_EVENT)
    sys.exit(0)

@anvil.server.callable
#JUST TO CHECK IF THE UPLINK WORKS
def say_hello(name):
  print(f"Hello from your own machine, {name}!")

def main():
    global process
    app_path = 'C:\\PATH TO YOUR ANVIL APP'

    process = subprocess.Popen(['anvil-app-server.exe', '--app' , app_path, '--uplink-key', '12345'], stdout=subprocess.PIPE)

    while True:
        output = process.stdout.readline().decode()
        if output == '' and process.poll() is not None:
            break
        if output:
            message = output.strip()
            #print('{}'.format(message))
            if message.find("HTTP Server running") != -1:
                anvil.server.connect("12345", url="ws://localhost:3030/_/uplink")
                webbrowser.open_new('http://localhost:3030')

if __name__ == '__main__':
    main()
1 Like