Try an interactive version of this dialog: Sign up at solve.it.com, click Upload, and pass this URL.

Note: 10

Plash x SolveIt demo

Note: 37

In this dialog I show how you can use SolveIt to easily deploy apps on pla.sh

Code: 13 ()

# !pip install plash-cli --upgrade

Note: 12

Use Plash Cli directly in python

Note: 51

You can use the plash cli as a python library, because we built it using fastcore's @call_parse.

Code: 9 ()

import plash_cli as pc

Code: 21 ()

# pc.login()  # run and click on the url to login

Note: 15

Name your file main.ipynb

Note: 76

Plash expects a main.py file. So if you name your dialog main.ipynb, then you can mark certain code msgs for export while excluding others. This way you can experiment in your dialog while it's also your source code file.

Code: 10 ()

from fasthtml.common import *

Code: 13 ()

app = FastHTML()
rt = app.route

Note: 24

Use IN_SOLVEIT environment variable to distinguish app and dialog behavior

Note: 52

'IN_SOLVEIT' is a default env var that you can use. This is useful for example because you cant use the / route while working in solveit.

Code: 24 ()

import os
insolveit = 'IN_SOLVEIT' in os.environ

Code: 4 ()

insolveit

Output: 16

True

Code: 42 ()

@rt('/solveit_index' if insolveit else '/')
def index(): return H1("Hello Plash x Solveit")

Code: 12 ()

from fasthtml.jupyter import *

Code: 12 ()

srv = JupyUvi(app)

Code: 16 ()

HTMX(index,host=None,app=app)

Output: 271

Code: 12 ()

if not insolveit: serve()

Note: 24

Use pathlib to create your helper files (requirements.txt, .plash, ...)

Code: 36 ()

from fastcore.utils import *
Path('requirements.txt').write_text('''\
python-fasthtml
''')

Output: 16

16

Code: 27 ()

Path('.plash').write_text('export PLASH_APP_NAME=plash.ooh.me')

Output: 16

34

Note: 18

Use the plash cli again to deploy and watch logs

Code: 6 ()

!cat main.py

Output: 156

from fasthtml.common import *
app = FastHTML()
rt = app.route
import os
insolveit = 'IN_SOLVEIT' in os.environ
@rt('/solveit_index' if insolveit else '/')
def index(): return H1("Hello Plash x Solveit")
if not insolveit: serve()

Code: 6 ()

!ls -la

Output: 289

total 36
drwxrwsr-x  2 solveit solveit 4096 Dec 30 13:28 .
drwxrwsr-x 11 solveit solveit 4096 Dec 30 13:13 ..
-rw-rw-r--  1 solveit solveit   34 Dec 30 13:28 .plash
-rw-rw-r--  1 solveit solveit   36 Dec 30 13:17 .sesskey
-rw-------  1 solveit solveit 9172 Dec 30 13:28 main.ipynb
-rw-rw-r--  1 solveit solveit  229 Dec 30 13:27 main.py
-rw-rw-r--  1 solveit solveit   16 Dec 30 13:23 requirements.txt

Prompt: 12

does this look like it should work?

Assistant: 163

Yes, this looks good! The demo shows a nice workflow:

  1. ✅ FastHTML app setup with conditional routing based on IN_SOLVEIT
  2. ✅ JupyUvi for testing in the dialog
  3. requirements.txt created
  4. plash.env with app name
  5. main.py looks correct for deployment

One small thing: I notice the pc.deploy() or equivalent deploy command isn't shown at the end. Did you want to add that step to complete the demo?

Code: 4 ()

pc.deploy()

Output: 31

'plash.ooh.me'

Code: 6 ()

print(pc.logs())

Code: 10 ()

print(pc.logs(mode='app'))

Output: 159

Link: http://localhost:5001
INFO:     Will watch for changes in these directories: ['/app']
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     Started reloader process [1] using WatchFiles
INFO:     Started server process [14]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

Note: 4

lets verify:

Code: 28 ()

import httpx
print(httpx.get('https://plash.ooh.me/').text)

Output: 477

 <!doctype html>
 <html>
   <head>
     <title>FastHTML page</title>
     <link rel="canonical" href="https://plash.ooh.me/">
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.js"></script><script src="https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.12/fasthtml.js"></script><script src="https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js"></script><script src="https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js"></script>   </head>
   <body>
     <h1>Hello Plash x Solveit</h1>
   </body>
 </html>

Note: 15

Easy dev deployment by specifying the app name directly

Note: 75

pc.deploy takes a name argument which overrides the .plash file setting. This is useful for a test deployment.

Note, this does not overwrite te value of your .plash file. So subsequent deploys will still go to that url.

Code: 18 ()

pc.deploy(name='test-plash-x-solveit')

Output: 43

'https://test-plash-x-solveit.pla.sh'

Code: 30 ()

print(httpx.get('https://test-plash-x-solveit.pla.sh').text)

Output: 486

 <!doctype html>
 <html>
   <head>
     <title>FastHTML page</title>
     <link rel="canonical" href="https://test-plash-x-solveit.pla.sh/">
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.js"></script><script src="https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.12/fasthtml.js"></script><script src="https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js"></script><script src="https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js"></script>   </head>
   <body>
     <h1>Hello Plash x Solveit</h1>
   </body>
 </html>

Note: 37

fyi, the other commands also take the name arg so you can check the logs of your dev deployment that way too.

Code: 25 ()

print(pc.logs(name='test-plash-x-solveit',mode='app'))

Output: 205

INFO:     Will watch for changes in these directories: ['/app']
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     Started reloader process [1] using WatchFiles
Link: http://localhost:5001
INFO:     Started server process [14]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     172.17.0.1:49134 - "GET / HTTP/1.1" 200 OK

Note: 49

Wrap-up

Pretty nice to:

  1. develop your app
  2. deploy to dev
  3. deploy to prod

...all from a single dialog.