pydle - a Pythonic, extensible, compliant IRC library

pydle is a compact, flexible and standards-abiding IRC library for Python 3, written out of frustration with existing solutions.

Features

  • Well-organized, easily extensible

    Thanks to the modular setup, pydle’s functionality is seperated in modules according to the standard they were defined in. This makes specific functionality trivial to find and decreases unwanted coupling, as well as allowing users to pick-and-choose the functionality they need.

    No spaghetti code.

  • Compliant

    pydle contains modules, or “features” in pydle terminology, for almost every relevant IRC standard:

    • RFC1459: The standard that defines the basic functionality of IRC - no client could live without.
    • TLS: Support for chatting securely using TLS encryption.
    • CTCP: The IRC Client-to-Client Protocol, allowing clients to query eachother for data.
    • ISUPPORT: A method for the server to indicate non-standard or extended functionality to a client, and for clients to activate said functionality if needed.
    • WHOX: Easily query status information for a lot of users at once.
    • IRCv3.1: An ongoing effort to bring the IRC protocol to the twenty-first century, featuring enhancements such as extended capability negotiation and SASL authentication.
    • IRCv3.2 (in progress): The next, in-development iteration of IRCv3. Features among others advanced message tagging, a generalized metadata system, and online status monitoring.

    No half-assing functionality.

  • Asynchronous

    IRC is an asychronous protocol; it only makes sense a clients that implements it is asynchronous as well. Built on top of the wonderful Tornado library, pydle relies on proven technologies to deliver proper high-performance asynchronous functionality and primitives. pydle allows using Futures to make asynchronous programming just as intuitive as doing regular blocking operations.

    No callback spaghetti.

  • Liberally licensed

    The 3-clause BSD license ensures you can use pydle whenever, for what purpose you want.

    No arbitrary restrictions.

Contents

Introduction to pydle

What is pydle?

pydle is an IRC library for Python 3.2 and up.

Although old and dated on some fronts, IRC is still used by a variety of communities as the real-time communication method of choice, and the most popular IRC networks can still count on tens of thousands of users at any point during the day.

pydle was created out of perceived lack of a good, Pythonic, IRC library solution that also worked with Python 3. It attempts to follow the standards properly, while also having functionality for the various extensions to the protocol that have been made over the many years.

What isn’t pydle?

pydle is not an end-user IRC client. Although a simple client may be trivial to implement using pydle, pydle itself does not seek out to be a full-fledged client. It does, however, provide the building blocks to which you can delegate most, if not all, of your IRC protocol headaches.

pydle also isn’t production-ready: while the maintainers try their utmost best to keep the API stable, pydle is still in heavy development, and APIs are prone to change or removal at least until version 1.0 has been reached.

Requirements

Most of pydle is written in pure, portable Python that only relies on the standard library. However, pydle relies on Tornado to do the heavy lifting on the asynchronous front. Optionally, if you plan to use pydle’s SASL functionality for authentication, the excellent pure-sasl library is required.

All dependencies can be installed using the standard package manager for Python, pip, and the included requirements file:

pip install -r requirements.txt

Compatibility

pydle works in any interpreter that implements Python 3.2 or higher. Although mainly tested in CPython, the standard Python implementation, there is no reason why pydle itself should not work in alternative implementations like PyPy, as long as they support the Python 3.2 language requirements.

Using pydle

Note

This section covers basic use of pydle. To see the full spectrum of what pydle is capable of, refer to the API reference.

A simple client

The most basic way to use pydle is instantiating a pydle.Client object, connecting it to a server and having it handle messages forever using pydle.Client.handle_forever(). pydle will automatically take care of ensuring that the connection persists, and will reconnect if for some reason disconnected unexpectedly.

import pydle

client = pydle.Client('MyBot')
# Client.connect() is a blocking function.
client.connect('irc.freenode.net', tls=True)
client.handle_forever()

Adding functionality

Of course, the above client doesn’t really do much, except idling and error recovery. To truly start adding functionality to the client, subclass pydle.Client and override one or more of the IRC callbacks.

import pydle

