{"id":13725110,"url":"https://github.com/ikvk/imap_tools","last_synced_at":"2026-01-17T10:57:21.119Z","repository":{"id":41481002,"uuid":"74050445","full_name":"ikvk/imap_tools","owner":"ikvk","description":"Work with email by IMAP","archived":false,"fork":false,"pushed_at":"2026-01-15T08:27:08.000Z","size":954,"stargazers_count":804,"open_issues_count":1,"forks_count":93,"subscribers_count":12,"default_branch":"master","last_synced_at":"2026-01-15T13:07:11.160Z","etag":null,"topics":["client","easy-to-use","email","imap","imap-client","imap-tools","mailbox-automation","mailbox-read","python","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ikvk.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-11-17T17:23:11.000Z","updated_at":"2026-01-15T08:24:37.000Z","dependencies_parsed_at":"2024-04-03T12:26:54.003Z","dependency_job_id":"c9a81a55-f73e-418a-a28c-86b4a3aeab2d","html_url":"https://github.com/ikvk/imap_tools","commit_stats":{"total_commits":322,"total_committers":15,"mean_commits":"21.466666666666665","dds":0.2639751552795031,"last_synced_commit":"ea9f752fe3d325b7ba6234b341664ad490340403"},"previous_names":[],"tags_count":92,"template":false,"template_full_name":null,"purl":"pkg:github/ikvk/imap_tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikvk%2Fimap_tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikvk%2Fimap_tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikvk%2Fimap_tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikvk%2Fimap_tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ikvk","download_url":"https://codeload.github.com/ikvk/imap_tools/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikvk%2Fimap_tools/sbom","scorecard":{"id":483903,"data":{"date":"2025-08-11","repo":{"name":"github.com/ikvk/imap_tools","commit":"b7182d339a93132a1a2bcafb2d8004fa0e03b4ed"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.7,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":2,"reason":"2 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":5,"reason":"5 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2013-22 / GHSA-27x4-j476-jp5f","Warn: Project is vulnerable to: PYSEC-2025-49 / GHSA-5rjg-fvgr-3xxf","Warn: Project is vulnerable to: GHSA-cx63-2mw6-8hw5","Warn: Project is vulnerable to: PYSEC-2022-43012 / GHSA-r9hx-vwmv-q579","Warn: Project is vulnerable to: PYSEC-2022-43017 / GHSA-qwmp-2cf2-g9g6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T17:19:21.805Z","repository_id":41481002,"created_at":"2025-08-19T17:19:21.805Z","updated_at":"2025-08-19T17:19:21.805Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28506593,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T10:25:30.148Z","status":"ssl_error","status_checked_at":"2026-01-17T10:25:29.718Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client","easy-to-use","email","imap","imap-client","imap-tools","mailbox-automation","mailbox-read","python","python3"],"created_at":"2024-08-03T01:02:13.280Z","updated_at":"2026-01-17T10:57:21.108Z","avatar_url":"https://github.com/ikvk.png","language":"Python","readme":".. http://docutils.sourceforge.net/docs/user/rst/quickref.html\n\n.. |nbsp| unicode:: 0xA0\n   :trim:\n\nimap_tools 📧\n========================================================================================================================\n\nHigh level lib for work with email by IMAP:\n\n- Basic message operations: fetch, uids, numbers\n- Parsed email message attributes\n- Query builder for search criteria\n- Actions with emails: copy, delete, flag, move, append\n- Actions with folders: list, set, get, create, exists, rename, subscribe, delete, status\n- IDLE commands: start, poll, stop, wait\n- Exceptions on failed IMAP operations\n- No external dependencies, tested\n\n.. image:: https://img.shields.io/pypi/dm/imap_tools.svg?style=social\n\n===============  =======================================================================================================\nPython version   3.8+\nLicense          Apache-2.0\nPyPI             https://pypi.python.org/pypi/imap_tools/\nRFC              `IMAP4.1 \u003chttps://tools.ietf.org/html/rfc3501\u003e`_,\n                 `EMAIL \u003chttps://tools.ietf.org/html/rfc2822\u003e`_,\n                 `IMAP related RFCs \u003chttps://github.com/ikvk/imap_tools/blob/master/docs/IMAP_related_RFCs.txt\u003e`_\nRepo mirror      https://gitflic.ru/project/ikvk/imap-tools\n===============  =======================================================================================================\n\n.. contents::\n\n⚙️ Installation\n------------------------------------------------------------------------------------------------------------------------\n::\n\n    $ pip install imap-tools\n\n📘 Guide\n------------------------------------------------------------------------------------------------------------------------\n\n📋 Basic\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nInfo about lib are at: *this page*, docstrings, issues, pull requests,\n`examples \u003chttps://github.com/ikvk/imap_tools/tree/master/examples\u003e`_, source, stackoverflow.com\n\n.. code-block:: python\n\n    from imap_tools import MailBox, AND\n\n    # Get date, subject and body len of all emails from INBOX folder\n    with MailBox('imap.mail.com').login('test@mail.com', 'pwd') as mailbox:\n        for msg in mailbox.fetch():\n            print(msg.date, msg.subject, len(msg.text or msg.html))\n\n`Description of basic example^, that you should to read \u003chttps://github.com/ikvk/imap_tools/blob/master/examples/basic.py\u003e`_.\n\n``MailBox, MailBoxStartTls, MailBoxUnencrypted`` - for create mailbox client. `STARTTLS example \u003chttps://github.com/ikvk/imap_tools/blob/master/examples/starttls.py\u003e`_.\n\n``BaseMailBox.\u003cauth\u003e`` - ``login, login_utf8, xoauth2, logout`` - authentication functions, support context manager.\n\n``BaseMailBox.fetch`` - first searches email uids by criteria in current folder, then fetch and yields `MailMessage \u003c#email-attributes\u003e`_, args:\n\n* *criteria* = 'ALL', message search criteria, `query builder \u003c#search-criteria\u003e`_\n* *charset* = 'US-ASCII', indicates charset of the strings that appear in the search criteria. See rfc2978\n* *limit* = None, limit on the number of read emails, useful for actions with a large number of messages, like \"move\". May be int or slice.\n* *mark_seen* = True, mark emails as seen on fetch\n* *reverse* = False, in order from the larger date to the smaller\n* *headers_only* = False, get only email headers (without text, html, attachments)\n* *bulk* = False, False - fetch each message separately per N commands - low memory consumption, slow; True - fetch all messages per 1 command - high memory consumption, fast; int - fetch all messages by bulks of the specified size, for 20 messages and bulk=5 -\u003e 4 IMAP commands\n* *sort* = None, criteria for sort messages on server, use SortCriteria constants. Charset arg is important for sort\n\n``BaseMailBox.uids`` - search mailbox for matching message uids in current folder, returns List[str], args:\n\n* *criteria* = 'ALL', message search criteria, `query builder \u003c#search-criteria\u003e`_\n* *charset* = 'US-ASCII', indicates charset of the strings that appear in the search criteria. See rfc2978\n* *sort* = None, criteria for sort messages on server, use SortCriteria constants. Charset arg is important for sort\n\n``BaseMailBox.\u003caction\u003e`` - `copy, move, delete, flag, append \u003c#actions-with-emails\u003e`_ - message actions.\n\n``BaseMailBox.folder.\u003caction\u003e`` - `list, set, get, create, exists, rename, subscribe, delete, status \u003c#actions-with-folders\u003e`_ - folder manager.\n\n``BaseMailBox.idle.\u003caction\u003e`` - `start, poll, stop, wait \u003c#idle-workflow\u003e`_ - idle manager.\n\n``BaseMailBox.numbers`` - search mailbox for matching message numbers in current folder, returns [str]\n\n``BaseMailBox.numbers_to_uids`` - Get message uids by message numbers, returns [str]\n\n``BaseMailBox.client`` - imaplib.IMAP4/IMAP4_SSL client instance.\n\n📧 Email attributes\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nEmail has 2 basic body variants: text and html. Sender can choose to include: one, other, both or neither(rare).\n\nMailMessage and MailAttachment public attributes are cached by functools.cached_property\n\n.. code-block:: python\n\n    for msg in mailbox.fetch():  # generator: imap_tools.MailMessage\n        msg.uid          # str | None: '123'\n        msg.subject      # str: 'some subject 你 привет'\n        msg.from_        # str: 'Bartölke@ya.ru'\n        msg.to           # tuple: ('iam@goo.ru', 'friend@ya.ru', )\n        msg.cc           # tuple: ('cc@mail.ru', )\n        msg.bcc          # tuple: ('bcc@mail.ru', )\n        msg.reply_to     # tuple: ('reply_to@mail.ru', )\n        msg.date         # datetime.datetime: 1900-1-1 for unparsed, may be naive or with tzinfo\n        msg.date_str     # str: original date - 'Tue, 03 Jan 2017 22:26:59 +0500'\n        msg.text         # str: 'Hello 你 Привет'\n        msg.html         # str: '\u003cb\u003eHello 你 Привет\u003c/b\u003e'\n        msg.flags        # tuple: ('\\\\Seen', '\\\\Flagged', 'ENCRYPTED')\n        msg.headers      # dict: {'received': ('from 1.m.ru', 'from 2.m.ru'), 'anti-virus': ('Clean',)}\n        msg.size_rfc822  # int: 20664 bytes - size info from server (*useful with headers_only arg)\n        msg.size         # int: 20377 bytes - size of received message\n\n        for att in msg.attachments:  # list: imap_tools.MailAttachment\n            att.filename             # str: 'cat.jpg'\n            att.payload              # bytes: b'\\xff\\xd8\\xff\\xe0\\'\n            att.content_id           # str: 'part45.06020801.00060008@mail.ru'\n            att.content_type         # str: 'image/jpeg'\n            att.content_disposition  # str: 'inline'\n            att.part                 # email.message.Message: original object\n            att.size                 # int: 17361 bytes\n\n        msg.obj              # email.message.Message: original object\n        msg.from_values      # imap_tools.EmailAddress | None\n        msg.to_values        # tuple: (imap_tools.EmailAddress,)\n        msg.cc_values        # tuple: (imap_tools.EmailAddress,)\n        msg.bcc_values       # tuple: (imap_tools.EmailAddress,)\n        msg.reply_to_values  # tuple: (imap_tools.EmailAddress,)\n\n        # imap_tools.EmailAddress example:\n        # EmailAddress(name='Ya', email='im@ya.ru')  # has \"full\" property = 'Ya \u003cim@ya.ru\u003e'\n\n🔍 Search criteria\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe ``criteria`` argument is used at ``fetch, uids, numbers`` methods of MailBox. Criteria can be of three types:\n\n.. code-block:: python\n\n    from imap_tools import AND\n\n    mailbox.fetch(AND(subject='weather'))  # query, the str-like object\n    mailbox.fetch('TEXT \"hello\"')          # str\n    mailbox.fetch(b'TEXT \"\\xd1\\x8f\"')      # bytes\n\nUse ``charset`` argument for encode criteria to the desired encoding. If criteria is bytes - encoding will be ignored.\n\n.. code-block:: python\n\n    mailbox.uids(A(subject='жёлтый'), charset='utf8')\n\nQuery builder implements all search logic described in `rfc3501 \u003chttps://tools.ietf.org/html/rfc3501#section-6.4.4\u003e`_.\nIt uses this classes:\n\n========  =====  ========================================== ======================================\nClass     Alias  Description                                Arguments\n========  =====  ========================================== ======================================\nAND       A      Combine conditions by logical \"AND\"        Search keys (see table below) | str\nOR        O      Combine conditions by logical \"OR\"         Search keys (see table below) | str\nNOT       N      Invert the result of a logical expression  AND/OR instances | str\nHeader    H      Header value for search by header key      name: str, value: str\nUidRange  U      UID range value for search by uid key      start: str, end: str\n========  =====  ========================================== ======================================\n\nA few examples below. See `detailed query examples \u003chttps://github.com/ikvk/imap_tools/blob/master/examples/search.py\u003e`_.\n\n.. code-block:: python\n\n    from imap_tools import A, AND, OR, NOT\n\n    # AND: subject contains \"cat\" AND message is unseen\n    A(subject='cat', seen=False)\n\n    # OR: header or body contains \"hello\" OR date equal 2000-3-15\n    OR(text='hello', date=datetime.date(2000, 3, 15))\n\n    # NOT: date not in the date list\n    NOT(OR(date=[dt.date(2019, 10, 1), dt.date(2019, 10, 10)]))\n\n    # PYTHON NOTE: you can't do A(text='a', NOT(subject='b')), use kwargs after logic classes (args)\n    A(NOT(subject='b'), text='a')\n\nServer side search notes:\n\n* For string search keys a message matches if the string is a substring of the field. The matching is case-insensitive.\n* When searching by dates - email's time and timezone are disregarding.\n\nSearch key table below.\n\nKey types marked with `*` can accepts a sequence of values like list, tuple, set or generator - for join by OR.\n\n=============  ===============  ======================  ================================================================\nKey            Types            Results                 Description\n=============  ===============  ======================  ================================================================\nanswered       bool             `ANSWERED/UNANSWERED`   with/without the Answered flag\nseen           bool             `SEEN/UNSEEN`           with/without the Seen flag\nflagged        bool             `FLAGGED/UNFLAGGED`     with/without the Flagged flag\ndraft          bool             `DRAFT/UNDRAFT`         with/without the Draft flag\ndeleted        bool             `DELETED/UNDELETED`     with/without the Deleted flag\nkeyword        str*             KEYWORD KEY             with the specified keyword flag\nno_keyword     str*             UNKEYWORD KEY           without the specified keyword flag\n`from_`        str*             FROM `\"from@ya.ru\"`     contain specified str in envelope struct's FROM field\nto             str*             TO `\"to@ya.ru\"`         contain specified str in envelope struct's TO field\nsubject        str*             SUBJECT \"hello\"         contain specified str in envelope struct's SUBJECT field\nbody           str*             BODY \"some_key\"         contain specified str in body of the message\ntext           str*             TEXT \"some_key\"         contain specified str in header or body of the message\nbcc            str*             BCC `\"bcc@ya.ru\"`       contain specified str in envelope struct's BCC field\ncc             str*             CC `\"cc@ya.ru\"`         contain specified str in envelope struct's CC field\ndate           datetime.date*   ON 15-Mar-2000          internal date is within specified date\ndate_gte       datetime.date*   SINCE 15-Mar-2000       internal date is within or later than the specified date\ndate_lt        datetime.date*   BEFORE 15-Mar-2000      internal date is earlier than the specified date\nsent_date      datetime.date*   SENTON 15-Mar-2000      rfc2822 Date: header is within the specified date\nsent_date_gte  datetime.date*   SENTSINCE 15-Mar-2000   rfc2822 Date: header is within or later than the specified date\nsent_date_lt   datetime.date*   SENTBEFORE 1-Mar-2000   rfc2822 Date: header is earlier than the specified date\nsize_gt        int \u003e= 0         LARGER 1024             rfc2822 size larger than specified number of octets\nsize_lt        int \u003e= 0         SMALLER 512             rfc2822 size smaller than specified number of octets\nnew            True             NEW                     have the Recent flag set but not the Seen flag\nold            True             OLD                     do not have the Recent flag set\nrecent         True             RECENT                  have the Recent flag set\nall            True             ALL                     all, criteria by default\nuid            iter(str)/str/U  UID 1,2,17              corresponding to the specified unique identifier set\nheader         H(str, str)*     HEADER \"A-Spam\" \"5.8\"   have a header that contains the specified str in the text\ngmail_label    str*             X-GM-LABELS \"label1\"    have this gmail label\n=============  ===============  ======================  ================================================================\n\n🗃️ Actions with emails\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nFirst of all read about UID `at rfc3501 \u003chttps://tools.ietf.org/html/rfc3501#section-2.3.1.1\u003e`_.\n\nAction's uid_list arg may takes:\n\n* str, that is comma separated uids\n* Sequence, that contains str uids\n\nTo get uids, use the maibox methods: uids, fetch.\n\nFor actions with large number of messages IMAP command may be too large and will cause exception at server side:\n\n* Use ``chunks`` arg at ``copy,move,delete,flag`` to specify number of UIDs to process at one IMAP command\n* Use ``limit`` arg at ``fetch`` to limit the number of messages returned\n\n.. code-block:: python\n\n    with MailBox('imap.mail.com').login('test@mail.com', 'pwd', initial_folder='INBOX') as mailbox:\n\n        # COPY messages with uid in 23,27 from current folder to folder1\n        mailbox.copy('23,27', 'folder1')\n\n        # MOVE all messages from current folder to INBOX/folder2, move by 100 emails at once\n        mailbox.move(mailbox.uids(), 'INBOX/folder2', chunks=100)\n\n        # DELETE messages with 'cat' word in its html from current folder\n        mailbox.delete([msg.uid for msg in mailbox.fetch() if 'cat' in msg.html])\n\n        # FLAG unseen messages in current folder as \\Seen, \\Flagged and TAG1\n        flags = (imap_tools.MailMessageFlags.SEEN, imap_tools.MailMessageFlags.FLAGGED, 'TAG1')\n        mailbox.flag(mailbox.uids(AND(seen=False)), flags, True)\n\n        # APPEND: add message to mailbox directly, to INBOX folder with \\Seen flag and now date\n        with open('/tmp/message.eml', 'rb') as f:\n            msg = imap_tools.MailMessage.from_bytes(f.read())  # *or use bytes instead MailMessage\n        mailbox.append(msg, 'INBOX', dt=None, flag_set=[imap_tools.MailMessageFlags.SEEN])\n\n📁 Actions with folders\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nBaseMailBox ``login,xoauth2`` arg ``initial_folder`` is \"INBOX\" by default, use None for not set folder on login.\n\n.. code-block:: python\n\n    with MailBox('imap.mail.com').login('test@mail.com', 'pwd') as mailbox:\n\n        # LIST: get all subfolders of the specified folder (root by default)\n        for f in mailbox.folder.list('INBOX'):\n            print(f)  # FolderInfo(name='INBOX|cats', delim='|', flags=('\\\\Unmarked', '\\\\HasChildren'))\n\n        # SET: select folder for work\n        mailbox.folder.set('INBOX')\n\n        # GET: get selected folder\n        current_folder = mailbox.folder.get()\n\n        # CREATE: create new folder\n        mailbox.folder.create('INBOX|folder1')\n\n        # EXISTS: check is folder exists (shortcut for list)\n        is_exists = mailbox.folder.exists('INBOX|folder1')\n\n        # RENAME: set new name to folder\n        mailbox.folder.rename('folder3', 'folder4')\n\n        # SUBSCRIBE: subscribe/unsubscribe to folder\n        mailbox.folder.subscribe('INBOX|папка два', True)\n\n        # DELETE: delete folder\n        mailbox.folder.delete('folder4')\n\n        # STATUS: get folder status info\n        stat = mailbox.folder.status('some_folder')\n        print(stat)  # {'MESSAGES': 41, 'RECENT': 0, 'UIDNEXT': 11996, 'UIDVALIDITY': 1, 'UNSEEN': 5}\n\n⏳ IDLE workflow\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIDLE logic are in ``mailbox.idle`` manager, its methods are in the table below:\n\n======== ============================================================================== ================================\nMethod   Description                                                                    Arguments\n======== ============================================================================== ================================\nstart    Switch on mailbox IDLE mode\npoll     Poll for IDLE responses                                                        timeout: |nbsp| Optional[float]\nstop     Switch off mailbox IDLE mode\nwait     Switch on IDLE, poll responses, switch off IDLE on response, return responses  timeout: |nbsp| Optional[float]\n======== ============================================================================== ================================\n\n.. code-block:: python\n\n    from imap_tools import MailBox, A\n\n    # waiting for updates 60 sec, print unseen immediately if any update\n    with MailBox('imap.my.moon').login('acc', 'pwd', 'INBOX') as mailbox:\n        responses = mailbox.idle.wait(timeout=60)\n        if responses:\n            for msg in mailbox.fetch(A(seen=False)):\n                print(msg.date, msg.subject)\n        else:\n            print('no updates in 60 sec')\n\nRead docstrings and see `detailed examples \u003chttps://github.com/ikvk/imap_tools/blob/master/examples/idle.py\u003e`_.\n\n⚠️ Exceptions\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nMost lib server actions raises exception if result is marked as not success.\n\nCustom lib exceptions here: `errors.py \u003chttps://github.com/ikvk/imap_tools/blob/master/imap_tools/errors.py\u003e`_.\n\n📜 Release notes\n------------------------------------------------------------------------------------------------------------------------\n\nHistory of important changes: `release_notes.rst \u003chttps://github.com/ikvk/imap_tools/blob/master/docs/release_notes.rst\u003e`_\n\n🛠️ Contribute\n------------------------------------------------------------------------------------------------------------------------\n\nIf you found a bug or have a question, then:\n\n1. Look for answer at: this page, issues, pull requests, `examples \u003chttps://github.com/ikvk/imap_tools/tree/master/examples\u003e`_, source, RFCs, stackoverflow.com, internet.\n2. And only then - create merge request or issue 🎯.\n\n💡 Reasons\n------------------------------------------------------------------------------------------------------------------------\n\n- Excessive low level of `imaplib` library.\n- Other libraries contain various shortcomings or not convenient.\n- Open source projects make world better.\n\n✨ Thanks\n------------------------------------------------------------------------------------------------------------------------\n\nIf the library helped you, please give it a star ⭐.\n\nBig thanks to people who helped to develop this library 🎉:\n\n`shilkazx \u003chttps://github.com/shilkazx\u003e`_,\n`somepad \u003chttps://github.com/somepad\u003e`_,\n`0xThiebaut \u003chttps://github.com/0xThiebaut\u003e`_,\n`TpyoKnig \u003chttps://github.com/TpyoKnig\u003e`_,\n`parchd-1 \u003chttps://github.com/parchd-1\u003e`_,\n`dojasoncom \u003chttps://github.com/dojasoncom\u003e`_,\n`RandomStrangerOnTheInternet \u003chttps://github.com/RandomStrangerOnTheInternet\u003e`_,\n`jonnyarnold \u003chttps://github.com/jonnyarnold\u003e`_,\n`Mitrich3000 \u003chttps://github.com/Mitrich3000\u003e`_,\n`audemed44 \u003chttps://github.com/audemed44\u003e`_,\n`mkalioby \u003chttps://github.com/mkalioby\u003e`_,\n`atlas0fd00m \u003chttps://github.com/atlas0fd00m\u003e`_,\n`unqx \u003chttps://github.com/unqx\u003e`_,\n`daitangio \u003chttps://github.com/daitangio\u003e`_,\n`upils \u003chttps://github.com/upils\u003e`_,\n`Foosec \u003chttps://github.com/Foosec\u003e`_,\n`frispete \u003chttps://github.com/frispete\u003e`_,\n`PH89 \u003chttps://github.com/PH89\u003e`_,\n`amarkham09 \u003chttps://github.com/amarkham09\u003e`_,\n`nixCodeX \u003chttps://github.com/nixCodeX\u003e`_,\n`backelj \u003chttps://github.com/backelj\u003e`_,\n`ohayak \u003chttps://github.com/ohayak\u003e`_,\n`mwherman95926 \u003chttps://github.com/mwherman95926\u003e`_,\n`andyfensham \u003chttps://github.com/andyfensham\u003e`_,\n`mike-code \u003chttps://github.com/mike-code\u003e`_,\n`aknrdureegaesr \u003chttps://github.com/aknrdureegaesr\u003e`_,\n`ktulinger \u003chttps://github.com/ktulinger\u003e`_,\n`SamGenTLEManKaka \u003chttps://github.com/SamGenTLEManKaka\u003e`_,\n`devkral \u003chttps://github.com/devkral\u003e`_,\n`tnusraddinov \u003chttps://github.com/tnusraddinov\u003e`_,\n`thepeshka \u003chttps://github.com/thepeshka\u003e`_,\n`shofstet \u003chttps://github.com/shofstet\u003e`_,\n`the7erm \u003chttps://github.com/the7erm\u003e`_,\n`c0da \u003chttps://github.com/c0da\u003e`_,\n`dev4max \u003chttps://github.com/dev4max\u003e`_,\n`ascheucher \u003chttps://github.com/ascheucher\u003e`_,\n`Borutia \u003chttps://github.com/Borutia\u003e`_,\n`nathan30 \u003chttps://github.com/nathan30\u003e`_,\n`daniel55411 \u003chttps://github.com/daniel55411\u003e`_,\n`rcarmo \u003chttps://github.com/rcarmo\u003e`_,\n`bhernacki \u003chttps://github.com/bhernacki\u003e`_,\n`ilep \u003chttps://github.com/ilep\u003e`_,\n`ThKue \u003chttps://github.com/ThKue\u003e`_,\n`repodiac \u003chttps://github.com/repodiac\u003e`_,\n`tiuub \u003chttps://github.com/tiuub\u003e`_,\n`Yannik \u003chttps://github.com/Yannik\u003e`_,\n`pete312 \u003chttps://github.com/pete312\u003e`_,\n`edkedk99 \u003chttps://github.com/edkedk99\u003e`_,\n`UlisseMini \u003chttps://github.com/UlisseMini\u003e`_,\n`Nicarex \u003chttps://github.com/Nicarex\u003e`_,\n`RanjithNair1980 \u003chttps://github.com/RanjithNair1980\u003e`_,\n`NickC-NZ \u003chttps://github.com/NickC-NZ\u003e`_,\n`mweinelt \u003chttps://github.com/mweinelt\u003e`_,\n`lucbouge \u003chttps://github.com/lucbouge\u003e`_,\n`JacquelinCharbonnel \u003chttps://github.com/JacquelinCharbonnel\u003e`_,\n`stumpylog \u003chttps://github.com/stumpylog\u003e`_,\n`dimitrisstr \u003chttps://github.com/dimitrisstr\u003e`_,\n`abionics \u003chttps://github.com/abionics\u003e`_,\n`link2xt \u003chttps://github.com/link2xt\u003e`_,\n`Docpart \u003chttps://github.com/Docpart\u003e`_,\n`meetttttt \u003chttps://github.com/meetttttt\u003e`_,\n`sapristi \u003chttps://github.com/sapristi\u003e`_,\n`thomwiggers \u003chttps://github.com/thomwiggers\u003e`_,\n`histogal \u003chttps://github.com/histogal\u003e`_,\n`K900 \u003chttps://github.com/K900\u003e`_,\n`homoLudenus \u003chttps://github.com/homoLudenus\u003e`_,\n`sphh \u003chttps://github.com/sphh\u003e`_,\n`bh \u003chttps://github.com/bh\u003e`_,\n`tomasmach \u003chttps://github.com/tomasmach\u003e`_,\n`errror \u003chttps://github.com/errror\u003e`_,\n`hurricane-dorian \u003chttps://github.com/hurricane-dorian\u003e`_,\n`dlucredativ \u003chttps://github.com/dlucredativ\u003e`_,\n`ziima \u003chttps://github.com/ziima\u003e`_\n\n\nHelp other open projects that you use 🚀\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikvk%2Fimap_tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fikvk%2Fimap_tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikvk%2Fimap_tools/lists"}