Skip to main content

ยท 4 min read
Feodor Fitsner

We've just released Pglet v0.5!

While working on this release Pglet made HN home page, got included into TLDR newsletter and topped 500 stars on GitHub (hey, if you enjoy using Pglet give it a โญ๏ธ)! That was exciting - we received great feedback from real users! Many of those comments/requests were incorporated in the release.

Faster WebSocket-based clients

Originally, Pglet was using Redis-like text-based protocol to modify web page controls. There was a proxy process running between a client library and Pglet server translating text commands to WebSocket messages understood by the server. A client library was communitcating with a proxy via Unix named pipes (or named pipes on Windows). Such design was chosen because initially Pglet was made to work with Bash and named pipes is what natively supported there. By adding clients for other languages such as Python and C#/PowerShell it became obvious that the layer of named pipes, command parser/translator and proxy process leads to increased complexity.

With the release of Pglet v0.5, client libraries for Python and C#/PowerShell were re-written to communicate directly with Pglet server via WebSocket protocol. Proxy process is no longer required. As a bonus, when a user application is exiting (CTRL+C), a client library is now sending correct WebSocket closing command to the server, so the app instantly becomes "inactive" and is removed from the server.

Versioning for Pglet and clients

Versions of Pglet Server and its clients follow SemVer format: MAJOR.MINOR.PATCH.

MAJOR part of the version will be changed when Pglet Server API changes break backward compatibility. For now it's 0 meaning there are no drastic changes to the API and it's not mature enough to become 1. All client libraries will follow the same MAJOR number.

Pglet clients could have MINOR version part greater or equal than Pglet server. When the next 0.6 version of Pglet server is released, all client libraries will be bumped to 0.6 as well.

PATCH version part is completely independent for Pglet server and all client libraries.

License changed to Apache 2.0

It looks like initially licensing Pglet under AGPL was "premature optimization". Yes, we may want to monetize Pglet with a hosted service and AGPL would stop big cloud providers from forking our service and incorporating it into their cloud offerings, but Pglet is very young project and, honestly, right now we don't foresee Microsoft copying it :)

On the other hand (A)GPL is used to be corporate-unfriendly license which reduces Pglet audience and slows adoption. We want every company using Pglet to build their internal tools!

So, we listened to your feedback and changed Pglet license to Apache License 2.0.

Local mode is now default

Streaming app UI to the web via hosted Pglet service (aka "Web" mode) is a primary use case for Pglet, so in the previous v0.4 release we made "web" mode default. However, after receiving feedback from users, we realized that an app needs to be tested locally before making it public. Therefore, in Pglet v0.5 we are reverting back "local" mode as default. As before Pglet Server is conveniently bundled into all client libraries to make local app development smooth and pleasant.

We need your feedback!

Give Pglet a try and let us know what you think! If you have a question or feature request please submit an issue, start a new discussion or drop an email.

Where does Pglet go next?