class MyClient(pydle.Client):
    """ This is a simple bot that will greet people as they join the channel. """

    def on_connect(self):
        super().on_connect()
        # Can't greet many people without joining a channel.
        self.join('#kochira')

    def on_join(self, channel, user):
        super().on_join(channel, user)
        self.message(channel, 'Hey there, {user}!', user=user)

client = MyClient('MyBot')
client.connect('irc.freenode.net', tls=True)
client.handle_forever()

This trivial example shows a few things:

  1. pydle.Client.on_connect() is a callback that gets invoked as soon as the client is fully connected to the server.
  2. pydle.Client.on_join() is a callback that gets invoked whenever a user joins a channel.
  3. Trivially enough, we can use pydle.Client.join() to instruct the client to join a channel.
  4. Finally, we can use pydle.Client.message() to send a message to a channel or to a user; it will even format the message for us according to advanced string formatting.

Hint

It is recommended to call the callbacks of the parent class using super(), to make sure whatever functionality implemented by your parent classes gets called too: pydle will gracefully handle the call even if no functionality was implemented or no callbacks overridden.

Multiple servers, multiple clients

Any pydle client instance can only be connected to a single server. That doesn’t mean that you are restricted to only being active on a single server at once, though. Using a pydle.ClientPool, you can instantiate multiple clients, connect them to different servers using pydle.ClientPool.connect(), and handle them within a single loop.

import pydle

class MyClient(pydle.Client):
    """ This is a simple bot that will greet people as they join the channel. """

    def on_connect(self):
        super().on_connect()
        # Can't greet many people without joining a channel.
        self.join('#kochira')

    def on_join(self, channel, user):
        super().on_join(channel, user)
        self.message(channel, 'Hey there, {user}!', user=user)

# Setup pool and connect clients.
pool = pydle.ClientPool()
servers = [ 'irc.freenode.net', 'irc.rizon.net', 'irc.esper.net' ]

for server in servers:
    client = pydle.Client('MyBot')
    pool.connect(client, server, tls=True)

# Handle all clients in the pool at once.
pool.handle_forever()

Warning

While multiple pydle.ClientPool instances can be created and ran, you should ensure a client is only active in a single pydle.ClientPool at once. Being active in multiple pools can lead to strange things like receiving messages twice, or interleaved outgoing messages.

Mixing and matching

Thanks to pydle’s modular “feature” system, you don’t have to support everything you want to support. You can choose just to select the options you think you need for your client by using pydle.featurize() to create a base class out of the featured you need.

import pydle

# Create a client that just supports the base RFC1459 spec, CTCP and an IRC services-style account system.
MyBaseClient = pydle.featurize(pydle.features.RFC1459Support, pydle.features.CTCPSupport, pydle.features.AccountSupport)

class MyClient(MyBaseClient):
    ...

A list of all available built-in features and their use can be found at the API reference.

In addition to this, you can of course also write your own features. Feature writing is discussed thoroughly in the feature section. Once you have written a feature, you can just featurize it on top of an existing client class.

import pydle
import vendor

# Add vendor feature on top of the base client.
MyBaseClient = pydle.featurize(pydle.Client, vendor.VendorExtensionSupport)

class MyClient(MyBaseClient):
    ...

Asynchronous functionality

Some actions inevitably require blocking and waiting for a result. Since pydle is an asynchronous library where a client runs in a single thread, doing this blindly could lead to issues like the operation blocking the handling of messages entirely.

Fortunately, pydle implements coroutines which allow you to handle a blocking operation almost as if it were a regular operation, while still retaining the benefits of asynchronous program flow. Coroutines allow pydle to be notified when a blocking operation is done, and then resume execution of the calling function appropriately. That way, blocking operations do not block the entire program flow,

In order for a function to be declared as a coroutine, it has to be decorated using the pydle.coroutine() decorator. It can then call functions that would normally block using Python’s yield operator. Since a function that calls a blocking function is itself blocking too, it has to be declared a coroutine as well.

Hint

As with a lot of things, documentation is key. Documenting that your function does blocking operations lets the caller know how to call the function, and to include the fact that it calls blocking operations in its own documentation for its own callers.

For example, if you are implementing an administrative system that works based off nicknames, you might want to check if the users are identified to NickServ. However, WHOISing a user using pydle.Client.whois() would be a blocking operation. Thanks to coroutines and pydle.Client.whois() being a blocking operation compatible with coroutines, the act of WHOISing will not block the entire program flow of the client.

