Design advice: Making a CLI & starting the app server in a script

Hi all :wave:. It’s been a while!

I’m building a CLI for one of my apps. When the admin types the_cli init, the app server fires up and the admin is prompted to set their username and password.

So far this works but I have a feeling there must be a better design.

Here’s how I’m doing it (forum references here and here):

# the_cli init will run this code

import time
from getpass import getpass
import anvil.server
from anvil.tables import app_tables
import bcrypt
import subprocess

subprocess.Popen(['anvil-app-server', '--app', 'MyApp', '--uplink-key', 'my_uplink_key'])
server_running = False

while not server_running:
    try:
        anvil.server.connect("my_uplink_key", url="ws://localhost:3030/_/uplink")
        server_running = True
    except:
        print('Waiting for web server')
        time.sleep(.5)

# prompt and set up the first user
email = input('Enter your email: ')
password = getpass('Enter your password: ')
new_user = app_tables.users.add_row(email=email, enabled=True)
password_hash = bcrypt.hashpw(bytes(password, encoding='ascii'), bcrypt.gensalt(16))
new_user['password_hash'] = password_hash.decode()

It seems tricky to deal with the subprocess and ugly to have a try block nested in a while loop but I couldn’t think of a better deign.

How would you design this kind of thing? Any small tips would be much appreciated.

2 Likes

Nice idea! I may try adding something similar to Amoni

1 Like

Glad to see that I’m not on completely the wrong track.

I thought there might be a more elegant way of waiting for the web server start before interacting with it.

Using IDLE this gives me a ConnectionRefusedError so explicitly using that in the except maybe?
Unless it gives you a different error when your subprocess is commented out.

I am often left with the feeling that something is too simple and could be more elegant, but I also know that nobody likes ‘clever’ code when someone else reads it later. :face_with_monocle:

I don’t understand what’s going on… you start one script, which starts a second process, then you connect with the first script… why do you start the second process? Are you connecting with both the first and second process?


(I haven’t tried, but) that while not server_running loop doesn’t convince me.

If the CLI is intended to be used interactively, then I would show that the connection didn’t work rather than keeping retrying.

If it’s intended to be used by a script… mmmh… still not sure I would have it trying forever.

Did you put the while loop because you gave you tried it without and you really needed it?
Or you are trying to solve a problem that you don’t yet know you have?