kademlia package

The best place to start is the examples folder before diving into the API.

kademlia.crawling module

class kademlia.crawling.NodeSpiderCrawl(protocol, node, peers, ksize, alpha)[source]

Bases: kademlia.crawling.SpiderCrawl

Create a new C{SpiderCrawl}er.

Parameters:
  • protocol – A KademliaProtocol instance.
  • node – A Node representing the key we’re looking for
  • peers – A list of Node instances that provide the entry point for the network
  • ksize – The value for k based on the paper
  • alpha – The value for alpha based on the paper
find()[source]

Find the closest nodes.

class kademlia.crawling.RPCFindResponse(response)[source]

Bases: object

A wrapper for the result of a RPC find.

Parameters:response – This will be a tuple of (<response received>, <value>) where <value> will be a list of tuples if not found or a dictionary of {‘value’: v} where v is the value desired
getNodeList()[source]

Get the node list in the response. If there’s no value, this should be set.

getValue()[source]
happened()[source]

Did the other host actually respond?

hasValue()[source]
class kademlia.crawling.SpiderCrawl(protocol, node, peers, ksize, alpha)[source]

Bases: object

Crawl the network and look for given 160-bit keys.

Create a new C{SpiderCrawl}er.

Parameters:
  • protocol – A KademliaProtocol instance.
  • node – A Node representing the key we’re looking for
  • peers – A list of Node instances that provide the entry point for the network
  • ksize – The value for k based on the paper
  • alpha – The value for alpha based on the paper
class kademlia.crawling.ValueSpiderCrawl(protocol, node, peers, ksize, alpha)[source]

Bases: kademlia.crawling.SpiderCrawl

find()[source]

Find either the closest nodes or the value requested.

kademlia.log module

class kademlia.log.FileLogObserver(f=None, level=3, default=4)[source]

Bases: twisted.python.log.FileLogObserver

emit(eventDict)[source]
class kademlia.log.Logger(**kwargs)[source]
critical(message, **kw)[source]
debug(message, **kw)[source]
error(message, **kw)[source]
info(message, **kw)[source]
msg(message, **kw)[source]
warning(message, **kw)[source]

kademlia.network module

Package for interacting on the network at a high level.

class kademlia.network.Server(ksize=20, alpha=3, id=None, storage=None)[source]

Bases: object

High level view of a node instance. This is the object that should be created to start listening as an active node on the network.

Create a server instance. This will start listening on the given port.

Parameters:
  • ksize (int) – The k parameter from the paper
  • alpha (int) – The alpha parameter from the paper
  • id – The id for this node on the network.
  • storage – An instance that implements IStorage
bootstrap(addrs)[source]

Bootstrap the server by connecting to other known nodes in the network.

Parameters:addrs – A list of (ip, port) tuple pairs. Note that only IP addresses are acceptable - hostnames will cause an error.
bootstrappableNeighbors()[source]

Get a list of (ip, port) tuple pairs suitable for use as an argument to the bootstrap method.

The server should have been bootstrapped already - this is just a utility for getting some neighbors and then storing them if this server is going down for a while. When it comes back up, the list of nodes can be used to bootstrap.

get(key)[source]

Get a key if the network has it.

Returns:None if not found, the value otherwise.
inetVisibleIP()[source]

Get the internet visible IP’s of this node as other nodes see it.

Returns:A list of IP’s. If no one can be contacted, then the list will be empty.
listen(port)[source]

Start listening on the given port.

This is the same as calling:

reactor.listenUDP(port, server.protocol)
classmethod loadState(fname)[source]

Load the state of this node (the alpha/ksize/id/immediate neighbors) from a cache file with the given fname.

refreshTable()[source]

Refresh buckets that haven’t had any lookups in the last hour (per section 2.3 of the paper).

saveState(fname)[source]

Save the state of this node (the alpha/ksize/id/immediate neighbors) to a cache file with the given fname.

saveStateRegularly(fname, frequency=600)[source]

Save the state of node with a given regularity to the given filename.

Parameters:
  • fname – File name to save retularly to
  • frequencey – Frequency in seconds that the state should be saved. By default, 10 minutes.
set(key, value)[source]

Set the given key to the given value in the network.

kademlia.node module

class kademlia.node.Node(id, ip=None, port=None)[source]
__iter__()[source]

Enables use of Node as a tuple - i.e., tuple(node) works.

distanceTo(node)[source]

Get the distance between this node and another.

sameHomeAs(node)[source]
class kademlia.node.NodeHeap(node, maxsize)[source]

Bases: object

A heap of nodes ordered by distance to a given node.

