pymap.interfaces

pymap.interfaces.backend

class pymap.interfaces.backend.BackendInterface(*args, **kwargs)[source]

Defines the abstract base class that is expected for backends that register themselves on the pymap.backend entry point.

abstract classmethod add_subparser(name, subparsers)[source]

Add a command-line argument sub-parser that will be used to choose this backend. For example:

parser = subparsers.add_parser('foo', help='foo backend')
parser.add_argument(...)
Parameters:
  • name (str) – The name to use for the subparser.

  • subparsers (Any) – The special action object as returned by add_subparsers().

Returns:

The new sub-parser object.

Return type:

ArgumentParser

abstract async classmethod init(args, **overrides)[source]

Initialize the backend and return an instance.

Parameters:
  • args (Namespace) – The command-line arguments.

  • overrides (Any) – Override keyword arguments to the config constructor.

Return type:

tuple[BackendInterface, IMAPConfig]

abstract async start(stack)[source]

Start the backend.

Parameters:

stack (AsyncExitStack) – An exit stack that should be used for cleanup.

Return type:

None

abstract property login: LoginInterface

Login interface that handles authentication credentials.

abstract property config: IMAPConfig

The IMAP config in use by the backend.

abstract property status: HealthStatus

The health status for the backend.

class pymap.interfaces.backend.ServiceInterface(backend, config)[source]

Defines the abstract base class that is expected for services that register themselves on the pymap.service entry point.

Parameters:
abstract classmethod add_arguments(parser)[source]

Add the arguments or argument group used to configure the service. For example:

group = parser.add_argument_group('foo service arguments')
group.add_argument(...)
Parameters:

parser (ArgumentParser) – The argument parser.

Return type:

None

abstract async start(stack)[source]

Start the service.

Parameters:

stack (AsyncExitStack) – An exit stack that should be used for cleanup.

Return type:

None

pymap.interfaces.message

class pymap.interfaces.message.MessageT

Type variable with an upper bound of MessageInterface.

alias of TypeVar(‘MessageT’, bound=MessageInterface)

class pymap.interfaces.message.MessageT_co

Covariant type variable with an upper bound of MessageInterface.

alias of TypeVar(‘MessageT_co’, bound=MessageInterface, covariant=True)

pymap.interfaces.message.FlagsKey

Type alias for the value used as a key in set comparisons detecting flag updates.

alias of tuple[int, frozenset[Flag]]

class pymap.interfaces.message.CachedMessage(*args, **kwargs)[source]

Cached message metadata used to track state changes. Used to produce untagged FETCH responses when a message’s flags have changed, or when a FETCH command requests metadata of an expunged message before its untagged EXPUNGE response has been sent.

This is intended to be compatible with MessageInterface, and should be implemented by the same classes in most cases.

abstract property uid: int

The message’s unique identifier in the mailbox.

abstract property internal_date: datetime

The message’s internal date.

abstract property permanent_flags: frozenset[Flag]

The permanent flags for the message.

abstract property email_id: ObjectId

The message’s email object ID.

abstract property thread_id: ObjectId

The message’s thread object ID.

abstract property flags_key: tuple[int, frozenset[Flag]]

Hashable value that represents the current flags of this message, used for detecting mailbox updates.

abstract get_flags(session_flags)[source]

Get the full set of permanent and session flags for the message.

Parameters:

session_flags (SessionFlags) – The current session flags.

Return type:

frozenset[Flag]

class pymap.interfaces.message.MessageInterface(*args, **kwargs)[source]

Message data such as UID, permanent flags, and when the message was added to the system.

abstract property uid: int

The message’s unique identifier in the mailbox.

abstract property expunged: bool

True if this message has been expunged from the mailbox.

abstract property internal_date: datetime

The message’s internal date.

abstract property permanent_flags: frozenset[Flag]

The permanent flags for the message.

abstract property email_id: ObjectId

The message’s email object ID, which can identify its content.

See also

RFC 8474 5.1.

abstract property thread_id: ObjectId

The message’s thread object ID, which groups messages together.

See also

RFC 8474 5.2.

abstract get_flags(session_flags)[source]

Get the full set of permanent and session flags for the message.