import pydle
ADMIN_NICKNAMES = [ 'Shiz', 'rfw' ]

class MyClient(pydle.Client):
    """
    This is a simple bot that will tell you if you're an administrator or not.
    A real bot with administrative-like capabilities would probably be better off maintaining a cache
    that would be invalidated upon parting, quitting or changing nicknames.
    """

    def on_connect(self):
        super().on_connect()
        self.join('#kochira')

    @pydle.coroutine
    def is_admin(self, nickname):
        """
        Check whether or not a user has administrative rights for this bot.
        This is a blocking function: use a coroutine to call it.
        See pydle's documentation on blocking functionality for details.
        """
        admin = False

        # Check the WHOIS info to see if the source has identified with NickServ.
        # This is a blocking operation, so use yield.
        if source in ADMIN_NICKNAMES:
            info = yield self.whois(source)
            admin = info['identified']

        return admin

    @pydle.coroutine
    def on_message(self, target, source, message):
        super().on_message(target, source, message)

        # Tell a user if they are an administrator for this bot.
        if message.startswith('!adminstatus'):
            admin = yield self.is_admin(source)

            if admin:
                self.message(target, '{source}: You are an administrator.', source=source)
            else:
                self.message(target, '{source}: You are not an administrator.', source=source)

Writing your own blocking operation that can work with coroutines is trivial: just make your blocking method return a pydle.Future instance (without the act of creating and returning the Future itself being blocking), and any coroutine yielding it will halt execution until the returned future is resolved, using either pydle.Future.set_result() or pydle.Future.set_exception(), while pydle can still handle everything else.

Features

pydle’s main IRC functionality is divided into seperate modular components called “features”. These features allow you to mix and match your client to fit exactly to your requirements, as well as provide an easy way to extend pydle yourself, without having to dive into the source code.

Built-in features

The following features are packaged with pydle and live in the pydle.features namespace.

RFC1459

API: pydle.features.RFC1459Support

RFC1459 is the bread and butter of IRC: it is the standard that defines the very base concepts of the IRC protocol, ranging from what a channel is to the basic commands to channel limits. If you want your client to have actually any useful IRC functionality, it is recommend to include this feature.

Transport Layer Security (TLS)

API: pydle.features.TLSSupport

Support for secure connections to the IRC server using Transport Layer Security.

This allows, if the server supports it, for encrypted connections between the server and the client, to prevent snooping and provide two-way authentication: both for the server to ensure its identity to the client, and for the client to ensure its identity to the server. The latter can also be used in certain service packages to automatically identify to the user account.

In order to connect to a TLS-enabled server, supply tls=True to pydle.features.TLSSupport.connect().

Hint

pydle does not verify server-side TLS certificates by default; to enable certificate verification, supply tls_verify=True to pydle.features.TLSSupport.connect() as well.

In order to supply a client certificate, pydle.features.TLSSupport takes 3 additional constructor parameters:

  • tls_client_cert: A path to the TLS client certificate.
  • tls_client_cert_key: A path to the TLS client certificate key.
  • tls_client_cert_password: The optional password for the certificate key.
Client-to-Client Protocol (CTCP)

API: pydle.features.CTCPSupport

Support for encapsulation of out-of-band features into standard IRC messages using the Client-to-Client Protocol.

This allows you to send meta-messages to other users, requesting e.g. their local time, client version, and more, and respond to such requests. It adds pydle.Client.ctcp(target, query, contents=None), which allows you to send a CTCP request to a target, and pydle.Client.ctcp_reply(target, query, contents=None), which allows you to respond to CTCP requests.

In addition, it registers the pydle.Client.on_ctcp(from, query, contents) hook, which allows you to act upon any CTCP request, and a per-type hook in the form of pydle.Client.on_ctcp_<type>(from, contents), which allows you to act upon CTCP requests of type type. type will always be lowercased. A few examples of type can be: action, time, version.

Finally, it registers the pydle.Client.on_ctcp_reply(from, queyr, contents) hook, which acts similar to the above hook, except it is triggered when the client receives a CTCP response. It also registers pydle.Client.on_ctcp_<type>_reply, which works similar to the per-type hook described above.

