Create a gist now

Instantly share code, notes, and snippets.

@lecram /escher.py
Last active May 22, 2018

What would you like to do?
This is a toy one-file application to manage persistent key-value string data. The file is *both* the application and its data. When you run any of the commands described in `escher.py --help`, the file will be executed and, after data change, it will rewrite itself with updated data. You can copy the file with whatever name to create multiple d…
#! /usr/bin/env python
"""{escher} -- one-file key-value storage.
What?
This is a toy application to manage persistent key-value string data.
The file {escher} is *both* the application and its data.
When you run any of the commands below, the file will be executed and,
after data change, it will rewrite itself with updated data.
You can copy the file with whatever name to create multiple datasets.
Remember that the data will be copied with the file. Each file must
be readable, writable, and executable.
Why?
I don't know; this is probably useless.
Usage:
Listing current keys:
$ {escher}
Getting the value of the foo key:
$ {escher} foo
(NOTE: If foo is not in the dataset, exit code will be 1.)
Setting the value of foo to bar:
$ {escher} foo bar
Removing the key foo:
$ {escher} foo ""
(NOTE: If foo is not in the dataset, exit code will be 1.)
Removing everything:
$ {escher} --clean
Printing this help message:
$ {escher} --help
"""
from __future__ import print_function
import sys
import os
import pickle
import zlib
import base64
__doc__ = __doc__.format(escher=os.path.basename(__file__))
sep = "--//--"
f = open(__file__, "r")
esc, her = f.read().split(repr(sep), 1)
f.close()
data = pickle.loads(zlib.decompress(base64.b64decode(her[1:].strip())))
args = sys.argv[1:]
print([
lambda : "\n".join(sorted(data.keys())) if data else
sys.exit(),
lambda key : __doc__ if key == "--help" else
not data.clear() and "X *" if key == "--clean" else
data.get(key, False) or
sys.exit("Error: key not found."),
lambda key, value : not data.update([(key, value)]) and
" ".join([key, "<-", value]) if value else
data.pop(key, True) and "X " + key if key in data else
sys.exit("Error: key not found."),
lambda fu, ti, le : print("Error: invalid argument list.") or sys.exit(2)
][min(len(args), 3)](*args[:3]))
her = base64.b64encode(zlib.compress(pickle.dumps(data, 2))).decode('ascii')
out = repr(sep).join([esc, "\n#" + her + "\n"])
with open(__file__, "w") as f: f.write(out)
'--//--'
#eJxrYKotZNADAAaFAZ8=
@mattrobenolt

This comment has been minimized.

Show comment Hide comment
@mattrobenolt

mattrobenolt Dec 14, 2012

There seems to be some issue when running with some concurrency. I did a quick test run with: seq 5000 | xargs -P100 -I% python escher.py foo% % and the file got corrupt.

I conclude that this, sir, is not in fact, web scale.

There seems to be some issue when running with some concurrency. I did a quick test run with: seq 5000 | xargs -P100 -I% python escher.py foo% % and the file got corrupt.

I conclude that this, sir, is not in fact, web scale.

@chewxy

This comment has been minimized.

Show comment Hide comment
@chewxy

chewxy Dec 14, 2012

Clearly it needs more node.js and eventloop/reactor style programming to make it webscale. Also while we're at it, chuck redis in and mongodb or something. Then it'll be webscale.

chewxy commented Dec 14, 2012

Clearly it needs more node.js and eventloop/reactor style programming to make it webscale. Also while we're at it, chuck redis in and mongodb or something. Then it'll be webscale.

@mdda

This comment has been minimized.

Show comment Hide comment
@mdda

mdda Dec 14, 2012

One thing I found when using this to replace my MongoDB installation is that it doesn't like '}' characters in the values (or keys). Pity. I don't see how this can get to be webscale without javascript compatibility.

mdda commented Dec 14, 2012

One thing I found when using this to replace my MongoDB installation is that it doesn't like '}' characters in the values (or keys). Pity. I don't see how this can get to be webscale without javascript compatibility.

@shenanigans

This comment has been minimized.

Show comment Hide comment
@shenanigans

shenanigans Dec 14, 2012

I thought you were just supposed to say "Hadoop" three times and drop your wallet on the floor?

I thought you were just supposed to say "Hadoop" three times and drop your wallet on the floor?

@shabda

This comment has been minimized.

Show comment Hide comment
@shabda

shabda Dec 14, 2012

@chewxy

, chuck redis in and mongodb or something.

Chuck Norris in and mongodb or something.

shabda commented Dec 14, 2012

@chewxy

, chuck redis in and mongodb or something.

Chuck Norris in and mongodb or something.

@Ivanca

This comment has been minimized.

Show comment Hide comment
@Ivanca

Ivanca Dec 14, 2012

I can see why you are programmers and not comedians.

Ivanca commented Dec 14, 2012

I can see why you are programmers and not comedians.

@kennethreitz

This comment has been minimized.

Show comment Hide comment
@kennethreitz

kennethreitz Dec 14, 2012

Haha, I wrote one of these myself, several years ago:

https://gist.github.com/477550

Haha, I wrote one of these myself, several years ago:

https://gist.github.com/477550

@lecram

This comment has been minimized.

Show comment Hide comment
@lecram

lecram Dec 14, 2012

@mdda
I couldn't reproduce any problem with '}' characters. Perhaps your shell uses then for substitution? Did you try enclosing the arguments in quotes? Can you show an example that doesn't work so I can try to fix it?

Owner

lecram commented Dec 14, 2012

@mdda
I couldn't reproduce any problem with '}' characters. Perhaps your shell uses then for substitution? Did you try enclosing the arguments in quotes? Can you show an example that doesn't work so I can try to fix it?

@saml

This comment has been minimized.

Show comment Hide comment
@saml

saml Dec 15, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment