How to define and use a custom ID generator?¶
By default, Kinto uses UUID4 as id
for its records. In some cases, it might
not be what you want. But you’re not out of luck, there is a way to configure
Kinto to use a different id_generator
than the default one.
Let’s define a “name generator”, which will output 8 random characters (uppercase or lowercase).
import random
import string
from kinto.core.storage import generators
class NameGenerator(generators.Generator):
regexp = r'^[a-zA-Z0-9-_]{8}$'
def __call__(self):
ascii_letters = ('abcdefghijklmopqrstuvwxyz'
'ABCDEFGHIJKLMOPQRSTUVWXYZ')
alphabet = ascii_letters + string.digits + '-_'
letters = [random.choice(ascii_letters + string.digits)]
letters += [random.choice(alphabet) for x in range(7)]
return ''.join(letters)
Note that you actually need to define both the generator and the validator, which can be provided as a regexp.
Important
The id generator should be random enough to avoid collisions.
The random approach here serves the purpose of this tutorial, but for a production ready implementation, have a look at dylang/shortid for example.
Enable in configuration¶
Okay, once we’ve got this new generator, we can put it in a file named
name_generator.py
, and then configure the Kinto server to use this
generator to actually generate the record IDs.
In your config/kinto.ini
configuration file, set the kinto.id_generator
setting:
kinto.id_generator = name_generator.NameGenerator
And then run your server as usual
$ kinto start --ini config/kinto.ini
Now, if you try to generate a new record, you should have the new ID used, well done!
$ echo '{"data": {"yeah": "oh"}}' | http POST http://localhost:8888/v1/buckets/default/collections/tasks/records --auth user:pass
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff
Content-Length: 171
Content-Type: application/json; charset=UTF-8
Date: Thu, 25 Feb 2016 22:13:20 GMT
Server: waitress
{
"data": {
"id": "fm64GtdA",
"last_modified": 1456438400719,
"yeah": "oh"
},
"permissions": {
"write": [
"basicauth:2025f72e6967625e3e878288b55d8946839e51968d11991b8a7dd0f040d4b6f0"
]
}
}
If you need to define different name generator per type of object, the setting name must be prefixed by the object type. For example:
kinto.bucket_id_generator = name_generator.BucketNameGenerator
kinto.group_id_generator = name_generator.GroupNameGenerator
kinto.collection_id_generator = name_generator.CollectionNameGenerator
kinto.record_id_generator = kinto.core.storage.generators.UUID4
Kinto.js client¶
The offline-first client Kinto/kinto.js can also be configured to generate custom ids. See its documentation for more details.