Server-side Extension Support (ISUPPORT)

API: pydle.features.ISUPPORTSupport

Support for IRC protocol extensions using the ISUPPORT message.

This feature allows pydle to support protocol extensions which are defined using the non-standard ISUPPORT (005) message. It includes built-in support for a number of popular ISUPPORT-based extensions, like CASEMAPPING, CHANMODES, NETWORK and PREFIX.

It also provides the generic pydle.Client.on_isupport_type(value) hook, where type is the type of ISUPPORT-based extension that the server indicated support for, and value is the optional value of said extension, or None if no value was present.

Account System

API: pydle.features.AccountSupport

Support for a generic IRC account system.

Most IRC networks have some kind of account system that allows users to register and manage their nicknames and personas. This feature provides additional support in pydle for this idea and its integration into the networks.

Currently, all it does is set the identified and account fields when doing a WHOIS query (pydle.Client.whois(user)) on someone, which indicate if the target user has identified to their account, and if such, their account name, if available.

Extended User Tracking

API: pydle.features.WHOXSupport

Support for better user tracking using WHOX.

This feature allows pydle to perform more accurate tracking of usernames, idents and account names, using the WHOX IRC extension. This allows pydle’s internal user database to be more accurate and up-to-date.

IRCv3

API: pydle.features.IRCv3Support

A shortcut for IRCv3.1 and IRCv3.2 support; see below.

IRCv3.1

API: pydle.features.IRCv3_1Support

IRCv3.1 support.

The `IRCv3 Working Group`_ is a working group organized by several network, server author, and client author representatives with the intention to standardize current non-standard IRC practices better, and modernize certain parts of the IRC protocol. The IRCv3 standards are specified as a bunch of extension specifications on top of the last widely-used IRC version, IRC v2.7, also known as RFC1459.

The IRCv3.1 specification adds useful features to IRC from a client perspective, including SASL authentication, support for indicating when a user identified to their account, and indicating when a user went away from their PC.

Including this feature entirely will activate all IRCv3.1 functionality for pydle. You can also opt-in to only select the two major features of IRCv3.1, the capability negotiation framework and SASL authentication support, as described below, by only including their features.

Capability Negotiation Support

API: pydle.features.ircv3.CapabilityNegotiationSupport

Support for capability negotiation for IRC protocol extensions.

This feature enables support for a generic framework for negotiationg IRC protocol extension support between the client and the server. It was quickly found that ISUPPORT alone wasn’t sufficient, as it only advertises support from the server side instead of allowing the server and client to negotiate. This is a generic base feature: enabling it on its own won’t do much, instead other features like the IRCv3.1 support feature, or the SASL authentication feature will rely on it to work.

This feature adds three generic hooks for feature authors whose features makes use of capability negotiation:

  • pydle.Client.on_capability_<cap>_available(value): Called when the server indicates capability cap is available.

    Is passed a value as given by the IRC server, or None if no value was given Should return either a boolean indicating whether or not to request the capability, or a string indicating to request the capability with the returned value.

  • pydle.Client.on_capability_<cap>_enabled(): Called when the server has acknowledged the request of capability cap, and it

    has been enabled. Should return one of three values: pydle.CAPABILITY_NEGOTIATING when the capability will be further negotiated, pydle.CAPABILITY_NEGOTIATED when the capability has been negotiated successfully, or pydle.CAPABILITY_FAILED when negotiation of the capability has failed. If the function returned pydle.CAPABILITY_NEGOTIATING, it has to call pydle.Client.capability_negotiated(cap, success=True) when negotiating is finished.

  • pydle.Client.on_capability_<cap>_disabled(): Called when a previously-enabled capability cap has been disabled.

User Authentication Support (SASL)

API: pydle.features.ircv3.SASLSupport

Support for user authentication using SASL.

This feature enables users to identify to their network account using the SASL protocol and practices. Three extra arguments are added to the pydle.Client constructor:

  • sasl_username: The SASL username.
  • sasl_password: The SASL password.
  • sasl_identity: The identity to use. Default, and most common, is ''.

These arguments are also set as attributes.

Currently, pydle’s SASL support requires on the Python pure-sasl package and is limited to support for the PLAIN mechanism.