This is a brief roadmap for Pglet project:

  • PowerShell guide and examples.
  • Node.js/Deno client (it's still based on Pglet v0.4), guide and examples.
  • Go (Golang) client, guide and examples.
  • Pglet hosted service into production:
    • performance optimization,
    • storage cleanup,
    • CPU/memory profiling,
    • metrics,
    • monitoring.

Happy New Year! ๐ŸŽ„๐Ÿค—

ยท 2 min read
Feodor Fitsner

The major feature of Pglet 0.4.6 release is built-in authentication and authorization. Pglet now allows creating protected pages and apps which require users to sign in with any of three methods: GitHub, Google or Microsoft account (Azure AD):

Just imagine, you can instantly add authentication to any of your backend scripts!

For example, in Python to create a page accessible to GitHub user with username ExampleUser and all users in myorg/Developers team:

page = pglet.page(permissions="github:ExampleUser, github:myorg/Developers")

To allow access to specific Azure AD groups/roles you need to specify their full name including tenant ID, for example:

page = pglet.page(permissions="{tenant-guid}/GroupA")

To give access to users authenticating with any method and @custom-domain.com email domain:

page = pglet.page(permissions="*@custom-domain.com")

Other changes and improvements

Web mode by default

Starting from this relase when you start a new page or multi-user app with default parameters its UI will be streamed to https://console.pglet.io. To create a local page add local=True parameter (Python), for example:

page = pglet.page("my-app", local=True) # this page will start a local Pglet server
page.add(Text('Hello, localhost!'))

console.pglet.io

Pglet hosted service was moved from app.pglet.io domain to console.pglet.io to emphasize the fact that Pglet is a secure web "console" where your backend apps can output reach progress.

Dark theme added and is now default

Pglet provides two built-in themes: dark and light and you can configure custom theme. To set page theme change its theme property, for example:

page = pglet.page("my-app")
page.theme = 'light'
page.update()

Re-connecting client

A serious stabilization work has been done to make Pglet client more resilient to network fluctuations. Now your Pglet app will stay online for many days, reliably connected to Pglet service.

Python package includes executables

Pglet package now includes pglet executables for all platforms, so they are downloaded during the package installation - that better works for corporate or k8s environments without outbound internet access.

ยท 4 min read
Feodor Fitsner
info

After publishing this post on Reddit PowerShell community we received great feedback about security. Currently Pglet service is in preview and is not recommended for use in production. We are working on built-in authentication/authorization functionality at the moment. It's going to be "Login with GitHub/Google/Microsoft" OAuth at first plus OpenID for any other providers.

Normally, to access computer via PowerShell you need to configure PowerShell remoting, open WinRM ports on firewall and, the most unpleasant part, add NAT rule on your router to expose a computer to the entire Internet.

So, how can I securely make a web UI for my script without any port opened on the firewall? I used Pglet - a free open-source service for adding remote UI to your scripts. Pglet acts as a relay between your script and a web browser. Your script "dials" the service and sends UI state updates while web users receive live page updates via WebSockets. Kind of Phoenix LiveView for PowerShell :)

To run the app you need to install pglet module:

Install-Module pglet -Scope CurrentUser -Force

The module works on Windows PowerShell on Windows 10 and PowerShell Core 6+ on Windows, Linux and Mac.

Here is how the app looks like:

Below is the entire program (GitHub):

Import-Module pglet

Connect-PgletApp -Name "ps-console/*" -Web -ScriptBlock {
$ErrorActionPreference = 'stop'

$page = $PGLET_PAGE
$page.Title = "PowerShell Remote Console"
$page.HorizontalAlign = 'stretch'

# Textbox with a command entered
$cmd = TextBox -Placeholder "Type PowerShell command and click Run or press ENTER..." -Width '100%'

# Event handler to call when "Run" button is clicked or Enter pressed
$run_on_click = {
$cmd_text = $cmd.value
if ([string]::IsNullOrWhitespace($cmd_text)) {
return
}

# disable textbox and Run button, add spinner while the command is evaluating
$cmd.value = ''
$command_panel.disabled = $true
$results.controls.insert(0, (Text $cmd_text -BgColor 'neutralLight' -Padding 10))
$results.controls.insert(1, (Spinner))
$page.update()

try {

# run the command
$result = Invoke-Expression $cmd_text

# if result is Array present it as Grid; otherwise Text
if ($result -is [System.Array]) {
$result_control = Grid -Compact -Items $result
} else {
$result_control = Text -Value ($result | Out-String) -Pre -Padding 10
}
} catch {
$result_control = Text -Value "$_" -Pre -Padding 10 -Color 'red'
}

# re-enable controls and replace spinner with the results
$command_panel.disabled = $false
$results.controls.removeAt(1)
$results.controls.insert(1, $result_control)
$page.update()
}

# container for command textbox and Run button
$command_panel = Stack -Horizontal -OnSubmit $run_on_click -Controls @(
$cmd
Button -Text "Run" -Primary -Icon 'Play' -OnClick $run_on_click
)

# results container
$results = Stack

# "main" view combining all controls together
$view = @(
$command_panel
Stack -Controls @(
Stack -Horizontal -VerticalAlign Center -Controls @(
Text 'Results' -Size large
Button -Icon 'Clear' -Title 'Clear results' -OnClick {
$results.controls.clear()
$results.update()
}
)
$results
)
)

# display the "main" view onto the page
$page.add($view)
}