Parameters:

session_flags (SessionFlags) – The current session flags.

Return type:

frozenset[Flag]

abstract async load_content(requirement)[source]

Loads the content of the message.

Parameters:

requirement (FetchRequirement) – The data required from the message content.

Return type:

LoadedMessageInterface

class pymap.interfaces.message.LoadedMessageInterface(*args, **kwargs)[source]

The loaded message content, which may include the header, the body, both, or neither, depending on the requirements.

It is assumed that this object contains the entire content in-memory. As such, when multiple MessageInterface objects are being processed, only one LoadedMessageInterface should be in scope at a time.

abstract property requirement: FetchRequirement

The FetchRequirement used to load the message content.

abstract get_header(name)[source]

Get the values of a header from the message.

Parameters:

name (bytes) – The name of the header.

Return type:

Sequence[str]

abstract get_headers(section)[source]

Get the headers from the message part.

The section argument indexes a nested sub-part of the message. For example, [2, 3] would get the 2nd sub-part of the message and then index it for its 3rd sub-part.

Parameters:

section (Sequence[int]) – Nested list of sub-part indexes.

Return type:

Writeable

abstract get_message_headers(section=None, subset=None, inverse=False)[source]

Get the headers from the message or a message/rfc822 sub-part of the message..

The section argument can index a nested sub-part of the message. For example, [2, 3] would get the 2nd sub-part of the message and then index it for its 3rd sub-part.

Parameters:
  • section (Sequence[int] | None) – Optional nested list of sub-part indexes.

  • subset (Collection[bytes] | None) – Subset of headers to get.

  • inverse (bool) – If subset is given, this flag will invert it so that the headers not in subset are returned.

Return type:

Writeable

abstract get_message_text(section=None)[source]

Get the text of the message part, not including headers.

The section argument can index a nested sub-part of the message. For example, [2, 3] would get the 2nd sub-part of the message and then index it for its 3rd sub-part.

Parameters:

section (Sequence[int] | None) – Optional nested list of sub-part indexes.

Return type:

Writeable

abstract get_body(section=None, binary=False)[source]

Get the full body of the message part, including headers.

The section argument can index a nested sub-part of the message. For example, [2, 3] would get the 2nd sub-part of the message and then index it for its 3rd sub-part.

Parameters:
  • section (Sequence[int] | None) – Optional nested list of sub-part indexes.

  • binary (bool) – True if the result has decoded any Content-Transfer-Encoding.

Return type:

Writeable

abstract get_size(section=None)[source]

Return the size of the message, in octets.

Parameters:

section (Sequence[int] | None) – Optional nested list of sub-part indexes.

Return type:

int

abstract get_envelope_structure()[source]

Build and return the envelope structure.

See also

RFC 3501 2.3.5.

Return type:

EnvelopeStructure

abstract get_body_structure()[source]

Build and return the body structure.

See also

RFC 3501 2.3.6

Return type:

BodyStructure

abstract contains(value)[source]