IRCv3.2

API: pydle.features.IRCv3_2Support

Support for the IRCv3.2 specification.

The IRCv3.2 specification is the second iteration of specifications from the `IRCv3 Working Group`_. This set of specification is still under development, and may change at any time. pydle’s support is conservative, likely incomplete and to-be considered experimental.

pydle currently supports the following IRCv3.2 extensions:

As with the IRCv3.1 features, using this feature enables all of pydle’s IRCv3.2 support. A user can also opt to only use individual large IRCv3.2 features by using the features below.

Online Status Monitoring

API: pydle.features.ircv3.MonitoringSupport

Support for monitoring a user’s online status.

This feature allows a client to monitor the online status of certain nicknames. It adds the pydle.Client.monitor(nickname) and pydle.Client.unmonitor(nickname) APIs to add and remove nicknames from the monitor list.

If a monitored user comes online, pydle.Client.on_user_online(nickname) will be called. Similarly, if a user disappears offline, pydle.Client.on_user_offline(nickname) will be called.

Tagged Messages

API: pydle.features.ircv3.TaggedMessageSupport

Support for message metadata using tags.

This feature allows pydle to parse message metadata that is transmitted using ‘tags’. Currently, this has no impact on any APIs or hooks for client developers.

Metadata

API: pydle.features.ircv3.MetadataSupport

Support for user and channel metadata.

This allows you to set and unset arbitrary key-value information on yourself and on channels, as well as retrieve such values from other users and channels.

Writing features

API reference

Client API

class pydle.Client

pydle.Client implements the featureset of pydle.BasicClient with all the features in the pydle.features namespace added. For the full reference, check the pydle.BasicClient documentation and the Feature API reference.

class pydle.MinimalClient

pydle.MinimalClient implements the featureset of pydle.BasicClient with some vital features in the pydle.features namespace added, namely:

For the full reference, check the pydle.BasicClient documentation and the Feature API reference.


class pydle.ClientPool(clients=None, eventloop=None)[source]

A pool of clients that are ran and handled in parallel.

add(client)[source]

Add client to pool.

connect(client, *args, eventloop=None, **kwargs)[source]

Add client to pool and connect it using the given argument. Refer to the connect() method of the added client for details on parameters.

disconnect(client, *args, **kwargs)[source]

Disconnect client from pool and remove it. Refer to the disconnect() method of the removed client for details on parameters.

handle_forever()[source]

Main loop of the pool: handle clients forever, until the event loop is stopped.

remove(client)[source]

Remove client from pool.


pydle.featurize(*features)[source]

Put features into proper MRO order.

class pydle.BasicClient(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]

Base IRC client class. This class on its own is not complete: in order to be able to run properly, _has_message, _parse_message and _create_message have to be overloaded.

users

A dict mapping a username to a dict with general information about that user. Available keys in the information dict:

  • nickname: The user’s nickname.
  • username: The user’s reported username on their source device.
  • realname: The user’s reported real name (GECOS).
  • hostname: The hostname where the user is connecting from.

channels

A dict mapping a joined channel name to a dict with information about that channel. Available keys in the information dict:

  • users: A set of all users currently in the channel.
connect(hostname=None, port=None, reconnect=False, eventloop=None, **kwargs)[source]

Connect to IRC server.

connected

Whether or not we are connected.

disconnect(expected=True)[source]

Disconnect from server.

handle_forever()[source]

Handle data forever.

in_channel(channel)[source]

Check if we are currently in the given channel.

is_channel(chan)[source]

Check if given argument is a channel name or not.

is_same_channel(left, right)[source]

Check if given channel names are equal.

is_same_nick(left, right)[source]

Check if given nicknames are equal.

on_connect()[source]

Callback called when the client has connected successfully.

on_raw(message)[source]

Handle a single message.

on_unknown(message)[source]

Unknown command.

raw(message)[source]

Send raw command.

rawmsg(command, *args, **kwargs)[source]

Send raw message.

Asynchronous API

pydle.coroutine(func)[source]

Decorator for coroutine functions that need to block for asynchronous operations.

class pydle.Future[source]

A future. An object that represents a result that has yet to be created or returned.

done()[source]