In the program I used just a few Pglet controls: Textbox, Button, Spinner and Stack for the layout. Controls are organized into DOM and every time page.update() is called its state is sent to Pglet service.

When you run the script, a new random URL is generated for your app and printed to the console:

At the very top of the program there is main entry point for the app:

Connect-PgletApp -Name "ps-console/*" -Web -ScriptBlock {
...
}

-Name parameter is a page URL and * means a randomly-generated string. You can add your own prefix to the random string or use another namespace, e.g. my-pages/ps-example-*.

If you want to tweak the app and test it locally, remove -Web parameter and a local Pglet server will be started. There is also self-hosted Pglet server if you need more control.

That's it! More great examples are coming!

ยท 2 min read
Feodor Fitsner

Pglet 0.2.3 adds more chart controls:

  • Pie Chart - demo
  • Line Chart - demo
  • Horizontal Bar Chart - demo

New controls

  • Callout - demo
  • IFrame - demo
  • Header navigation menu (inverted toolbar) - demo

Deep linking

It's now possible to switch between application states (views, areas) by means of URL hash. See how to use it in Deep linking guide.

Other fixes and improvements

  • #13 Deep linking
  • #56 Fixed: VerticalBarChart control: theme colors are not supported in data points
  • #59 iframe control
  • #62 Enhancement - Application Installation Conforms to XDG Specification
  • #65 Line Chart (LineChart) control
  • #67 Horizontal Bar Chart (BarChart) control
  • #69 Pie Chart (PieChart) control
  • #70 Callout control
  • #71 Inverted toolbar button for use in app header
  • #73 Enhancement: configure pglet server options via config file
  • #74 Add host clients authentication with a token
  • #75 Stack control: overflow properties

Give Pglet a try and let us know what you think! There are multiple feedback channels available:

ยท 2 min read
Feodor Fitsner

Pglet 0.2.2 adds the first chart control - VerticalBarChart:

View live demo of VerticalBarChart control

Theming improvements

All color-like attributes in all controls can now accept Fluent UI theme slot colors and "shared" colors.

The list of theme colors can be found on Fluent UI Theme Slots page.

The list of shared colors can be found on Fluent UI Shared Colors page.

For example, you can add an icon with themePrimary color:

add icon name=shop color=themePrimary

Color is being searched in the following order:

  1. Theme slot color
  2. Shared color
  3. Fallback to a named web color or color hex value.

Other fixes and improvements

  • #43 Nav control: unify expanded/collapsed for groups and items
  • #45 ChoiceGroup control: Add "iconColor" property to Option
  • #46 Stack control: add "wrap" property
  • #47 Text control: Markdown mode
  • #48 Chart control: VerticalBarChart
  • #49 Add "trim" attribute to "add" command
  • #52 All color attributes accept theme slot colors and shared colors
  • #53 New control: Image
  • #54 Link control: can contain child controls and other improvements
  • #55 Text control: new "border*" properties

Give Pglet a try and let us know what you think! There are multiple feedback channels available:

ยท 2 min read
Feodor Fitsner

We've just released Pglet 0.2.0!

A ton of new controls were added such as navigation menu, toolbar, grid, tabs, dialog and panel. Now we feel confident Pglet allows to fully unleash your creativity and build a user interface of any complexity!

New features

ARM support

This release adds binaries for Linux ARM and Apple Silicon M1 - Go 1.16 made that possible. Now you can add remote web UI to your Raspberry PI apps or control what's going on in any IoT device.

Docker image

Docker image pglet/server with self-hosted Pglet Server is now available - run it on a VPS server or drop into your Kubernetes cluster.

Theming

Theming in Pglet takes similar approach as in Fluent UI Theme Designer - you choose primary, text, background colors and the theme is auto-magically generated from those colors. To change page theme in Pglet set page control properties: themePrimaryColor, themeTextColor, themeBackgroundColor. Check out Theme demo!

New controls

Improved controls

