Skip to content

Tutorial 1 — Hello World with Storage

This tutorial shows you how to build a file upload application using PyGo’s native storage package — zero-config local storage that works out of the box.

A simple file upload app where users can:

  • Upload files via a form
  • See uploaded files in a list
  • Download files by ID
myapp/
├── app/
│ ├── web/
│ │ └── upload.pgo ← Model, handler, route
│ └── templates/
│ └── upload.html ← HTMX form + list
└── pygo.toml

Create app/web/upload.pgo:

# Import the storage package (built into PyGo)
from storage import LocalStore
# Define a file record model
model UploadedFile:
id: String
filename: String
content_type: String
size: Integer
created: DateTime
# Initialize local storage
store = LocalStore("./uploads", "/files")
handler upload:
upload_file(file: File) -> String:
# Save file using native storage package
result = store.save(file)
return f"File saved: {result['id']}"
# Route the upload form submission
route POST /upload -> upload

Create app/templates/upload.html:

<div x-data="{ uploading: false }">
<form
hx-post="/upload"
hx-swap="outerHTML"
enctype="multipart/form-data"
@submit="uploading = true"
>
<input type="file" name="file" required />
<button :disabled="uploading">
<span x-show="!uploading">Upload</span>
<span x-show="uploading">Uploading...</span>
</button>
</form>
</div>
Terminal window
# Start development server
pygo dev
# Upload a file
curl -F "file=@test.txt" http://localhost:8080/upload

Visit http://localhost:8080/templates/upload.html in your browser.

When you write from storage import LocalStore in .pgo:

  1. Transpiler generates both:
    • gen_go.go — creates a *storage.LocalStore instance
    • gen_py.py — creates a storage.LocalStore instance
  2. Runtime initializes storage on startup
  3. Handler uses the store transparently — no configuration needed

This is the power of PyGo’s native packages — written in Go, exposed to Python, works out of the box.