Instantly take photos from your phone and access them in any dialog.
- A tiny FastHTML server runs on port 6000, serving a camera capture page
- Open the page on your phone browser, tap to snap β photo auto-uploads to the instance
- Call
snap()in any dialog to display the latest photo
1. Create the server notebook: /AUTORUN/snap_server
This runs automatically on instance startup. It needs one code cell:
from fasthtml.common import *
from fasthtml.jupyter import JupyUvi
from pathlib import Path
from datetime import datetime
from PIL import Image as PILImage
import io
PHOTO_DIR = Path('/app/data/photos')
PHOTO_DIR.mkdir(exist_ok=True)
app = FastHTML(hdrs=[Meta(name='viewport', content='width=device-width, initial-scale=1')])
rt = app.route
@rt('/cam')
def cam():
return Title('πΈ Snap'), Main(
H2('πΈ Snap Photo', style='text-align:center'),
Form(
Input(type='file', name='photo', accept='image/*', capture='environment',
onchange='this.form.submit()', style='display:none', id='fileinput'),
Label('Tap to Capture', _for='fileinput',
style='display:block;text-align:center;padding:40px;font-size:1.5em;'
'background:#4CAF50;color:white;border-radius:12px;cursor:pointer;margin:20px'),
method='post', action='/cam/upload', enctype='multipart/form-data'),
Div(id='status', style='text-align:center;padding:20px;font-size:1.2em'),
style='max-width:400px;margin:auto;padding:20px')
@rt('/cam/upload', methods=['POST'])
async def upload(request):
form = await request.form()
photo = form['photo']
ts = datetime.now().strftime('%Y%m%d_%H%M%S')
dest = PHOTO_DIR / f'{ts}.jpg'
content = await photo.read()
img = PILImage.open(io.BytesIO(content))
img.thumbnail((1920, 1920))
img.save(dest, 'JPEG', quality=85)
return Title('πΈ Snap'), Main(
H2('β
Uploaded!', style='text-align:center;color:green'),
Img(src=f'/cam/photo/{ts}', style='max-width:100%;border-radius:8px'),
A('Take Another', href='/cam',
style='display:block;text-align:center;padding:20px;font-size:1.2em'),
style='max-width:400px;margin:auto;padding:20px')
@rt('/cam/photo/{name}')
def photo(name: str):
from starlette.responses import FileResponse
return FileResponse(PHOTO_DIR / f'{name}.jpg', media_type='image/jpeg')
srv = JupyUvi(app, port=6001)2. Add a port mapping: In your instance settings, map a subdomain to port 6000.
3. Bookmark on your phone: Open https://your-port-6000-subdomain.solve.it.com/cam and bookmark it.
4. Optional β create a CRAFT at /CRAFTs/snap so any dialog can load snap():
First note cell: describe the CRAFT. Then one code cell:
from pathlib import Path
from IPython.display import Image
PHOTO_DIR = Path('/app/data/photos')
def snap(n=0):
"Show the nth most recent photo (0=latest). Returns IPython Image."
photos = sorted(PHOTO_DIR.glob('*.jpg'), reverse=True)
if not photos: print('No photos yet'); return
return Image(filename=str(photos[n]), width=600)From any dialog (after loading the snap CRAFT):
snap()β latest photosnap(1)β previous photosnap(n)β nth most recent