Button - additional types of Button control were implemented: compound buttons, icon buttons, toolbar, action and link buttons, buttons with context menus and split buttons. Check out Buttons demo!

Text - You can now control the styling of Text control such as color and background as well as border properties and text alignment within it (vertical alignment in center works too!). Check out Text demo!

Other fixes and improvements

  • Controls are based on Fluent UI 8.
  • replace command.
  • Event ticker to avoid hanging event loops.
  • Pglet Server now does not allow remote host clients by default. Remote hosts clients can be enabled with ALLOW_REMOTE_HOST_CLIENTS=true environment variable. Pglet Server Docker image set this variable by default.

Give Pglet a try and let us know what you think! There are multiple feedback channels available:

ยท 4 min read
Feodor Fitsner

Today we are officially launching Pglet!

This is not a groundbreaking event shaking the World and it won't make any ripples on the Internet, but it's still very important milestone for us as it's a good chance to make functionality cut off and present Pglet to the public.

What we've got

You probably won't be able to do a real app with Pglet yet, but we believe it's quite the MVP in a Technical Preview state. The core Pglet functionality is there: pages can be created, controls can be added, modified and removed with live updates streamed to users via WebSockets, page control events triggered by users are broadcasted back to your program - the entire concept's working. We've got basic layout (Stack) and data entry controls (Textbox, Button, etc.) to do simple apps and dashboards, but Fluent UI library, Pglet is based on, is huge and it's a lot more controls to do!

We've got Pglet client bindinds for 4 languages: Python, Bash, PowerShell and Node.js. We chose these languages for MVP to have a good sense of what might be involved in supporting another language. These are scriping non-typed environments mostly, but probably the next binding we do would be Go or C#. Python bindings is the most complete implementation with classes for every control and control event handlers.

We've got Pglet Service which is a hosted Pglet server which you can use right away to bring your web experiences to the web. For technical preview it's just a basic deployment on GAE (will do a separate blog post about that), but quite enough to play with.

The experience

It's been really exciting to work on Pglet during the last 6 months and we learned a lot. Being a C# and mostly Windows developer for more than 15 years it was an absolute pleasure to develop in Go: clean and simple language syntax, goroutines and channels, everything async by design, explicit exceptions management - I'll probably do another post about that experience! Making Pglet UI in React with TypeScript was fun as well: both are fantastic technologies! There is also a challenge to support multiple platforms. Pglet works on Windows, Linux and macOS and you need to constantly think about the experience on all 3 platforms and do a triple amount of tests, CI workflows and other chore things.

What's next

For year 2021 our goal is being able to build and run full-blown backend apps in production. Therefore we are going to work in multiple directions:

Controls

We are going to add more controls and improve existing ones. Pglet is still missing navigation controls like menus, toolbars and tabs. Grid is on top priority, for sure, and it's going to be the huge! Charts will be added as well, so you can build beautiful dashboards.

Pglet Service

This year we are going to bring Pglet Service into production mode with a proper persistence, authentication and account/profile dashboards. All Pglet backend UI is going to be implemented with Pglet.

More docs and examples

We'll be working on providing more Pglet examples, we'll write deployment guides for standalone Pglet apps and self-hosted Pglet Server.

Conclusion

At this stage we are actively looking for any feedback to understand if the project idea is moving in the right direction. We'd be happy to know what would be your requirements, what's missing in Pglet, what's nice or inconvenient, what could be implemented with higher priority.

Feel free to give Pglet a try and let us know what you think! There are multiple feedback channels available:

ยท 5 min read
Feodor Fitsner
Pglet (pronounced as "piglet") empowers DevOps to easily add rich user interface into their internal apps and utilities without any knowledge of HTML, CSS and JavaScript.

The problems of internal apps

Hi, I'm Feodor, the founder of AppVeyor - CI/CD service for software developers.

At AppVeyor, as any other startup, we do a lot of internal apps supporting the core business. Our users don't see those apps. These could be scripts for processing database data, monitoring dashboards, background apps for housekeeping, scheduled scripts for reporting, backend web apps for account management and billing.

