Перейти к документации
Python

openemail.drafts

Каждый метод этого пространства имён: его сигнатура, параметры, что он возвращает, и пример.

Методы

Unsent messages saved in the mailbox.

drafts.list()

List one page of drafts

Разрешенияdrafts:readПостранично перебирает результаты
Сигнатура
def list(    *,    limit: int | None = None,    cursor: str | None = None,    query: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[DraftSummaryResource]

Returns one page of saved drafts, most recently saved first. A row is only object and id, so call get for recipients, subject and body. A draft is stored as a thread labelled DRAFT, so this reads the same index as threads.list(folder='draft').

query= takes the same search syntax as threads.list. Plain words must all appear and match loosely, ignoring case, accents and separators, against the draft's subject, its sender and the first 4,000 characters of its body with markup stripped, while a quoted phrase is matched as written apart from case and accents, so "ben jamin" does not find "Ben-Jamin". Filler words such as the or emails are dropped when something else is left to search for. Recipients are stored as one list without roles and are not written for a draft, so to:, cc: and bcc: match nothing here. subject:, body: and from: narrow the search, and after:, before:, newer_than: and older_than: read the time the draft was last saved, in UTC, with after: including the day it names and before: excluding it. A draft saved with no subject is stored as (no subject), so subject:"no subject" finds it. The drafts folder always applies, so in: and folder is: operators such as is:sent cannot widen the search beyond drafts, in:anywhere included.

The API pages with an opaque pageToken, which the SDK hands back as nextCursor and accepts as cursor=. A page holds 25 drafts unless limit= says otherwise.

Параметры

limitint

Drafts per page, a whole number from 1 to 100. Defaults to 25.

cursorstr

The nextCursor of the previous page, passed back unchanged.

querystr

Mailbox search over the subject, sender and body preview. Plain words must all appear and match loosely, a quoted phrase has to appear as written, filler words are dropped when something else is left to search for, and operators such as subject: and older_than:30d narrow it. to:, cc: and bcc: match nothing on a draft, and the search cannot leave drafts.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Возвращает

Page[DraftSummaryResource], a dict with items, hasMore and nextCursor. Each item holds only object, which is always draft, and id.

Пример

from openemail import openemail page = openemail.drafts.list(query='subject:proposal', limit=20) for summary in page['items']:    draft = openemail.drafts.get(summary['id'])     print(draft['id'], draft['subject'], draft['to']) print('More to read:', page['hasMore'])

Примечания

  • The server offers a cursor whenever a page comes back full, so hasMore can be True on the last page and the following call returns no items.

  • Saving a draft moves it to the top, so a draft edited while you page is not returned by later pages.

  • A value query= cannot use is ignored rather than narrowing, so a typo in a value widens the result instead of emptying it. That covers category:, larger:, smaller:, size:, messagesize:, list:, rfc822msgid:, received: and sent:, the category words such as is:promotions, a has: word naming no kind of attachment, an importance: other than high or low, an unreadable date and a duration whose unit is not h, d, w, m or y. An operator name it does not know, project: for instance, is searched as plain text.

Также доступно в

API
GET /drafts
TypeScript
drafts.list()
Ruby
drafts.list
CLI
openemail drafts list

drafts.list_all()

Collect every draft into one list

Разрешенияdrafts:readПостранично перебирает результаты
Сигнатура
def list_all(    *,    limit: int | None = None,    cursor: str | None = None,    query: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[DraftSummaryResource]

Walks every page with the same query= as list and returns once the last page is in, so the whole result sits in memory at once. Drafts rarely number in the thousands, which makes this the simplest way to read them all.

Each request asks for limit= drafts, 25 when you leave it out. Passing cursor= starts the walk from that page instead of the first. The walk ends at the first empty page or when the server stops offering a cursor, and a failure on any page raises and discards what was collected.

Параметры

limitint

Page size for each request, a whole number from 1 to 100. Defaults to 25.

cursorstr

A nextCursor to start the walk from instead of the first page.

querystr

Mailbox search over the subject, sender and body preview, as in list. Plain words must all appear and match loosely, a quoted phrase has to appear as written, filler words are dropped when something else is left to search for, and operators such as subject: and older_than:30d narrow it. to:, cc: and bcc: match nothing on a draft, and the search cannot leave drafts.

api_keystr

Overrides the client's API key for every page of this walk.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Возвращает

list[DraftSummaryResource], every matching draft as a dict of object and id, most recently saved first.

Пример

from openemail import openemail drafts = openemail.drafts.list_all(limit=100) print(len(drafts), 'drafts waiting')

Примечания

  • Rows are ids only. Reading each draft afterwards is one get per id.

  • Each page is its own request with its own retries, so one failed attempt does not restart the walk.

Также доступно в

API
GET /drafts
TypeScript
drafts.listAll()
Ruby
drafts.list_all

drafts.iterate()

Stream drafts one at a time across pages

Разрешенияdrafts:readПостранично перебирает результаты
Сигнатура
def iterate(    *,    limit: int | None = None,    cursor: str | None = None,    query: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[DraftSummaryResource]

Returns a generator that yields drafts one by one and requests the next page only when the current one is used up. Nothing is fetched until the loop starts, and breaking out of it stops further requests.

The cursor marks a position in save time rather than a row count, so deleting drafts inside the loop does not make the walk skip the ones after them. Updating a draft during the walk moves it to the top, and it is not yielded a second time.

Параметры

limitint

Page size for each request, a whole number from 1 to 100. Defaults to 25.

cursorstr

A nextCursor to start from instead of the first page.

querystr

Mailbox search over the subject, sender and body preview, as in list. Plain words must all appear and match loosely, a quoted phrase has to appear as written, filler words are dropped when something else is left to search for, and operators such as subject: and older_than:30d narrow it. to:, cc: and bcc: match nothing on a draft, and the search cannot leave drafts.

api_keystr

Overrides the client's API key for every page of this walk.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Возвращает

Iterator[DraftSummaryResource], a generator yielding one dict of object and id per step.

Пример

from openemail import openemail for summary in openemail.drafts.iterate(query='older_than:30d'):    draft = openemail.drafts.get(summary['id'])     if not draft['to'] and draft['subject'] == '(no subject)':        openemail.drafts.delete(draft['id'])

Примечания

  • The generator is lazy, so an abandoned loop costs only the pages it consumed.

Также доступно в

API
GET /drafts
TypeScript
drafts.iterate()
Ruby
drafts.iterate

drafts.get()

Read a draft's recipients, subject and body

Разрешенияdrafts:read
Сигнатура
def get(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DraftResource

Returns the fields a draft was saved with: to, cc, bcc, subject, the body as html, the from address, the threadId it replies to and its attachment list. The id must belong to a thread labelled DRAFT, so an ordinary thread id is a 404 here even though threads.get opens it.

Values come back normalised rather than as sent. Recipients are bare addresses with display names dropped, an empty subject reads as (no subject), and from is the address the draft was saved with. It is reported only while the workspace can still send as the stored sender, so a draft saved from an address that has since gone reads from as None, as does a draft saved without a sender. A draft saved with text and no html returns that text in html, unconverted.

threadId is None for a draft that does not reply to anything. attachments carries only filename and contentType, because draft attachments are stored as names and types without content.

Параметры

idstrОбязательно

Draft id, which starts with draft-.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Возвращает

DraftResource with id, to, cc, bcc, subject, html, from, threadId and attachments, each attachment a dict of filename and contentType.

Пример

from openemail import openemail draft = openemail.drafts.get('draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8') print(draft['from'], draft['to'], draft['subject'])print(draft['threadId'] or 'starts a new conversation')

Примечания

  • A draft keeps the same id through every update.

  • A missing draft raises OpenEmailApiError with is_not_found set to True.

Также доступно в

API
GET /drafts/{id}
TypeScript
drafts.get()
Ruby
drafts.get
CLI
openemail drafts get

drafts.create()

Save a new draft

Разрешенияdrafts:write
Сигнатура
def create(    body: DraftInput,    *,    api_key: str | None = None,    timeout: float | None = None,) -> SavedDraftResource

Saves an unsent message to the mailbox and returns its id. Every field is optional, so an empty dict saves a blank draft. The body is strict: any key outside the fields below is a 422 invalid_parameter, and there is no field for attachments.

Nothing is validated beyond length. Addresses in to, cc and bcc may carry a display name, as in Ada Lovelace <[email protected]>, and from is stored as given. A draft saved without from has no sender, and get reads from back as None. subject is capped at 998 characters, and html and text at 1,000,000 each. When both bodies are sent only html is kept.

threadId records the conversation the draft replies to, but the draft is stored as a thread of its own under its new id. It shows up in threads.list(folder='draft'), not inside the original thread.

Параметры

body['to']list[str]

Recipient addresses, bare or with a display name.

body['cc']list[str]

Copy recipients, bare or with a display name.

body['bcc']list[str]

Blind copy recipients, bare or with a display name.

body['subject']str

At most 998 characters. Empty is stored as (no subject).

body['html']str

Body markup, at most 1,000,000 characters. Kept over text when both are set.

body['text']str

Body used only when html is absent, at most 1,000,000 characters. Stored as is and read back in html.

body['from']str

Sender address, optionally with a display name. Left out, the draft is saved with no sender.

body['threadId']str

Id of the thread this draft replies to.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Возвращает

SavedDraftResource, a dict of object and id, where id is the new draft's id.

Пример

from openemail import openemail draft = openemail.drafts.create(    {        'from': 'Ada Lovelace <[email protected]>',        'to': ['[email protected]'],        'subject': 'Engine notes for Thursday',        'html': '<p>Agenda below, comments welcome.</p>',    }) print(draft['id'])

Примечания

  • The SDK does not retry a create after a network failure, because the endpoint takes no idempotency key and a second attempt saves a second draft.

  • A display name containing a comma splits into two broken recipients, because the lists are joined and split again on commas. Send such names without the comma.

  • Draft ids are draft- followed by a UUID.

Также доступно в

API
POST /drafts
TypeScript
drafts.create()
Ruby
drafts.create
CLI
openemail drafts create

drafts.update()

Change fields on a saved draft

Разрешенияdrafts:write
Сигнатура
def update(    id: str,    body: DraftInput,    *,    api_key: str | None = None,    timeout: float | None = None,) -> SavedDraftResource

A partial update: each field you send replaces the stored value and each field you leave out keeps it. Lists replace wholesale, so sending to with one address drops the rest. The limits and the strict body are the same as create.

The draft must already exist. An unknown id, or the id of a thread that is not a draft, is a 404 rather than a new draft. The returned id is the one to keep using, and it is always the id you passed.

Sending text without html replaces the stored body with that text. An update also empties the draft's attachment list, because draft attachments are stored as names and types without content and only entries with content are carried over.

Параметры

idstrОбязательно

Draft id, which starts with draft-.

body['to']list[str]

Replacement recipients. An empty list clears them.

body['cc']list[str]

Replacement copy recipients.

body['bcc']list[str]

Replacement blind copy recipients.

body['subject']str

Replacement subject, at most 998 characters.

body['html']str

Replacement body markup, at most 1,000,000 characters.

body['text']str

Replacement body used only when html is absent.

body['from']str

Replacement sender. An empty string clears it, leaving the draft with no sender.

body['threadId']str

Thread the draft replies to. An empty string detaches it.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Возвращает

SavedDraftResource, a dict of object and id.

Пример

from openemail import openemail draft_id = 'draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8' openemail.drafts.update(    draft_id,    {        'to': ['[email protected]', '[email protected]'],        'subject': 'Engine notes for Thursday, revised',    },) draft = openemail.drafts.get(draft_id) print(draft['to'], draft['subject'])

Примечания

  • The SDK does not retry this call after a network failure. Read the draft with get before trying again.

  • An empty string is the only way to clear threadId or from, since leaving a field out keeps its stored value.

Также доступно в

API
PATCH /drafts/{id}
TypeScript
drafts.update()
Ruby
drafts.update
CLI
openemail drafts update

drafts.delete()

Delete a draft permanently

Разрешенияdrafts:write
Сигнатура
def delete(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeletedDraftResource

Removes the draft, its stored body and its attachment entries from the mailbox. It does not go to the Bin and there is no undo.

The id must belong to a thread carrying the DRAFT label, so an ordinary thread id is a 404. Use threads.trash to remove real mail.

Параметры

idstrОбязательно

Draft id, which starts with draft-.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises OpenEmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Возвращает

DeletedDraftResource, a dict of object, id and deleted, which is always True.

Пример

from openemail import openemail removed = openemail.drafts.delete('draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8') print(removed['id'], removed['deleted'])

Примечания

  • The SDK does not retry a delete. A 404 on your own second attempt after a lost response means the first one worked.

  • threads.update refuses DRAFT with 422 label_not_directly_settable, so an ordinary thread can never be turned into something this method deletes.

Также доступно в

API
DELETE /drafts/{id}
TypeScript
drafts.delete()
Ruby
drafts.delete
CLI
openemail drafts delete