Returns True if the future has finished running.

result(timeout=None)[source]

If the operation succeeded, return its result. If it failed, re-raise its exception.

This method takes a timeout argument for compatibility with concurrent.futures.Future but it is an error to call it before the Future is done, so the timeout is never used.

set_result(result)[source]

Sets the result of a Future.

It is undefined to call any of the set methods more than once on the same object.

exception(timeout=None)[source]

If the operation raised an exception, return the Exception object. Otherwise returns None.

This method takes a timeout argument for compatibility with concurrent.futures.Future but it is an error to call it before the Future is done, so the timeout is never used.

set_exception(exception)[source]

Sets the exception of a Future.

Features API

RFC1459
class pydle.features.RFC1459Support(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]

Basic RFC1459 client.

away(message)[source]

Mark self as away.

back()[source]

Mark self as not away.

ban(channel, target, range=0)[source]

Ban user from channel. Target can be either a user or a host. This command will not kick: use kickban() for that. range indicates the IP/host range to ban: 0 means ban only the IP/host, 1+ means ban that many ‘degrees’ (up to 3 for IP addresses) of the host for range bans.

cycle(channel)[source]

Rejoin channel.

is_same_channel(left, right)[source]

Check if given nicknames are equal in the server’s case mapping.

is_same_nick(left, right)[source]

Check if given nicknames are equal in the server’s case mapping.

join(channel, password=None)[source]

Join channel, optionally with password.

kick(channel, target, reason=None)[source]

Kick user from channel.

kickban(channel, target, reason=None, range=0)[source]

Kick and ban user from channel.

message(target, message)[source]

Message channel or user.

notice(target, message)[source]

Notice channel or user.

on_channel_message(target, by, message)[source]

Callback received when the client received a message in a channel.

on_channel_notice(target, by, message)[source]

Callback called when the client received a notice in a channel.

on_invite(channel, by)[source]

Callback called when the client was invited into a channel by someone.

on_join(channel, user)[source]

Callback called when a user, possibly the client, has joined the channel.

on_kick(channel, target, by, reason=None)[source]

Callback called when a user, possibly the client, was kicked from a channel.

on_kill(target, by, reason)[source]

Callback called when a user, possibly the client, was killed from the server.

on_message(target, by, message)[source]

Callback called when the client received a message.

on_mode_change(channel, modes, by)[source]

Callback called when the mode on a channel was changed.

on_nick_change(old, new)[source]

Callback called when a user, possibly the client, changed their nickname.

on_notice(target, by, message)[source]

Callback called when the client received a notice.

on_part(channel, user, message=None)[source]

Callback called when a user, possibly the client, left a channel.

on_private_message(by, message)[source]

Callback called when the client received a message in private.

on_private_notice(by, message)[source]

Callback called when the client received a notice in private.

on_quit(user, message=None)[source]

Callback called when a user, possibly the client, left the network.

on_topic_change(channel, message, by)[source]

Callback called when the topic for a channel was changed.

on_user_mode_change(modes)[source]

Callback called when a user mode change occurred for the client.

part(channel, message=None)[source]

Leave channel, optionally with message.

quit(message=None)[source]

Quit network.

set_mode(target, *modes)[source]

Set mode on target. Users should only rely on the mode actually being changed when receiving an on_{channel,user}_mode_change callback.

set_nickname(nickname)[source]

Set nickname to given nickname. Users should only rely on the nickname actually being changed when receiving an on_nick_change callback.

set_topic(channel, topic)[source]

Set topic on channel. Users should only rely on the topic actually being changed when receiving an on_topic_change callback.

unban(channel, target, range=0)[source]

Unban user from channel. Target can be either a user or a host. See ban documentation for the range parameter.

whois(nickname)[source]

Return information about user. This is an blocking asynchronous method: it has to be called from a coroutine, as follows:

info = yield self.whois(‘Nick’)
whowas(nickname)[source]

Return information about offline user. This is an blocking asynchronous method: it has to be called from a coroutine, as follows:

info = yield self.whowas(‘Nick’)

Transport Layer Security
class pydle.features.TLSSupport(*args, tls_client_cert=None, tls_client_cert_key=None, tls_client_cert_password=None, **kwargs)[source]