Internal apps need User Interface (UI) to present progress/results and grab user input. The simplest form of UI is text console output. Console output can be easily produced from any program or script.

Text output has limitations. It could be hard to present complex structures like hierarhies or visualize the progress of multiple concurrent processes (e.g. copying files in parallel). There is no easy way to fill out the form. Plain text cannot be grouped into collapsible areas. We need rich UI for our internal apps.

Console output can be logged and studied later or you can sit in front of your computer and stare at log "tail". But we want to be mobile. We want to control internal apps from anywhere and any device. We want to share the progress of long-running process with colleagues or send a link to a realt-time dashboard to a manager. Maybe have "Approve" button in the middle of the script to proceed with irreversible actions. We want to collaborate on the results in a real-time. Does it mean we need to build another web app?

Building web apps is hard. Our small team is mostly DevOps. We all do development, deployment and maintenance. We are all good in doing backend coding in different languages: Bash, PowerShell, Python, C#, TypeScript. However, not every team member is a full-stack developer being able to create a web app. Frontend development is a completely different beast: HTTP, TLS, CGI, HTML, CSS, JavaScript, React, Vue, Angular, Svelte, WebPack and so on. Web development today has a steep learning curve.

Building secure web apps is even harder. Internal app works with sensitive company data (databases, keys, credentials, etc.) and presumably hosted in DMZ. You simply can't allow any developer being able to deploy web app with an access to internal resources and available to the whole world.

Pglet to the rescue

Let's say you are the developer responsible for deployment and maintenance of backend services and database - DevOp. You mostly work with Golang and use Bash or Python for writing scripts and tools. Your team asked you to implement a simple real-time dashboard with some metrics from backend services. Dashboard should be accessible outside your org.

Should you do a web app? You don't have much experience of writing web apps. Alright, you know the basics of HTML/CSS, you know how to use StackOverflow, but how do you start with the app? Should it be IIS + FastCGI or Flask, plain HTML + jQuery or React, or something else?

Pglet gives you a page, a set of nice-looking controls and the API to arrange those controls on a page and query their state.

Pglet is the tool that hosts virtual pages for you. Think of a page as a "canvas", a "hub", an "app" where both your programs and users collaborate. Programs use an API to control page contents and listen to the events generated by users. Users view page in their browsers and continuosly receive real-time page updates. When in- API is just plain-text commands like "add column A", "add text B to column A", "get the value of textbox C", "wait until button D is clicked" - it's easy to format/parse strings in any programming language.

Bash-like pseudo-code for a simple app greeting user by the name could look like the following:

# create/connect to a page and return its "handle" (named pipe)
$p = (pglet page connect "myapp")

# display entry form
echo 'add row' > $p
echo 'add col id=form to=row' > $p
echo 'add textbox id=yourName to=form' > $p
echo 'add button id=submit to=form' > $p

# listen for events coming from a page
while read eventName eventTarget < "$p.events"
do
# user fills out the form and clicks "submit" button
if [[ "$eventTarget" == "submit" && "$eventName" == "click" ]]; then

# read textbox value
echo 'get yourName value' > $p
read $yourName < $p

# replace forms contents with the greeting
echo 'clear form' > $p
echo "add text value='Thank you, $yourName!' to=form" > $p
fi
done

You can build a web app in Bash! No HTML, no templates, no spaghetti code. You don't need to care about the design of your internal app - you get fully-featured controls with "standard" look-n-feel. What you care about is the time you need to deliver the required functionality.

Highlights

  • Imperatively program UI with commands.
  • Standard controls: layout, data, form. Skins supported.
  • Fast and simple API via named pipes - call from Bash, PowerShell and any other language.
  • Secure by design. Program makes calls to Pglet to update/query UI. Pglet doesn't have access and knows nothing about internal resources located behind the firewall. Pglet keeps no sensitive data such as connection strings, credentials or certificates.
  • Two types of pages can be hosted:
    • Shared page: multiple programs/scripts can connect to the same page and multiple users can view/interact with the same page.
    • App: a new session is created for every connected user; multiple programs/scripts can serve user sessions (load-balancing).