[DONE] An Anvil client-code REPL

One of the biggest drawbacks of Anvil for me has been the ambiguity about which features of Python are available in the client-side code based on Skulpt. Currently, the best way to know for sure seems to be to test out the code you want to use. (For instance, you can create an app with a Module as the startup and use print statements to double-check that that bit of Python is working as expected.)

I wish there were a console-like REPL available in the context of each app to make this kind of gut-check testing quicker and easier. I’m picturing something like the “Interactive” demo at http://skulpt.org/, but with the latest Anvil implementation and the ability to import my Anvil modules. (The ability to load and interact with GUI objects would be a bonus but not critical for the purpose I have in mind.)

More broadly, I think making a client-side Python REPL (or notebook) easily available might appeal to the Python developers that I imagine are Anvil’s primary target audience.

6 Likes

This might be especially helpful in inspecting the app’s values at the point of an exception.

Might be related to this previous FR

1 Like

Yeah, there are a lot of practical uses for such a thing.

1 Like

Also see this FR which I believe is the same.

I may merge these at some point.

1 Like

Well, those other FRs seem focused on server-side code, which already has a solution via Uplink.

Okay great. Now we have FR for client and server side. Unfortunately uplink may not represent a solution to the linked FRs (as David alludes to). Either way, this is a nice FR for sure and I voted for it.

Here’s a solution to part of the problem… does it work in Anvil/Skulpt?

It’s a repl I made a while ago when getting to know Skulpt, and I’ve ported it over to an Anvil app.

You can visit the repl at

https://anvil-repl.anvil.app/


does skulpt support this feature?

Ntz84HR0cO


Because the repl is in Anvil you can also do some interesting stuff like:

qLz8Xq72qM


Use
ctrl/cmd + enter to execute a line of code
ctrl + c for keyboard interrupt

No autocomplete i’m afraid :frowning_face:

10 Likes

Thank you! I already made use of it to gut check something just now. :smile:

1 Like

I would love to see this as a Console component in the toolbox.

You could add a Console to a form just like you add a TextArea. When the app starts, the Console will be a REPL that shares the form’s interpreter.

This would allow you to add a Console to a form (only during development) and test the code with the very variables available in the client code.

2 Likes

This feature has now been implemented, in the new Beta Anvil Editor. It’s available every time you run an app!

image

6 Likes

Wow. Now when I get an exception in Debug mode, the code keeps running and I can investigate what went wrong with this interactive console!

5 Likes

For a list of all importable modules, you can type:

import sys
sys.modules

Relative references to your app modules don’t (currently) seem to work, but they can be accessed as [your_app's_package_name].[your_module_name] (replacing the square-bracketed names with your actual names).

2 Likes

Are there any Docs on how to use the Client Repl? I’ve been trying to access actual variables in my forms as they are running and crashing and burning pretty spectacularly, lol. To be fair, this might also be me just not understanding the Python going into this, but regardless, some direction would be appreciated :slight_smile:

The client repl imports the anvil name space.

If you want to access live elements that are on the screen you’ll always have to start from get_open_form() and work your way down the component hierarchy.

New session:
>>> f = get_open_form() # or anvil.get_open_form()
>>> f
<my_project.Form1 object>
>>> b = f.button_1
>>> b
<Button object>
>>> b.text = "foo"
New session:
>>> f = get_open_form() # or anvil.get_open_form()
>>> f.content_panel.get_components()[0] # get the form loaded into the conent_panel
<my_project.Form2 object>
>>> g = _ # last stored repl value
>>> g
<my_project.Form2 object>

If you want to import a module, you can’t do relative imports. Instead you’ll need to do absolute imports.
New session:
>>> import my_project.Module1 as m
>>> m.my_func()
1
>>> _ # last stored repl value
1

This means you can access global variables if you’ve put them in a module somewhere.

Autocompletion in the client repl is something we’re working on :wink: .

7 Likes

If you wonder what my_project is, you can find it in the “settings” - “dependencies” page, in the “use this app as a library” - “package name” text box.

This is especially useful if your app has a long name with spaces and other special characters.

3 Likes

Oooh that makes a lot of sense, thanks @stucork and @stefano.menci !i

It strikes me that if you’re using hash routing (everyone should be), you could also get access to cached forms from the routing library, and inspect the data on those. Sort of like a stack of called route forms.

Are there any functions in the routing library to make that easy through the REPL, or would it be examining the private globals?

1 Like

This may be useful too: Find components in the app console

2 Likes

Sure - you could use

>>> from anvil_extras.routing import get_cache
>>> get_cache()['home']
<my_project.HomeForm object>
4 Likes