Sumukh Barve

Polydojo Founder's blog on Software, Business and more.


2020-11-16

Hello, World!

I'm Sumukh, the Founder and CEO of Polydojo. We're the folks behind Polydojo.com and BoardBell.com. Last month, we decided to ramp-up our contributions to the open source software community.

In this blog post, I'll describe our newly released FOSS projects, and give you an idea of what's to come.

ViloLog: Blogging Platform

In keeping with software engineering tradition, we begin each project with "Hello, World!". Hence the title of this post. But aside from tradition, there's another reason behind the that title: ViloLog is saying hello too!

ViloLog is our new open source blogging engine. This blog, the one you're currently reading, is powered by it. It's is a bit like Jekyll, in that it's simple and Markdown based. But it's backed by a database, not the file system.

Why not Jekyll?

Because non-developers aren't comfortable with Git. Instead of git push, isn't it easier to just click 'Save'?

Why not Wordpress?

Because Wordpress is a bit too bloated for our taste. Also, our team isn't a big fan of PHP.

There's another reason behind building ViloLog. Let's circle back to it at the end.

Dotsi: Dot-Accessible Python Dicts

At Polydojo, use just two languages. Python on the back-end, JavaScript on the front. Plain JavaScript objects are super-easy to create (just {}) and they fully support dot-notation. Wouldn't it be nice if Python dictionaries supported dot-notation too? With Dotsi, they do!

Here's Dotsi in action, in an interactive Python shell:

>>> import dotsi
>>> 
>>> d = dotsi.fy({"foo": {"bar": "baz"}})  # Dict in Dict
>>> d.foo.bar
'baz'
>>> d.users = [{"id": 0, "name": "Alice"}] # Dict in List
>>> d.users[0].name
'Alice'
>>> 

Note that dot-notation can be used with nested dicts, including with those nested within lists. Alternative libraries like EasyDict/Addict also provide dot-notation for dicts, but don't accommodate dicts nested within lists.

Vilo: Multi-App Web Framework

Vilo is a simple, lightweight Python web framework for building WSGI apps. It's especially helpful if you're looking to create multiple, entirely isolated apps.

Here's a super-tiny Vilo app:

import vilo;                # Import vilo
app = vilo.buildApp();      # Create app

@app.route("GET", "/")      # Add route
def get_homepage (req, res):
    return "Hello, World!";

wsgi = app.wsgi;            # WSGI callable

You may have noticed that the above snippet is quite similar to a Flask/Bottle app. But did you notice the route handler's req (request) and res (response) parameters? Instead of relying on globals, they're explicitly supplied to each route handler.

Why not Flask/Bottle?

Flask and Bottle are both great. Unlike Django, they're lightweight, unopinionated and flexible; which is largely why we like them. But they require us to rely on globals like request, g, and/or response.

If you're building a single app, globals can be very handy. But if you're looking to build and deploy multiple (entirely isolated) apps, having to deal with automatically context-aware globals seems eerily magical.

PogoDB: NoSQL Postgres Wrapper

PogoDB is a wrapper around Postgres' JSONB type. With JSONB, Postgres is no longer just a SQL database. It's NoSQL too! You can use it for storing pretty much any JSON-serializable object.

Here's a quick taste of PogoDB:

# Insert a document:
db.insertOne({
  "_id":"a", "author":"Alice", "text":"AA", "rank":0,
})

# Insert more:
db.insertMany([
  {"_id":"b", "author":"Becci", "text":"BB", "rank":1},
  {"_id":"d", "author":"Alice", "text":"DD", "rank":1},
]);

# Find a document authored by Becci:
db.findOne({"author": "Becci"})

# Find ALL documents authored by Alice:
db.find({"author": "Alice"})

Of course, update, delete, increment etc. operations are also supported. And you can even customize queries with raw SQL clauses. Check out the docs for more.

Qree: Simple Templating Engine

Qree (read 'Curie') is a tiny but mighty Python templating engine, geared toward HTML. Instead of using regular expressions or PEGs, Qree relies on Python's exec() and eval(). Thus, it supports all language features, out of the box.

Here's a quick taste of Qree:

qree.renderStr("<h2>Hello, {{: data :}}", data="World!")
# Output: <h2>Hello, World!</h2>

qree.renderStr("<h2>Mr. {{: data.title() + "!" :}}", data="bond")
# Output: <h2>Mr. Bond!</h2>

qree.renderStr("<h2>Mr. {{: data :}}", data="<b> Villain </b> ")
# Output: <h2>Mr. &lt;b&gt; Villain &lt;/b&gt; </h2>

Of course, loops and conditionals are fully supported. For example:

qree.renderStr("""
@= for n in range(1, data + 1):
@{
  {{: n :}} is {{: 'EVEN' if n % 2 == 0 else 'ODD' :}}
@}
""", data=4)

Output:

  1 is ODD
  2 is EVEN
  3 is ODD
  4 is EVEN

You might have noticed that Qree HTML-escapes anything that goes between {{: and :}} tags; and that it relies on @{ and @} for inferring indentation. Check out the docs to know more.

Circling Back To ViloLog

ViloLog is built using the Vilo web framework, PogoDB database wrapper and Qree templating engine. Plus, it uses Dotsi too!

In addition to avoiding Jekyll and Wordpress, a major motivation behind building ViloLog is that it serves as a sample application for Vilo and PogoDB.

As ViloLog depends on every other project listed above, it's the youngest and most nascent of them all.

What's Next?

In the past month or so, we've released five new FOSS projects. Except ViloLog, which is still nascent, all of them are reasonably documented. Where do we go from here?

But of course, we'll continue to work on each project. And in addition to our own projects, we hope to soon start making contributions to other projects too.

We've also started exploring open source business models. While I can't say if we'll end up launching a COSS product, the idea certainly is interesting.

Stay Tuned

At Polydojo, our adventures in software shall continue. I'll keep writing software, and blog posts too! So stay tuned. If you have any questions or comments, please feel free to reach me at [email protected].


Next: Build Your Own Python Template Engine