Coder Social home page Coder Social logo

mjs / imapclient Goto Github PK

View Code? Open in Web Editor NEW
491.0 15.0 81.0 4.33 MB

An easy-to-use, Pythonic and complete IMAP client library

Home Page: https://imapclient.readthedocs.io/

License: Other

Shell 0.27% Python 99.73%
python imap imap-client python-3 python-2

imapclient's Introduction

Essentials

IMAPClient is an easy-to-use, Pythonic and complete IMAP client library.

Current version 3.0.1
Supported Python versions 3.7 - 3.11
License New BSD
Project home https://github.com/mjs/imapclient/
PyPI https://pypi.python.org/pypi/IMAPClient
Documentation https://imapclient.readthedocs.io/
Discussions https://github.com/mjs/imapclient/discussions
Test Status master branch

Features

  • Arguments and return values are natural Python types.
  • IMAP server responses are fully parsed and readily usable.
  • IMAP unique message IDs (UIDs) are handled transparently. There is no need to call different methods to use UIDs.
  • Escaping for internationalised mailbox names is transparently handled. Unicode mailbox names may be passed as input wherever a folder name is accepted.
  • Time zones are transparently handled including when the server and client are in different zones.
  • Convenience methods are provided for commonly used functionality.
  • Exceptions are raised when errors occur.

Example

from imapclient import IMAPClient

# context manager ensures the session is cleaned up
with IMAPClient(host="imap.host.org") as client:
    client.login('someone', 'secret')
    client.select_folder('INBOX')

    # search criteria are passed in a straightforward way
    # (nesting is supported)
    messages = client.search(['NOT', 'DELETED'])

    # fetch selectors are passed as a simple list of strings.
    response = client.fetch(messages, ['FLAGS', 'RFC822.SIZE'])

    # `response` is keyed by message id and contains parsed,
    # converted response items.
    for message_id, data in response.items():
        print('{id}: {size} bytes, flags={flags}'.format(
            id=message_id,
            size=data[b'RFC822.SIZE'],
            flags=data[b'FLAGS']))

Why IMAPClient?

You may ask: "why create another IMAP client library for Python? Doesn't the Python standard library already have imaplib?".

The problem with imaplib is that it's very low-level. It expects string values where lists or tuples would be more appropriate and returns server responses almost unparsed. As IMAP server responses can be quite complex this means everyone using imaplib ends up writing their own fragile parsing routines.

Also, imaplib doesn't make good use of exceptions. This means you need to check the return value of each call to imaplib to see if what you just did was successful.

IMAPClient actually uses imaplib internally. This may change at some point in the future.

Installing IMAPClient

IMAPClient is listed on PyPI and can be installed with pip:

pip install imapclient

More installation methods are described in the documentation.

Documentation

IMAPClient's manual is available at http://imapclient.readthedocs.io/. Release notes can be found at http://imapclient.readthedocs.io/#release-history.

See the examples directory in the root of project source for examples of how to use IMAPClient.

Current Status

You should feel confident using IMAPClient for production purposes.

In order to clearly communicate version compatibility, IMAPClient will strictly adhere to the Semantic Versioning scheme from version 1.0 onwards.

The project's home page is https://github.com/mjs/imapclient/ (this currently redirects to the IMAPClient Github site). Details about upcoming versions and planned features/fixes can be found in the issue tracker on Github. The maintainers also blog about IMAPClient news. Those articles can be found here.

Discussions

Github Discussions can be used to ask questions, propose changes or praise the project maintainers :)

Working on IMAPClient

The contributing documentation contains information for those interested in improving IMAPClient.

IMAP Servers

IMAPClient is heavily tested against Dovecot, Gmail, Fastmail.fm (who use a modified Cyrus implementation), Office365 and Yahoo. Access to accounts on other IMAP servers/services for testing would be greatly appreciated.

Interactive Console

This script connects an IMAPClient instance using the command line args given and starts an interactive session. This is useful for exploring the IMAPClient API and testing things out, avoiding the steps required to set up an IMAPClient instance.

The IPython shell is used if it is installed. Otherwise the code.interact() function from the standard library is used.

The interactive console functionality can be accessed running the interact.py script in the root of the source tree or by invoking the interact module like this:

python -m imapclient.interact ...

"Live" Tests

IMAPClient includes a series of live, functional tests which exercise it against a live IMAP account. These are useful for ensuring compatibility with a given IMAP server implementation.

The livetest functionality are run from the root of the project source like this:

python livetest.py <livetest.ini> [ optional unittest arguments ]

The configuration file format is described in the main documentation.

WARNING: The operations used by livetest are destructive and could cause unintended loss of data. That said, as of version 0.9, livetest limits its activity to a folder it creates and subfolders of that folder. It should be safe to use with any IMAP account but please don't run livetest against a truly important IMAP account.

Please include the output of livetest.py with an issue if it fails to run successfully against a particular IMAP server. Reports of successful runs are also welcome. Please include the type and version of the IMAP server, if known.

imapclient's People

Contributors

axoroll7 avatar bengotow avatar bonilindsley avatar carsonip avatar d70-t avatar dependabot[bot] avatar duesee avatar frispete avatar grawity avatar jap avatar jhatch28 avatar jheckel avatar john2x avatar johnvillalovos avatar jonasc avatar magopian avatar maparent avatar mgorny avatar mhammond avatar mjs avatar mlorant avatar nicolaslm avatar nnathan avatar pawelgorzelany avatar pinoatrome avatar shoaib30 avatar thomasst avatar unpublished avatar wojcikstefan avatar zrose584 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

imapclient's Issues