TLS support.

Pass tls_client_cert, tls_client_cert_key and optionally tls_client_cert_password to have pydle send a client certificate upon TLS connections.

connect(hostname=None, port=None, tls=False, **kwargs)[source]

Connect to a server, optionally over TLS. See pydle.features.RFC1459Support.connect for misc parameters.


Client-to-Client Protocol
class pydle.features.CTCPSupport(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]

Support for CTCP messages.

ctcp(target, query, contents=None)[source]

Send a CTCP request to a target.

ctcp_reply(target, query, response)[source]

Send a CTCP reply to a target.

on_ctcp(by, target, what, contents)[source]

Callback called when the user received a CTCP message. Client subclasses can override on_ctcp_<type> to be called when receiving a message of that specific CTCP type, in addition to this callback.

on_ctcp_reply(by, target, what, response)[source]

Callback called when the user received a CTCP response. Client subclasses can override on_ctcp_<type>_reply to be called when receiving a reply of that specific CTCP type, in addition to this callback.


Account
class pydle.features.AccountSupport(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]

ISUPPORT
class pydle.features.ISUPPORTSupport(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]

ISUPPORT support.


Extended WHO
class pydle.features.WHOXSupport(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]

Licensing

pydle license

Copyright (c) 2014, Shiz
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL SHIZ BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

pydle relies on Tornado for a significant part of its networking code; its license is printed in verbatim below.