Constructor.

@param node: The node to measure all distnaces from. @param maxsize: The maximum size that this heap can grow to.

allBeenContacted()[source]
getIDs()[source]
getNodeById(id)[source]
getUncontacted()[source]
markContacted(node)[source]
popleft()[source]
push(nodes)[source]

Push nodes onto heap.

@param nodes: This can be a single item or a C{list}.

remove(peerIDs)[source]

Remove a list of peer ids from this heap. Note that while this heap retains a constant visible size (based on the iterator), it’s actual size may be quite a bit larger than what’s exposed. Therefore, removal of nodes may not change the visible size as previously added nodes suddenly become visible.

kademlia.protocol module

class kademlia.protocol.KademliaProtocol(sourceNode, storage, ksize)[source]

Bases: rpcudp.protocol.RPCProtocol

callFindNode(nodeToAsk, nodeToFind)[source]
callFindValue(nodeToAsk, nodeToFind)[source]
callPing(nodeToAsk)[source]
callStore(nodeToAsk, key, value)[source]
getRefreshIDs()[source]

Get ids to search for to keep old buckets up to date.

handleCallResponse(result, node)[source]

If we get a response, add the node to the routing table. If we get no response, make sure it’s removed from the routing table.

rpc_find_node(sender, nodeid, key)[source]
rpc_find_value(sender, nodeid, key)[source]
rpc_ping(sender, nodeid)[source]
rpc_store(sender, nodeid, key, value)[source]
rpc_stun(sender)[source]
transferKeyValues(node)[source]

Given a new node, send it all the keys/values it should be storing.

@param node: A new node that just joined (or that we just found out about).

Process: For each key in storage, get k closest nodes. If newnode is closer than the furtherst in that list, and the node for this server is closer than the closest in that list, then store the key/value on the new node (per section 2.5 of the paper)

kademlia.routing module

class kademlia.routing.KBucket(rangeLower, rangeUpper, ksize)[source]

Bases: object

addNode(node)[source]

Add a C{Node} to the C{KBucket}. Return True if successful, False if the bucket is full.

If the bucket is full, keep track of node in a replacement list, per section 4.1 of the paper.

depth()[source]
getNodes()[source]
hasInRange(node)[source]
head()[source]
isNewNode(node)[source]
removeNode(node)[source]
split()[source]
touchLastUpdated()[source]
class kademlia.routing.RoutingTable(protocol, ksize, node)[source]

Bases: object

@param node: The node that represents this server. It won’t be added to the routing table, but will be needed later to determine which buckets to split or not.

addContact(node)[source]
findNeighbors(node, k=None, exclude=None)[source]
flush()[source]
getBucketFor(node)[source]

Get the index of the bucket that the given node would fall into.

getLonelyBuckets()[source]

Get all of the buckets that haven’t been updated in over an hour.

isNewNode(node)[source]
removeContact(node)[source]
splitBucket(index)[source]
class kademlia.routing.TableTraverser(table, startNode)[source]

Bases: object

next()[source]

Pop an item from the left subtree, then right, then left, etc.

kademlia.storage module

class kademlia.storage.ForgetfulStorage(ttl=604800)[source]

Bases: object

By default, max age is a week.

__getitem__(key)[source]
__setitem__(key, value)[source]
cull()[source]
get(key, default=None)[source]
iteritems()[source]
iteritemsOlderThan(secondsOld)[source]
interface kademlia.storage.IStorage[source]

Bases: zope.interface.Interface

Local storage for this node.

iteritemsOlderThan(secondsOld)[source]

Return the an iterator over (key, value) tuples for items older than the given secondsOld.

__setitem__(key, value)[source]

Set a key to the given value.

iteritems()[source]

Get the iterator for this storage, should yield tuple of (key, value)

classmethod __getitem__()[source]

Return the attribute description for the given name.

classmethod get()[source]

Query for an attribute description

kademlia.utils module

General catchall for functions that don’t make sense as methods.

class kademlia.utils.OrderedSet[source]

Bases: list

push(thing)[source]
kademlia.utils.deferredDict(d)[source]

Just like a C{defer.DeferredList} but instead accepts and returns a C{dict}.

@param d: A C{dict} whose values are all C{Deferred} objects.

@return: A C{DeferredList} whose callback will be given a dictionary whose keys are the same as the parameter C{d}’s and whose values are the results of each individual deferred call.

kademlia.utils.digest(s)[source]
kademlia.utils.sharedPrefix(args)[source]

Find the shared prefix between the strings.

For instance, sharedPrefix([‘blahblah’, ‘blahwhat’]) is ‘blah’.