IRC (Internet Relay Chat) protocol client library for Python
Internet Relay Chat (IRC) protocol client library
The home of irclib is:
You can download project releases from PyPI.
Some legacy content is still available at the foundational SourceForge site.
Tests are continuously run using Travis-CI.
This library is intended to encapsulate the IRC protocol at a quite low level. It provides an event-driven IRC client framework. It has a fairly thorough support for the basic IRC protocol, CTCP and DCC connections.
In order to understand how to make an IRC client, I’m afraid you more or less must understand the IRC specifications. They are available here:
IRC requires Python 2.6 or newer (including Python 3).
You have several options to install the IRC project.
- Use “easy_install irc” or “pip install irc” to grab the latest version from the cheeseshop (recommended).
- Run “python setup.py install” (from the source distribution) or
- Run “paver install” (from repo checkout, requires paver) or
- Copy irc directory to appropriate site-packages directory.
The main features of the IRC client framework are:
- Abstraction of the IRC protocol.
- Handles multiple simultaneous IRC server connections.
- Handles server PONGing transparently.
- Messages to the IRC server are done by calling methods on an IRC connection object.
- Messages from an IRC server triggers events, which can be caught by event handlers.
- Reading from and writing to IRC server sockets are normally done by an internal select() loop, but the select()ing may be done by an external main loop.
- Functions can be registered to execute at specified times by the event-loop.
- Decodes CTCP tagging correctly (hopefully); I haven’t seen any other IRC client implementation that handles the CTCP specification subtilties.
- A kind of simple, single-server, object-oriented IRC client class that dispatches events to instance methods is included.
- DCC connection support.
- The IRC protocol shines through the abstraction a bit too much.
- Data is not written asynchronously to the server (and DCC peers), i.e. the write() may block if the TCP buffers are stuffed.
- Like most projects, documentation is lacking…
Unfortunately, this library isn’t as well-documented as I would like it to be. I think the best way to get started is to read and understand the example program irccat, which is included in the distribution.
The following files might be of interest:
The library itself. Read the code along with comments and docstrings to get a grip of what it does. Use it at your own risk and read the source, Luke!
An IRC bot implementation.
A basic IRC server implementation. Suitable for testing, but not production quality.
Example scripts in the scripts directory:
A simple example of how to use the IRC client. irccat reads text from stdin and writes it to a specified user or channel on an IRC server.
The same as above, but using the SimpleIRCClient class.
Another simple example. servermap connects to an IRC server, finds out what other IRC servers there are in the net and prints a tree-like map of their interconnections.
An example bot that uses the SingleServerIRCBot class from irc.bot. The bot enters a channel and listens for commands in private messages or channel traffic. It also accepts DCC invitations and echos back sent DCC chat messages.
Receives a file over DCC.
Sends a file over DCC.
NOTE: If you’re running one of the examples on a unix command line, you need to escape the # symbol in the channel. For example, use \#test or “#test” instead of #test.
By default, the IRC library does attempt to decode all incoming streams as UTF-8, but the author acknowledges that there are cases where decoding is undesirable or a custom decoding option is desirable. To support these cases, since irc 3.4.2, the ServerConnection class may be customized. The ‘buffer_class’ attribute on the ServerConnection determines what class is used for buffering lines from the input stream. By default it is DecodingLineBuffer, but may be re-assigned with another class, such as irc client.LineBuffer, which does not decode the lines and passes them through as byte strings. The ‘buffer_class’ attribute may be assigned for all instances of ServerConnection by overriding the class attribute:
irc.client.ServerConnection.buffer_class = irc.client.LineBuffer
or it may be overridden on a per-instance basis (as long as it’s overridden before the connection is established):
server = irc.client.IRC().server() server.buffer_class = irc.client.LineBuffer server.connect()
- Fixed encoding errors in server on Python 3.
- Added a set_keepalive method to the ServerConnection. Sends a periodic PING message every indicated interval.
Added support for throttling send_raw messages via the ServerConnection object. For example, on any connection object:
That would set the rate limit to 30 Hz (30 per second). Thanks to Jason Kendall for the suggestion and bug fixes.
- Fix typo in client.NickMask.
- Fix typo in bot.py.
- Issue #15: Added client support for ISUPPORT directives on server connections. Now, each ServerConnection has a features attribute which reflects the features supported by the server. See the docs for irc.features for details about the implementation.
- Issue #14: Fix errors when handlers of the same priority are added under Python 3. This also fixes the unintended behavior of allowing handlers of the same priority to compare as unequal.
This release brings several backward-incompatible changes to the scheduled commands.
- Refactored implementation of schedule classes. No longer do they override the datetime constructor, but now only provide suitable classmethods for construction in various forms.
- Removed backward-compatible references from irc.client.
- Remove ‘arguments’ parameter from scheduled commands.
Clients that reference the schedule classes from irc.client or that construct them from the basic constructor will need to update to use the new class methods:
- DelayedCommand -> DelayedCommand.after - PeriodicCommand -> PeriodicCommand.after
Arguments may no longer be passed to the ‘function’ callback, but one is encouraged instead to use functools.partial to attach parameters to the callback. For example:
DelayedCommand.after(3, func, ('a', 10))
func = functools.partial(func, 'a', 10) DelayedCommand.after(3, func)
This mode puts less constraints on the both the handler and the caller. For example, a caller can now pass keyword arguments instead:
func = functools.partial(func, name='a', quantity=10) DelayedCommand.after(3, func)
Readability, maintainability, and usability go up.
- Issue #13: TypeError on Python 3 when constructing PeriodicCommand (and thus execute_every).
- Fixed regression created in 7.0 where PeriodicCommandFixedDelay would only cause the first command to be scheduled, but not subsequent ones.
- Moved scheduled command classes to irc.schedule module. Kept references for backwards-compatibility.
PeriodicCommand now raises a ValueError if it’s created with a negative or zero delay (meaning all subsequent commands are immediately due). This fixes #12.
Renamed the parameters to the IRC object. If you use a custom event loop and your code constructs the IRC object with keyword parameters, you will need to update your code to use the new names, so:
IRC(fn_to_add_socket=adder, fn_to_remove_socket=remover, fn_to_add_timeout=timeout)
IRC(on_connect=adder, on_disconnect=remover, on_schedule=timeout)
If you don’t use a custom event loop or you pass the parameters positionally, no change is necessary.
- Fixed some unhandled exceptions in server client connections when the client would disconnect in response to messages sent after select was called.
- Moved LineBuffer and DecodingLineBuffer from client to buffer module. Backward-compatible references have been kept for now.
- Removed daemon mode and log-to-file options for server.
- Miscellaneous bugfixes in server.
- Fix error in 2to3 conversion on irc/server.py (issue #11).
The IRC library is now licensed under the MIT license.
- Added irc/server.py, based on hircd by Ferry Boender.
- Added support for CAP command (pull request #10), thanks to Danneh Oaks.
Another backward-incompatible change. In irc 5.0, many of the unnecessary getter functions have been removed and replaced with simple attributes. This change addresses issue #2. In particular:
- Connection._get_socket() -> Connection.socket (including subclasses)
- Event.eventtype() -> Event.type
- Event.source() -> Event.source
- Event.target() -> Event.target
- Event.arguments() -> Event.arguments
The nm_to_* functions were removed. Instead, use the NickMask class attributes.
These deprecated function aliases were removed from irc.client:
- parse_nick_modes -> modes.parse_nick_modes - parse_channel_modes -> modes.parse_channel_modes - generated_events -> events.generated - protocol_events -> events.protocol - numeric_events -> events.numeric - all_events -> events.all - irc_lower -> strings.lower
Also, the parameter name when constructing an event was renamed from eventtype to simply type.
- Removed deprecated arguments to ServerConnection.connect. See notes on the 3.3 release on how to use the connect_factory parameter if your application requires ssl, ipv6, or other connection customization.
- Filter out disconnected sockets when processing input.
- Created two new exceptions in irc.client: MessageTooLong and InvalidCharacters.
- Use explicit exceptions instead of ValueError when sending data.
SingleServerIRCBot now accepts keyword arguments which are passed through to the ServerConnection.connect method. One can use this to use SSL for connections:
factory = irc.connection.Factory(wrapper=ssl.wrap_socket) bot = irc.bot.SingleServerIRCBot(..., connect_factory = factory)
- Issue #6: Fix AttributeError when legacy parameters are passed to ServerConnection.connect.
- Issue #7: Fix TypeError on iter(LineBuffer).
3.4 never worked - the decoding customization feature was improperly implemented and never tested.
The ServerConnection now allows custom classes to be supplied to customize the decoding of incoming lines. For example, to disable the decoding of incoming lines, replace the buffer_class on the ServerConnection with a version that passes through the lines directly:
irc.client.ServerConnection.buffer_class = irc.client.LineBuffer
This fixes #5.
- Added connection module with a Factory for creating socket connections.
- Added connect_factory parameter to the ServerConnection.
It’s now possible to create connections with custom SSL parameters or other socket wrappers. For example, to create a connection with a custom SSL cert:
import ssl import irc.client import irc.connection import functools irc = irc.client.IRC() server = irc.server() wrapper = functools.partial(ssl.wrap_socket, ssl_cert=my_cert()) server.connect(connect_factory = irc.connection.Factory(wrapper=wrapper))
With this release, many of the parameters to ServerConnection.connect are now deprecated:
Instead, one should pass the appropriate values to a connection.Factory instance and pass that factory to the .connect method. Backwards-compatibility will be maintained for these parameters until the release of irc 4.0.
- Restore Python 2.6 compatibility.
- Protect from UnicodeDecodeError when decoding data on the wire when data is not properly encoded in ASCII or UTF-8.
- Additional branch protected by mutex.
- Implemented thread safety via a reentrant lock guarding shared state in IRC objects.
- Fix some issues with bytes/unicode on Python 3
- Distribute using setuptools rather than paver.
- Minor tweaks for Python 3 support. Now installs on Python 3.
- Added error checking when sending a message - for both message length and embedded carriage returns. Fixes #4.
- Updated README.
- Improved Unicode support. Fixes failing tests and errors lowering Unicode channel names.
- Issue #3541414 - The ServerConnection and DCCConnection now encode any strings as UTF-8 before transmitting.
- Issue #3527371 - Updated strings.FoldedCase to support comparison against objects of other types.
- Shutdown the sockets before closing.
Applications that are currently encoding unicode as UTF-8 before passing the strings to ServerConnection.send_raw need to be updated to send Unicode or ASCII.
This release officially deprecates 2.0.1-2.0.3 in favor of 3.0.
- Re-release of irc 2.0 (without the changes from 2.0.1-2.0.3) for correct compatibility indication.
DelayedCommands now use the local time for calculating ‘at’ and ‘due’ times. This will be more friendly for simple servers. Servers that expect UTC times should either run in UTC or override DelayedCommand.now to return an appropriate time object for ‘now’. For example:
def startup_bot(): irc.client.DelayedCommand.now = irc.client.DelayedCommand.utcnow ...
- Added irc.client.PeriodicCommandFixedDelay. Schedule this command to have a function executed at a specific time and then at periodic intervals thereafter.
- Removed irclib and ircbot legacy modules.
- Fix file saving using dccreceive.py on Windows. Fixes #2863199.
- Created NickMask class from nm_to_* functions. Now if a source is a NickMask, one can access the .nick, .host, and .user attributes.
- Use correct attribute for saved connect args. Fixes #3523057.
- Added ServerConnection.reconnect method. Fixes #3515580.
- Added missing events. Fixes #3515578.
- Moved functionality from irclib module to irc.client module.
- Moved functionality from ircbot module to irc.bot module.
- Retained irclib and ircbot modules for backward-compatibility. These will be removed in 1.0.
- Renamed project to simply ‘irc’.
To support the new module structure, simply replace references to the irclib module with irc.client and ircbot module with irc.bot. This project will support that interface through all versions of irc 1.x, so if you’ve made these changes, you can safely depend on irc >= 0.7, <2.0dev.
- Fixed failing test where DelayedCommands weren’t being sorted properly. DelayedCommand a now subclass of the DateTime object, where the command’s due time is the datetime. Fixed issue #3518508.
- Fixed incorrect usage of Connection.execute_delayed (again).
- Minimum Python requirement is now Python 2.6. Python 2.3 and earlier should use 0.5.0 or earlier.
- Removed incorrect usage of Connection.execute_delayed. Added Connection.execute_every. Fixed issue 3516241.
- Use new-style classes.