Tornado license

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

   "License" shall mean the terms and conditions for use, reproduction,
   and distribution as defined by Sections 1 through 9 of this document.

   "Licensor" shall mean the copyright owner or entity authorized by
   the copyright owner that is granting the License.

   "Legal Entity" shall mean the union of the acting entity and all
   other entities that control, are controlled by, or are under common
   control with that entity. For the purposes of this definition,
   "control" means (i) the power, direct or indirect, to cause the
   direction or management of such entity, whether by contract or
   otherwise, or (ii) ownership of fifty percent (50%) or more of the
   outstanding shares, or (iii) beneficial ownership of such entity.

   "You" (or "Your") shall mean an individual or Legal Entity
   exercising permissions granted by this License.

   "Source" form shall mean the preferred form for making modifications,
   including but not limited to software source code, documentation
   source, and configuration files.

   "Object" form shall mean any form resulting from mechanical
   transformation or translation of a Source form, including but
   not limited to compiled object code, generated documentation,
   and conversions to other media types.

   "Work" shall mean the work of authorship, whether in Source or
   Object form, made available under the License, as indicated by a
   copyright notice that is included in or attached to the work
   (an example is provided in the Appendix below).

   "Derivative Works" shall mean any work, whether in Source or Object
   form, that is based on (or derived from) the Work and for which the
   editorial revisions, annotations, elaborations, or other modifications
   represent, as a whole, an original work of authorship. For the purposes
   of this License, Derivative Works shall not include works that remain
   separable from, or merely link (or bind by name) to the interfaces of,
   the Work and Derivative Works thereof.

   "Contribution" shall mean any work of authorship, including
   the original version of the Work and any modifications or additions
   to that Work or Derivative Works thereof, that is intentionally
   submitted to Licensor for inclusion in the Work by the copyright owner
   or by an individual or Legal Entity authorized to submit on behalf of
   the copyright owner. For the purposes of this definition, "submitted"
   means any form of electronic, verbal, or written communication sent
   to the Licensor or its representatives, including but not limited to
   communication on electronic mailing lists, source code control systems,
   and issue tracking systems that are managed by, or on behalf of, the
   Licensor for the purpose of discussing and improving the Work, but
   excluding communication that is conspicuously marked or otherwise
   designated in writing by the copyright owner as "Not a Contribution."

   "Contributor" shall mean Licensor and any individual or Legal Entity
   on behalf of whom a Contribution has been received by Licensor and
   subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   copyright license to reproduce, prepare Derivative Works of,
   publicly display, publicly perform, sublicense, and distribute the
   Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   (except as stated in this section) patent license to make, have made,
   use, offer to sell, sell, import, and otherwise transfer the Work,
   where such license applies only to those patent claims licensable
   by such Contributor that are necessarily infringed by their
   Contribution(s) alone or by combination of their Contribution(s)
   with the Work to which such Contribution(s) was submitted. If You
   institute patent litigation against any entity (including a
   cross-claim or counterclaim in a lawsuit) alleging that the Work
   or a Contribution incorporated within the Work constitutes direct
   or contributory patent infringement, then any patent licenses
   granted to You under this License for that Work shall terminate
   as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
   Work or Derivative Works thereof in any medium, with or without
   modifications, and in Source or Object form, provided that You
   meet the following conditions:

   (a) You must give any other recipients of the Work or
       Derivative Works a copy of this License; and

   (b) You must cause any modified files to carry prominent notices
       stating that You changed the files; and

   (c) You must retain, in the Source form of any Derivative Works
       that You distribute, all copyright, patent, trademark, and
       attribution notices from the Source form of the Work,
       excluding those notices that do not pertain to any part of
       the Derivative Works; and

   (d) If the Work includes a "NOTICE" text file as part of its
       distribution, then any Derivative Works that You distribute must
       include a readable copy of the attribution notices contained
       within such NOTICE file, excluding those notices that do not
       pertain to any part of the Derivative Works, in at least one
       of the following places: within a NOTICE text file distributed
       as part of the Derivative Works; within the Source form or
       documentation, if provided along with the Derivative Works; or,
       within a display generated by the Derivative Works, if and
       wherever such third-party notices normally appear. The contents
       of the NOTICE file are for informational purposes only and
       do not modify the License. You may add Your own attribution
       notices within Derivative Works that You distribute, alongside
       or as an addendum to the NOTICE text from the Work, provided
       that such additional attribution notices cannot be construed
       as modifying the License.

   You may add Your own copyright statement to Your modifications and
   may provide additional or different license terms and conditions
   for use, reproduction, or distribution of Your modifications, or
   for any such Derivative Works as a whole, provided Your use,
   reproduction, and distribution of the Work otherwise complies with
   the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
   any Contribution intentionally submitted for inclusion in the Work
   by You to the Licensor shall be under the terms and conditions of
   this License, without any additional terms or conditions.
   Notwithstanding the above, nothing herein shall supersede or modify
   the terms of any separate license agreement you may have executed
   with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
   names, trademarks, service marks, or product names of the Licensor,
   except as required for reasonable and customary use in describing the
   origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
   agreed to in writing, Licensor provides the Work (and each
   Contributor provides its Contributions) on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   implied, including, without limitation, any warranties or conditions
   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
   PARTICULAR PURPOSE. You are solely responsible for determining the
   appropriateness of using or redistributing the Work and assume any
   risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
   whether in tort (including negligence), contract, or otherwise,
   unless required by applicable law (such as deliberate and grossly
   negligent acts) or agreed to in writing, shall any Contributor be
   liable to You for damages, including any direct, indirect, special,
   incidental, or consequential damages of any character arising as a
   result of this License or out of the use or inability to use the
   Work (including but not limited to damages for loss of goodwill,
   work stoppage, computer failure or malfunction, or any and all
   other commercial damages or losses), even if such Contributor
   has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
   the Work or Derivative Works thereof, You may choose to offer,
   and charge a fee for, acceptance of support, warranty, indemnity,
   or other liability obligations and/or rights consistent with this
   License. However, in accepting such obligations, You may act only
   on Your own behalf and on Your sole responsibility, not on behalf
   of any other Contributor, and only if You agree to indemnify,
   defend, and hold each Contributor harmless for any liability
   incurred by, or claims asserted against, such Contributor by reason
   of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

   To apply the Apache License to your work, attach the following
   boilerplate notice, with the fields enclosed by brackets "[]"
   replaced with your own identifying information. (Don't include
   the brackets!)  The text should be enclosed in the appropriate
   comment syntax for the file format. We also recommend that a
   file or class name and description of purpose be included on the
   same "printed page" as the copyright notice for easier
   identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

pydle optionally relies on pure-sasl to provide SASL authentication methods; its license is printed in verbatim below.

pure-sasl license

http://www.opensource.org/licenses/mit-license.php

Copyright 2007-2011 David Alan Cridland
Copyright 2011 Lance Stout
Copyright 2012 Tyler L Hobbs

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.