Folder names with double quotes around them have the double quotes stripped

Originally reported by: Menno Smits (Bitbucket: mjs0)


In [1]: c.create_folder('"foo"')
Out[1]: 'Create completed.'

In [2]: c.create_folder('"foo" bar')
Out[2]: 'Create completed.'

In [3]: [x for x in c.list_folders() if 'foo' in str(x)]
Out[3]: [(['\\HasNoChildren'], '/', '"foo" bar'), (['\\HasNoChildren'], '/', 'foo')]

There could be similar issues with other folder handling methods.


Work around imaplib SSL bug

Originally reported by: Menno Smits (Bitbucket: mjs0)


Details from Mark:

In short, there is a bug in imaplib when dealing with ssl connections
which terminate early - the SSL readline() method in imaplib gets into
a loop reading empty strings from the socket and appending them to a
list, chewing lots of memory and causing some consternation :)

The bug seems to be http://bugs.python.org/issue5949 and it has been
fixed in various versions, although I hit it in 2.6.3.

It was fixed in 2.6 in:
http://svn.python.org/view/python/branches/release26-maint/Lib/imaplib.py?r1=76761&r2=76760&pathrev=76761

But note that it has not been back-ported to 2.5 or earlier.

The bug report above includes a patch to imaplib's readline. It should
be possible to monkeypatch in the fixed version if a buggy imaplib
version is detected.


Return LIST style responses as namedtuples

Originally reported by: Menno Smits (Bitbucket: mjs0)


Currently methods that return lists of folder name objects return (flags, delim, name) triples. It would be friendlier if these where namedtuples with "flags", "delimiter" and "name" attributes.

This avoids breaking the existing positional API while adding convenience (and avoiding magic numbers).

Example:

folders = client.list_folders()
folder = folders[0]

assert folder.flags == folder[0]
assert folder.delim == folder[1]
assert folder.name == folder[2]

fetch ENVELOPE doesn't work with gmail

Originally reported by: Anonymous


>>> server.select_folder('william')
7L
>>> server.fetch(1, ("ENVELOPE",))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "imapclient/imapclient.py", line 436, in fetch
    return parser(data)
  File "imapclient/imapclient.py", line 573, in parse
    msgid, data = self.parse_data(response_item)
  File "imapclient/imapclient.py", line 614, in parse_data
    for name, item in FetchTokeniser().process_pairs(data):
  File "imapclient/imapclient.py", line 699, in process_pairs
    for m in strict_finditer(self.PAIR_RE, s):
  File "imapclient/imapclient.py", line 763, in strict_finditer
    "%r before -- %r remains" % (s[:i], s[i:]))
ValueError: failed to match all of input. 'UID 1 ENVELOPE ("Fri, 16 Jul 2004 15:59:43 -0400" "on my way" (("Mark Eichin" NIL "eichin" "gmail.com")' before -- ') (("Mark Eichin" NIL "eichin" "gmail.com")) (("Mark Eichin" NIL "eichin" "gmail.com")) (("Other Person" NIL "..." "...")) NIL NIL NIL "<[email protected]>")' remains

(email address parts elided from one of the strings, but the match has already failed at that point. Also, this is with strict_finditer tweaked as-shown so you can see the successful part of the match as well as the failed part...)

It appears that this is what keeps fetch(1, ("ALL",)) from working, as well, it hits the !ValueError in the same place at least, and the other parts of ALL work when fetched individually.


Genshi UnicodeDecode error from trac:

Originally reported by: Anonymous


I get this error when posting a ticket (which is why 29 and 30 are duplicates, sorry) - the posting works, but I can't see the resulting ticket...

Trac Error

Genshi UnicodeDecodeError error while rendering template (unknown template location)

TracGuide โ€” The Trac User and Administration Guide


fetch ENVELOPE doesn't work with gmail

Originally reported by: anonymous (Bitbucket: anonymous)


>>> server.select_folder('william')
7L
>>> server.fetch(1, ("ENVELOPE",))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "imapclient/imapclient.py", line 436, in fetch
    return parser(data)
  File "imapclient/imapclient.py", line 573, in parse
    msgid, data = self.parse_data(response_item)
  File "imapclient/imapclient.py", line 614, in parse_data
    for name, item in FetchTokeniser().process_pairs(data):
  File "imapclient/imapclient.py", line 699, in process_pairs
    for m in strict_finditer(self.PAIR_RE, s):
  File "imapclient/imapclient.py", line 763, in strict_finditer
    "%r before -- %r remains" % (s[:i], s[i:]))
ValueError: failed to match all of input. 'UID 1 ENVELOPE ("Fri, 16 Jul 2004 15:59:43 -0400" "on my way" (("Mark Eichin" NIL "eichin" "gmail.com")' before -- ') (("Mark Eichin" NIL "eichin" "gmail.com")) (("Mark Eichin" NIL "eichin" "gmail.com")) (("Other Person" NIL "..." "...")) NIL NIL NIL "<[email protected]>")' remains

(email address parts elided from one of the strings, but the match has already failed at that point.  Also, this is with strict_finditer tweaked as-shown so you can see the successful part of the match as well as the failed part...)

It appears that this is what keeps fetch(1, ("ALL",)) from working, as well, it hits the ValueError in the same place at least, and the other parts of ALL work when fetched individually.

nicer ENVELOPE parsing

Originally reported by: Menno Smits (Bitbucket: mjs0)


ENVELOPE fetch response items are curently just a nested set of tuples. A richer data structure would be friendlier to use. ENVELOPE responses should have helper properties/methods for getting the addresses out (and more?) and named attributes for each field.


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.