Docs

Get started

This page takes you from nothing to a running Evlet site with your own model. It takes about 15 minutes. You need a terminal and Python.

#What Evlet is

Evlet is a Python framework for business apps. You describe your records as Python classes called models. Evlet then gives you a database table, forms and lists in the browser, permission checks and an HTTP API for each model.

You will build a small Notes app and run it on a site called acme. In Evlet, a site is called an instance. Read the framework overview if you want the words explained first.

#Requirements

  • Python 3.12 or newer. Check with python3 --version.
  • macOS, Linux or Windows.
  • Nothing else. SQLite is built in, so there is no database server to install. You do not need Node.js for apps written in Python.

#Install Evlet

Make a folder for your work and create a Python virtual environment in it. A virtual environment keeps Evlet's packages apart from the rest of your computer.

Terminal
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade evlet

On Windows, create it with py -3.12 -m venv .venv and activate it with .venv\Scripts\Activate.ps1 in PowerShell.

These docs are written for Evlet 0.4.3. To install exactly that version, run python -m pip install evlet==0.4.3. Check what you have with python -m pip show evlet.

#Create a project, an app and a site

One command does it all:

Terminal
evlet setup myproject --app notes --instance acme --dev

It runs these steps in order:

  1. Creates the folder myproject with its own Python environment and installs Evlet in it.
  2. Creates an app called notes.
  3. Creates an instance (a site) called acme.
  4. Asks whether you trust the app, then installs it on acme. This creates the site's database.
  5. Starts a development server on 127.0.0.1 and prints a sign-in link.

Read the trust question. Installing an app runs its Python code on your computer. Your own new app is safe. Review apps you download before you say yes. In scripts, where nobody can answer, add --trust after you have reviewed the code.

If a step fails, the message names it. Fix the cause and run the same command again. Steps that already finished are skipped.

#The same steps one at a time

If you want to see each step, run them yourself:

Terminal
evlet setup myproject
cd myproject
evlet app notes
evlet instance acme
evlet install notes --instance acme
evlet dev --instance acme

#Sign in for the first time

Every instance has a built-in System Administrator with the username admin. It starts with no password. There is no default password.

evlet dev prints a one-time sign-in link when it starts:

Output
The admin account has no password yet. Open this link to sign in and choose one (works once, for 10 minutes):
  http://127.0.0.1:8000/_dev/signin?token=...

Open the link in your browser. Then:

  1. Choose a password on the Set your password screen. A new instance asks admins for at least 15 characters.
  2. Set up two-step sign-in with an authenticator app. A new instance asks this of admins.
  3. You are signed in. The first page is Docs.

Each link works once and expires after 10 minutes. For a fresh link, run evlet dev-link in a second terminal. Once the Administrator has a password, later links just sign you in.

The rules for passwords and two-step sign-in live in instances/acme/config.py. On a site for development only, Security(password_min=1, ...) allows any password.

#The project layout

After setup, the project looks like this:

Output
myproject/
  .venv/                     the project's own Python environment, with Evlet
  .evlet/                    build output Evlet manages; do not edit
  apps/
    notes/                   your app: plain Python you own
      __init__.py
      pyproject.toml         name, version and Python dependencies
      setup.py
      models/
        __init__.py
        item.py              the starter model
  instances/
    acme/                    your site: data, never code
      config.py              site settings and sign-in rules
      apps.lock              which app versions the site runs
      data/
        database.sqlite3     the site's database

Run Evlet commands from inside myproject. They find the project from the folder you are in, and they use the project's own .venv for you.

Keep apps/ in version control. Keep instances/ out of it: it holds customer data and secrets. Back it up instead.

The starter model in apps/notes/models/item.py looks like this:

Python
from evlet import Model, Rule, Text


class NotesItem(Model):
    permissions = {
        'admin': Rule(('read', 'create', 'update', 'delete')),
        'editor': Rule(('read', 'create', 'update')),
        'viewer': Rule(('read',)),
    }
    title = Text(required=True, max_length=160)

    class Meta:
        label = 'Item'
        plural = 'Items'
        title_field = 'title'
        list_fields = ('title',)
        search_fields = ('title',)

permissions says which roles may do what. A role that is not listed gets nothing. Meta holds labels and list settings for the browser.

#Your first model

Add a Task model to the Notes app. Create apps/notes/models/task.py:

Python
from evlet import Boolean, Date, Link, Model, Rule, Text


class NotesTask(Model):
    permissions = {
        'admin': Rule(('read', 'create', 'update', 'delete')),
        'editor': Rule(('read', 'create', 'update')),
        'viewer': Rule(('read',)),
    }
    title = Text(required=True, max_length=160)
    item = Link('notesitem')
    due = Date()
    done = Boolean(default=False)

    class Meta:
        label = 'Task'
        plural = 'Tasks'
        title_field = 'title'
        list_fields = ('title', 'due', 'done')

Evlet finds every model in models/ by itself. You do not register it anywhere. Link('notesitem') points each task at an Item. notesitem is the Item model's table name: its class name in lower case.

#Write the migration

The site's database does not have a table for tasks yet. Evlet never changes your database by itself. You add a migration: a small Python file that says what changes.

Stop the development server with Control-C. Then let Evlet write the migration:

Terminal
evlet makemigration notes --instance acme --name tasks

It writes apps/notes/migrations/m0001_tasks.py:

Python
"""0001_tasks: written by evlet makemigration. Review it, then keep it unchanged once applied."""

from evlet import Boolean, CreateModel, Date, Link, Migration, Model, Text


class NotesTask(Model):
    title = Text(required=True, max_length=160)
    item = Link('notesitem')
    due = Date()
    done = Boolean(default=False)


migration = Migration(
    '0001_tasks',
    CreateModel(NotesTask),
)

The migration holds a frozen copy of the model: the fields as they are today. Your live model can keep changing; this file stays the same once it is applied.

To see what would change without writing anything, run evlet migrate acme --plan.

#Migrate and serve

Apply the migration, then start the server again:

Terminal
evlet migrate acme
evlet dev --instance acme

evlet migrate asks you to trust the changed app code, then writes a backup of the database to instances/acme/data/backups/ and applies the migration. Open the new sign-in link and you will find Tasks next to Items.

evlet dev reloads Python changes while you work. A change to the fields of a model still needs a migration. To run the site without development tools, use evlet serve acme. It serves on http://127.0.0.1:8000.

#Next steps

  • Read the Model engine guide. It covers fields, links, calculations, validation, permissions, actions and migrations.
  • Try evlet playground for a demo site with sample data. It keeps nothing after it stops.
  • Run evlet docs to read the guides that ship with your installed version, offline.