The Basic Concepts

JustPy Components

JustPy components are classes that instantiate reusable elements that can be be rendered in a browser. Out of the box, JustPy comes with many components. You can use the available JustPy components and also build more complex components using other components as building blocks.

In JustPy, components are implemented as Python classes. When you define a new component, you do so by defining a new Python class.

A JustPy element is an instance of a component class.

import justpy as jp
p = jp.P()
p.text = 'Hello!'

In the example above, p is an instance of the class P. Its text attribute is set to 'Hello!'. The above is similar to the HTML element:

<p>Hello!</p>

You can set the JustPy element attributes when the element is created (synonym for instantiated) using keyword arguments to make code shorter and clearer:

import justpy as jp
p = jp.P(text='Hello!')

Just creating an element is not very useful. We need to get it on a web page and into the user's browser tab. We will do this next.

JustPy Web Pages

In JustPy, web pages are instances of the JustPy class WebPage. You create a web page the same way you create any class instance in Python:

import justpy as jp
wp = jp.WebPage()

In the example above we created the web page wp. It is an empty web page that does not contain any elements.

Let's create an element and add it to the page:

import justpy as jp
wp = jp.WebPage()
p = jp.P(text='Hello World!')
wp.add(p)  # Same as p.add_to(wp), wp = wp + p, wp += p

In the example above, we create a web page. Then we create a p element and add it to the page using the add method.

Since adding an element to a page is very common, there is a way to do so using the keyword argument a:

import justpy as jp
wp = jp.WebPage()
p = jp.P(text='Hello World!', a=wp)

This code snippet has the same functionality as the one above it.

JustPy Requests

So far we have created a page and added an element to it. We haven't yet loaded the page into the user's browser.

Note

In this tutorial, I will call the process of delivering a Web page to a user "rendering the page".

When you type a URL into your browser's Address Bar and tell your browser to navigate to that address, the browser generates a request; it requests data from the server the URL you entered points to.

When a request comes from a browser, the JustPy framework runs a user defined function. This function must return a web page which is then rendered in the browser that sent the request. All that you as a developer need to do is write the function that takes a request and returns a web page. The framework takes care of the rest.

Hello World

Here is a basic example:

import justpy as jp

def hello_world():
    wp = jp.WebPage()
    p = jp.P(text='Hello World!', a=wp)
    return wp

jp.justpy(hello_world)

The function hello_world creates a web page, adds a paragraph element to it and returns the page.

Note

In this tutorial, functions like hello_world will be called "request handlers".

The jp.justpy(hello_world) command starts a web server and sends all requests to the function hello_world.

Run the program above (as explained in getting started ). You should see 'Hello World!' in your browser.

More Hello World

Saying hello once isn't enough! We would like to say "hello" ten times. We also want to let the user know how many times we said "hello". More specifically, we would like "Hello World!" to show up ten times on the page and be enumerated. In addition, we would like to use a bigger font each time.

import justpy as jp

def hello_world():
    wp = jp.WebPage()
    for i in range(1,11):
        jp.P(text=f'{i}) Hello World!', a=wp, style=f'font-size: {10*i}px')
    return wp

jp.justpy(hello_world)

Run the program above and look at the result in your browser.

Warning

Don't forget to terminate the previous program first.

Two JustPy servers cannot run at the same time on the same port.

The P instances are created inside a loop with the loop index being used to give each paragraph some different text and a different font size.

The style attribute in JustPy is the same as the HTML style attribute. It allows using CSS properties to style the element.

For example, change the style assignment to:

style=f'color: blue; font-size: {10*i}px' 

and see what happens.

Tailwind and JustPy

Another way to style elements is to use classes. By default, instances of WebPage support styling using Tailwind classes. If you are familiar with CSS, checkout Tailwind. For me, it is a joy to work with.

Info

You can also put your own CSS on a page and use your own class definitions by setting the css attribute of a page.

Let's use Tailwind classes to style our page:

import justpy as jp

def hello_world():
    wp = jp.WebPage()
    my_paragraph_design = "w-64 bg-blue-500 m-2 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
    for i in range(1,11):
        jp.P(text=f'{i}) Hello World!', a=wp, classes=my_paragraph_design)
    return wp

jp.justpy(hello_world)

In this program Tailwind classes are used to make the output a little nicer. The JustPy attribute classes is equivalent to the HTML attribute class (which is a reserved word in Python).

Creating Web Pages Once

You may have noticed that since we have been serving the same page to everyone, there is no need to create a new page each time a request is made. We can create a page one time, and serve the same page for all requests:

import justpy as jp

wp = jp.WebPage(delete_flag=False)
my_paragraph_design = "w-64 bg-blue-500 m-2 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
for i in range(1,11):
    jp.P(text=f'{i}) Hello World!', a=wp, classes=my_paragraph_design)

def hello_world():
    return wp

jp.justpy(hello_world)

Info

When you define a page that is going to be rendered in more than one browser tab or page, you need to set its delete_flag to False.

Otherwise, the page (the instance of WebPage to be precise) will be deleted when a browser tab or window that renders that page is closed. The default is for JustPy to remove all references to the page and the elements on it so that the Python garbage collector can reclaim the memory.

Warning

When a page's (or element's) delete_flag is set to False, none of its child elements will be deleted, even if their delete_flag is True.

In the next part of the tutorial you will learn how to deal with events such as a mouse click.