Skip to main content

Control the web with Python

Project description

Binder

Purly

Control the web with Python :snake:

Install

Install a dev version (a pypi version is coming soon):

git clone https://github.com/rmorshea/purly && cd purly/ && pip install -e . -r requirements.txt

Getting Started

Run the following snippet of code, and then navigate to http://127.0.0.1:8000/model/index.

import purly

# Prepare your layout
purly.state.Machine().run(debug=False)
layout = purly.Layout('ws://127.0.0.1:8000/model/stream')

# create your HTML
div = layout.html('div')
div.style.update(height='20px', width='20px', background_color='coral')

# add it to the layout
layout.children.append(div)

# and sync it!
layout.sync()

Now your creation should have magically appeared in the browser page you opened!

div with some styling

Architecture (Not Final)

Purly's fundamental goal is to give Python as much control of a webpage as possible, and do so in one incredibly simple package. There is one major problem that stands in the way of this goal - data synchronization. Purly's answer to this problem is its model server which acts as a "source of truth" about the state of a webpage for any clients which connect to it and adhere to its protocol.

Model Server

protocol

Purly uses a web socket server to keep multiple concurrent clients in sync. The animation above shows 2 clients - a Python client pushing updates to a single Browser - however you could have more clients producing and / or consuming, model updates. Each client is associated with a single model (any JSON serializable object), however there can be multiple models that are stored on the server. Clients connect to a particular model by specifying its name in the socket route (e.g. ws://host:port/model/<model-name>/stream). Only clients that are connected to the same model communicate with each other via the server.

Model Specification

While the Model Server supports any JSON serializable model, Purly, as a framework for controlling the web must:

  1. Communicate as fully as possible the structure of DOM elements and their various interactions.
  2. Send updates to DOM models over a network in short and easy to interpret packages:
  • Update messages must be small in size in order to reduce network traffic.

To accomplish the goals defined above we propose a flat DOM model:

Model = {
  id: Element,
  # Maps a uniquely identifiable string to an Element.
  root: Element,
  # The id "root" should always indicate the outermost Element.
  ...
}
Element = {
  tagName: string
  # Standard HTML tags like h1, table, div, etc.
  signature: string
  # The hash of this element attributes, and the hashes of its children.
  children: [
    string,
    # Any arbitrary string.
    {type: 'ref', 'ref': string},
    # An object where the key "ref" refers to the "key" attribute.
    ...
  ],
  attributes: {
    key: id,
    # The id that uniquely identifies this Element.
    parent_key: id
    # The unique id of this element's parent.
    attr: value,
    # Map any attribute name to any JSON serializable value.
    on<Event>: {
      # Specify an event callback with an attribute of the form "on<Event>".
      callback: uuid,
      # A unique identifier by which to refer to the callback function.
      keys: [...],
      # Details of the event to pass on to the callback.
      update: [...]
      # Any attributes that should be synced before the callback is triggered.
    }
  }
}

Purly Model Example

The following HTML

<div key='root'>
  Make a selection:
  <input type='text' key='abc123'></input>
<div>

would be communicated with the following Purly model:

{
  root: {
    tag: 'div',
    elements: [
      'Make a selection:'
      {'ref': 'abc123'},
    ]
    attributes: {
      'key': 'root'
    }
  },
  abc123: {
    tag: 'input',
    elements: [],
    attributes: {
      'key': 'abc123',
      'type': 'text',
    },
  }
}

Communication Protocol

The Purly model server sends and receives JSON serializable arrays which contain objects in the form of a Message.

[
  Message,
  # a dict conforming to the Message spec
  ...
]

Message

There are two types of messages - Updates and Signals - however both conform to the following format.

Message = {
  "header": {
    "type": "signal" or "update",
    # Message type (indicates the kind of content).
    "version": "0.1",
    # Message protocol version.
  }
  # Content which depends on the message type.
  "content": dict,
}

Signals

  • A Signal does not modify the state of the model server.
  • Signal content is distributed unmodified to other model clients.

Updates

  • The content field specifies changes that will be merged into the model.
  • Only the differences between the Update content and the model are distributed to other clients.
  • Update merges are performed in a nested fashion

If the current state of the model is

{
  'a': {
    'b': 1,
    'c': 1,
  }
}

and an update message

{
  'a': {
    'c': 2
  }
}

is received, the resulting model state is

{
  'a': {
    'b': 1,
    'c': 2,
  }
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

purly-0.1.0.tar.gz (463.4 kB view details)

Uploaded Source

Built Distributions

purly-0.1.0-py3.6.egg (473.4 kB view details)

Uploaded Source

purly-0.1.0-py3-none-any.whl (465.7 kB view details)

Uploaded Python 3

File details

Details for the file purly-0.1.0.tar.gz.

File metadata

  • Download URL: purly-0.1.0.tar.gz
  • Upload date:
  • Size: 463.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.19.1 setuptools/39.2.0 requests-toolbelt/0.8.0 tqdm/4.23.4 CPython/3.6.6

File hashes

Hashes for purly-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0833f36d1abbbe475362acd57e19602f5d69ec3acb79b6fa02420a3180ee8120
MD5 fe7d9afc953e87ca069ca412f85f55e8
BLAKE2b-256 063024eefdbdf93298102859fbdd11090f0fab6c1c137467da44633006abeb81

See more details on using hashes here.

File details

Details for the file purly-0.1.0-py3.6.egg.

File metadata

  • Download URL: purly-0.1.0-py3.6.egg
  • Upload date:
  • Size: 473.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.19.1 setuptools/39.2.0 requests-toolbelt/0.8.0 tqdm/4.23.4 CPython/3.6.6

File hashes

Hashes for purly-0.1.0-py3.6.egg
Algorithm Hash digest
SHA256 8b9f97b0a1f9ed0bb31966004d3c6119938864c03cc4c292d99a46ed551bcefa
MD5 89868434412fad1322c02925b0d5eb42
BLAKE2b-256 8d46a0ee07a84334eaea931a06ba547f98e9fce8031df40cf035e939ba9f8af9

See more details on using hashes here.

File details

Details for the file purly-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: purly-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 465.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.19.1 setuptools/39.2.0 requests-toolbelt/0.8.0 tqdm/4.23.4 CPython/3.6.6

File hashes

Hashes for purly-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7353c077406e7c9f2548b007926c2874ce084391250eb52f21c171eb4f024f70
MD5 de4dd5cd04f120390f152e1588b478aa
BLAKE2b-256 2009359c448cbd6664bf25424abdfbdc719e7b9fd76fe670327dbf7faa4362fd

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page