Check the body of the message for a sub-string. This may be optimized to only search headers and text/* MIME parts.

Parameters:

value (bytes) – The sub-string to find.

Return type:

bool

pymap.interfaces.mailbox

class pymap.interfaces.mailbox.MailboxInterface(*args, **kwargs)[source]

Describes a mailbox as it exists in an IMAP backend, whether or not it is currently selected.

abstract property mailbox_id: ObjectId

The mailbox object ID.

This value must have no relationship to the mailbox name, e.g. a renamed mailbox should have the same ID but a deleted/re-created mailbox of the same name must have a different ID.

See also

RFC 8474 4.

abstract property readonly: bool

Whether the mailbox is read-only or read-write.

abstract property permanent_flags: frozenset[Flag]

The permanent flags allowed in the mailbox.

abstract property session_flags: frozenset[Flag]

The session flags allowed in the mailbox.

abstract property flags: frozenset[Flag]

Set of all permanent and session flags available on the mailbox.

abstract property exists: int

Number of total messages in the mailbox.

abstract property recent: int

Number of recent messages in the mailbox.

abstract property unseen: int

Number of unseen messages in the mailbox.

abstract property first_unseen: int | None

The sequence number of the first unseen message.

abstract property next_uid: int

The predicted next message UID.

abstract property uid_validity: int

The mailbox UID validity value.

pymap.interfaces.session

class pymap.interfaces.session.SessionInterface(*args, **kwargs)[source]

Corresponds to a single, authenticated IMAP session.

abstract property owner: str

The SASL authorization identity of the logged-in user.

abstract property filter_set: FilterSetInterface[Any] | None

Manages the active and inactive filters for the login user.

abstract close()[source]

Called at the end of a session, to clean up any resources.

Return type:

None

abstract async cleanup()[source]

Called after every operation, success or failure, to allow the backend to clean up resources.

Note

Any exception raised by this method will be silently ignored.

Return type:

None

abstract async list_mailboxes(ref_name, filter_, subscribed=False, selected=None)[source]

List the mailboxes owned by the user.

Parameters:
  • ref_name (str) – Mailbox reference name.

  • filter – Mailbox name with possible wildcards.

  • subscribed (bool) – If True, only list the subscribed mailboxes.

  • selected (SelectedMailbox | None) – If applicable, the currently selected mailbox name.

  • filter_ (str)

Return type:

tuple[Iterable[tuple[str, str | None, Sequence[bytes]]], SelectedMailbox | None]

abstract async get_mailbox(name, selected=None)[source]

Retrieves a MailboxInterface object corresponding to an existing mailbox owned by the user. Raises an exception if the mailbox does not yet exist.

Parameters:
  • name (str) – The name of the mailbox.

  • selected (SelectedMailbox | None) – If applicable, the currently selected mailbox name.

Raises:

MailboxNotFound

Return type:

tuple[MailboxInterface, SelectedMailbox | None]

abstract async create_mailbox(name, selected=None)[source]

Creates a new mailbox owned by the user.

See also

RFC 3501 6.3.3.

Parameters:
  • name (str) – The name of the mailbox.

  • selected (SelectedMailbox | None) – If applicable, the currently selected mailbox name.

Raises:

MailboxConflict

Return type:

tuple[ObjectId, SelectedMailbox | None]

abstract async delete_mailbox(name, selected=None)[source]

Deletes the mailbox owned by the user.

See also

RFC 3501 6.3.4.

Parameters:
  • name (str) – The name of the mailbox.

  • selected (SelectedMailbox | None) – If applicable, the currently selected mailbox name.

Raises:
Return type:

SelectedMailbox | None

abstract async rename_mailbox(before_name, after_name, selected=None)[source]

Renames the mailbox owned by the user.

See also

RFC 3501 6.3.5.

Parameters:
  • before_name (str) – The name of the mailbox before the rename.

  • after_name (str) – The name of the mailbox after the rename.

  • selected (SelectedMailbox | None) – If applicable, the currently selected mailbox name.

Raises:
Return type:

SelectedMailbox | None

abstract async subscribe(name, selected=None)[source]

Mark the given folder name as subscribed, whether or not the given folder name currently exists.

See also

RFC 3501 6.3.6.

Parameters:
  • name (str) – The name of the mailbox.

  • selected (SelectedMailbox | None) – If applicable, the currently selected mailbox name.

Raises:

MailboxNotFound

Return type:

SelectedMailbox | None

abstract async unsubscribe(name, selected=None)[source]

Remove the given folder name from the subscription list, whether or not the given folder name currently exists.

See also

RFC 3501 6.3.6.

Parameters:
  • name (str) – The name of the mailbox.

  • selected (SelectedMailbox | None) – If applicable, the currently selected mailbox name.

Raises:

MailboxNotFound

Return type:

SelectedMailbox | None

abstract async append_messages(name, messages, selected=None)[source]

Appends a message to the end of the mailbox.

See also

RFC 3502 6.3.11.

Parameters:
Raises:
Return type:

tuple[AppendUid, SelectedMailbox | None]

abstract async select_mailbox(name, readonly=False)[source]

Selects an existing mailbox owned by the user. The returned session is then used as the selected argument to other methods to fetch mailbox updates.

Parameters:
  • name (str) – The name of the mailbox.

  • readonly (bool) – True if the mailbox is read-only.

Raises:

MailboxNotFound

Return type:

tuple[MailboxInterface, SelectedMailbox]

abstract async check_mailbox(selected, *, wait_on=None, housekeeping=False)[source]

Checks for any updates in the mailbox.

If wait_on is given, this method should block until either this event is signalled or the mailbox has detected updates. This method may be called continuously as long as wait_on is not signalled.

If housekeeping is True, perform any house-keeping necessary by the mailbox backend, which may be a slower operation.

Parameters:
  • selected (SelectedMailbox) – The selected mailbox session.

  • wait_on (Event | None) – If given, block until this event signals.

  • housekeeping (bool) – If True, the backend may perform additional housekeeping operations if necessary.

Raises:

MailboxNotFound

Return type:

SelectedMailbox

abstract async fetch_messages(selected, sequence_set, set_seen)[source]

Get a list of loaded message objects corresponding to given sequence set.

Parameters:
  • selected (SelectedMailbox) – The selected mailbox session.

  • sequence_set (SequenceSet) – Sequence set of message sequences or UIDs.

  • set_seen (bool) – True if the messages should get the \Seen flag.

Raises:

MailboxNotFound

Return type:

tuple[Iterable[tuple[int, MessageInterface]], SelectedMailbox]

abstract async search_mailbox(selected, keys)[source]

Get the messages in the current mailbox that meet all of the given search criteria.

See also

RFC 3501 7.2.5.

Parameters:
Raises:

MailboxNotFound

Return type:

tuple[Iterable[tuple[int, MessageInterface]], SelectedMailbox]

abstract async expunge_mailbox(selected, uid_set=None)[source]

All messages that are marked as deleted are immediately expunged from the mailbox.

Parameters:
  • selected (SelectedMailbox) – The selected mailbox session.

  • uid_set (SequenceSet | None) – Only the messages in the given UID set should be expunged.

Raises:
Return type:

SelectedMailbox

abstract async copy_messages(selected, sequence_set, mailbox)[source]

Copy a set of messages into the given mailbox.

See also

RFC 3501 6.4.7.

Parameters:
  • selected (SelectedMailbox) – The selected mailbox session.

  • sequence_set (SequenceSet) – Sequence set of message sequences or UIDs.

  • mailbox (str) – Name of the mailbox to copy messages into.

Raises:
Return type:

tuple[CopyUid | None, SelectedMailbox]

abstract async move_messages(selected, sequence_set, mailbox)[source]

Move a set of messages into the given mailbox, removing them from the selected mailbox.

See also

RFC 6851

Parameters:
  • selected (SelectedMailbox) – The selected mailbox session.

  • sequence_set (SequenceSet) – Sequence set of message sequences or UIDs.

  • mailbox (str) – Name of the mailbox to copy messages into.

Raises:
Return type:

tuple[CopyUid | None, SelectedMailbox]

abstract async update_flags(selected, sequence_set, flag_set, mode=FlagOp.REPLACE)[source]

Update the flags for the given set of messages.

See also

RFC 3501 6.4.6.

Parameters:
  • selected (SelectedMailbox) – The selected mailbox session.

  • sequence_set (SequenceSet) – Sequence set of message sequences or UIDs.

  • flag_set (frozenset[Flag]) – Set of flags to update.

  • mode (FlagOp) – Update mode for the flag set.

Raises:
Return type:

tuple[Iterable[tuple[int, MessageInterface]], SelectedMailbox]

pymap.interfaces.login

class pymap.interfaces.login.LoginInterface(*args, **kwargs)[source]

Defines the authentication operations for backends.

abstract property tokens: TokensInterface

Handles creation and authentication of bearer tokens.

abstract async authenticate(credentials)[source]

Authenticate the credentials.

Parameters:

credentials (ServerCredentials) – Authentication credentials supplied by the user.

Raises:

InvalidAuth

Return type:

IdentityInterface

abstract async authorize(authenticated, authzid)[source]

The authenticated identity must be authorized to assume the identity of authzid, returning its user identity if successful.

Parameters:
  • authenticated (IdentityInterface) – The identity that successfully authorized.

  • authzid (str) – The identity name to be authorized.

Raises:

AuthorizationFailure

Return type:

IdentityInterface

class pymap.interfaces.login.IdentityInterface(*args, **kwargs)[source]

Defines the operations available to a user identity. This user identity may or may not “exist” yet in the backend.

abstract property name: str

The SASL authorization identity of the user.

abstract property roles: frozenset[str]

The set of roles granted to this identity.

abstract new_session()[source]

Returns a new IMAP session.

Raises:
Return type:

AbstractAsyncContextManager[SessionInterface]

abstract async new_token(*, expiration=None)[source]

Returns a bearer token that may be used in future authentication attempts.

Since tokens should use their own private key, backends may return None if it does not support tokens or the user does not have a private key.

Parameters:

expiration (datetime | None) – When the token should stop being valid.

Raises:
Return type:

str | None

abstract async get()[source]

Return the metadata associated with the user identity.

Raises:
Return type:

UserMetadata

abstract async set(metadata)[source]

Assign new metadata to the user identity.

Parameters:

metadata (UserMetadata) – New metadata, such as password.

Returns:

The entity_tag of the updated metadata, if applicable.

Raises:
Return type:

int | None

abstract async delete()[source]

Delete existing metadata for the user identity.

Raises:
Return type:

None

pymap.interfaces.filter

class pymap.interfaces.filter.FilterValueT

Type variable for the filter value representation.

alias of TypeVar(‘FilterValueT’)

class pymap.interfaces.filter.FilterInterface(*args, **kwargs)[source]

Protocol defining the interface for message filters. Filters may choose the mailbox or discard the message or modify its contents or metadata. The filter may also trigger external functionality, such as sending a vacation auto-response or a copy of the message to an SMTP endpoint.

abstract async apply(sender, recipient, mailbox, append_msg)[source]

Run the filter and return the mailbox where it should be appended, or None to discard, and the message to be appended, which is usually the same as append_msg.

Parameters:
  • sender (str) – The envelope sender of the message.

  • recipient (str) – The envelope recipient of the message.

  • mailbox (str) – The intended mailbox to append the message.

  • append_msg (AppendMessage) – The message to be appended.

Raises:

AppendFailure

Return type:

tuple[str | None, AppendMessage]

class pymap.interfaces.filter.FilterCompilerInterface(*args, **kwargs)[source]

Protocol for classes which can compile a filter value into an implementation.

abstract property value_type: type[FilterValueT]

The filter value type.

abstract property filter_type: type[FilterInterface]

The filter implementation type.

abstract async compile(value)[source]

Compile the filter value and return the resulting implementation.

Parameters:

value (FilterValueT) – The filter value:

Return type:

FilterInterface

class pymap.interfaces.filter.FilterSetInterface(*args, **kwargs)[source]

Protocol defining the interface for accessing and managing the set of message filters currently active and available. This interface intentionally resembles that of a ManageSieve server.

See also

RFC 5804

abstract property compiler: FilterCompilerInterface[FilterValueT]

Compiles filter values into an implementation.

abstract async put(name, value)[source]

Add or update the named filter value.

Parameters:
  • name (str) – The filter name.

  • value (FilterValueT) – The filter value.

Return type:

None

abstract async delete(name)[source]

Delete the named filter. If the named filter is active, ValueError is raised.

Parameters:

name (str) – The filter name.

Raises:

KeyError

Return type:

None

abstract async rename(before_name, after_name)[source]

Rename the filter, maintaining its active status. An exception is raised if before_name does not exist or after_name already exists.

Parameters:
  • before_name (str) – The current filter name.

  • after_name (str) – The intended filter name.

Raises:

KeyError

Return type:

None

abstract async clear_active()[source]

Disable any active filters.

Return type:

None

abstract async set_active(name)[source]

Set the named filter to be active.

Parameters:

name (str) – The filter name.

Raises:

KeyError

Return type:

None

abstract async get(name)[source]

Return the named filter value.

Parameters:

name (str) – The filter name.

Raises:

KeyError

Return type:

FilterValueT

abstract async get_active()[source]

Return the active filter value, if any.

Return type:

FilterValueT | None

abstract async get_all()[source]

Return the active filter name and a list of all filter names.

Return type:

tuple[str | None, Sequence[str]]