cole / aiosmtplib Goto Github PK
View Code? Open in Web Editor NEWasyncio smtplib implementation
License: MIT License
asyncio smtplib implementation
License: MIT License
Hello,
I'm having trouble sending several emails in a loop. When I do so, I've got an error apparently spawning randomly. Do you have any ideas of what the issue is?
Please read the code below.
from time import sleep
import email
import asyncio
import aiosmtplib
loop = asyncio.get_event_loop()
for i in range(20):
smtp = aiosmtplib.SMTP(hostname='gmail-smtp-in.l.google.com', port=25, loop=loop, use_tls=False)
msg = email.message_from_string(my_eml)
loop.run_until_complete(smtp.connect())
loop.run_until_complete(smtp.starttls())
loop.run_until_complete(smtp.send_message(msg))
sleep(0.5)
smtp.close()
loop.close()
Traceback (most recent call last):
File "test.py", line 33, in <module>
loop.run_until_complete(smtp.send_message(msg))
File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 468, in run_until_complete
return future.result()
File "/Users/myuser/.local/share/virtualenvs/proxy-D8_I7f06/lib/python3.6/site-packages/aiosmtplib/smtp.py", line 229, in send_message
sender, recipients, flat_message, timeout=timeout)
File "/Users/myuser/.local/share/virtualenvs/proxy-D8_I7f06/lib/python3.6/site-packages/aiosmtplib/smtp.py", line 155, in sendmail
response = await self.data(message, timeout=timeout)
File "/Users/myuser/.local/share/virtualenvs/proxy-D8_I7f06/lib/python3.6/site-packages/aiosmtplib/esmtp.py", line 278, in data
timeout=timeout)
File "/Users/myuser/.local/share/virtualenvs/proxy-D8_I7f06/lib/python3.6/site-packages/aiosmtplib/protocol.py", line 120, in read_response
line = await self._readline(timeout=timeout)
File "/Users/myuser/.local/share/virtualenvs/proxy-D8_I7f06/lib/python3.6/site-packages/aiosmtplib/protocol.py", line 227, in _readline
self._stream_reader.readuntil(separator=b'\n'), loop=self._loop)
AttributeError: 'NoneType' object has no attribute 'readuntil'
Python 3.6.5
aiosmtplib 1.0.2
Cheers,
Taslim42.
Hello.
Sometimes it may be desirable to send emails directly to remote mail servers instead of localhost
. In my case, I want to push books to Kindle devices by sending emails to @kindle.com
.
After roughly looking through the source code, I suppose there is no way so far to specify an email domain (e.g. kindle.com
in my case) instead of hostname
. I think it would be great if this can be supported by aiosmtplib as it is such a common use scenario. It does take much effort to figure out how to properly resolve and maintain cache/TTL of MX records with asyncio.
Thanks for the project.
When aiosmtplib
installed besides .../site-packages/aiosmtplib
directory there is also .../site-packages/docs
directory created with its docs.
Can this confusing behavior be changed?
It would be nice if the SMTP
class could be used as an async context manager. From digging around, it looks like it might be possible, but it isn't documented.
We should be able to pass a timeout to connect or init.
Can I connect to smtp server using unix socket?
When calling send_message
on an aiosmtplib connection where the remote end has closed, I'd expect to get a SMTPServerDisconnected
exception.
Instead, I get an assertion error, which is not the most ideal thing to handle:
File "aiosmtplib/smtp.py", line 229, in send_message
sender, recipients, flat_message, timeout=timeout)
File "aiosmtplib/smtp.py", line 152, in sendmail
await self.mail(sender, options=mail_options, timeout=timeout)
File "aiosmtplib/esmtp.py", line 217, in mail
b'MAIL', from_string, *options_bytes, timeout=timeout)
File "aiosmtplib/connection.py", line 270, in execute_command
*args, timeout=timeout)
File "aiosmtplib/protocol.py", line 178, in execute_command
await self.write_and_drain(command, timeout=timeout)
File "aiosmtplib/protocol.py", line 146, in write_and_drain
assert self._stream_writer is not None, 'Client not connected'
AssertionError: Client not connected
Python 3.5, aiosmtplib 1.0.2.
from wikipedia: https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
message should be:
From: [email protected]
To: [email protected]
Subject: Testing
content
async def send_hello_world():
message = EmailMessage()
client = SMTP(hostname="smtp.gmail.com", port=587,username='[email protected]',password='************', use_tls=False)
print("sandeep patel")
message["From"] = "[email protected]"
message["To"] = "[email protected]"
message["Subject"] = "Hello World!"
message.set_content("Sent via aiosmtplib")
async with client:
await client.smtp_client(message)
Getting Error
' raise SMTPException("SMTP AUTH extension not supported by server.")\n'
'aiosmtplib.errors.SMTPException: SMTP AUTH extension not supported by server.\n'
rt
I am unable to send emails from a Microsoft Exchange account hosted on Office365. My credentials are valid and I have succesfully tested sending emails with smtplib. For some reason SMTPAuth.server_auth_methods
ends up being an empty list and then sending an email fails with
SMTP AUTH extension not supported by server.
You can see a minimal working example below (I have not tried to reproduce the error without an Office 365 account).
import asyncio
from email.message import EmailMessage
import aiosmtplib
PASSWORD = 'password'
USER = '[email protected]'
async def send_hello_world():
message = EmailMessage()
message["From"] = '[email protected]'
message["To"] = "[email protected]"
message["Subject"] = "Hello World!"
message.set_content("Sent via aiosmtplib")
send = await aiosmtplib.send(message,
hostname="smtp.office365.com",
port=587,
password=PASSWORD,
username=USER)
return send
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(send_hello_world())
If provided, automatically call login on connect.
I've looked around in the tests for examples on how to properly send mails with non-ascii characters in address lines. I cannot get the following to work:
import asyncio
from email.message import EmailMessage
from aiosmtplib.email import formataddr
import aiosmtplib
PASSWORD = 'password'
USER = '[email protected]'
async def send_hello_world():
message = EmailMessage()
message["From"] = "[email protected]"
message["To"] = formataddr(("æøå", "[email protected]"))
message["Subject"] = "Hello World!"
message.set_content("Sent via aiosmtplib")
send = await aiosmtplib.send(message,
hostname="smtp.office365.com",
port=587,
start_tls=True,
password=PASSWORD,
username=USER)
return send
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(send_hello_world())
The interesting line is this: message["To"] = formataddr(("æøå", "[email protected]"))
. Theæøå
breaks the email somehow.
I do receive an email - however, there is no subject and the email body is the EmailMessage sort of converted to a string. I could succesfully send the email with smtplib with no issues. What do I nee
I ported this code from my old implementation on standard smtplib module, and perhaps it is not correct for aiosmtplib.
But i think this shouldn't matter.
import asyncio
import aiosmtplib
from email.mime.text import MIMEText
from email.header import Header
async def send_mail(host, login, password, from_addr, to_addr, subject, body_text):
msg=MIMEText(*body_text)
msg['Subject']=Header(subject, 'utf-8')
msg['From']=from_addr
msg['To']=to_addr
server=aiosmtplib.SMTP(host)
await server.connect()
await server.starttls()
await server.login(login, password)
try:
await server.sendmail(from_addr, [to_addr], msg.as_string())
except (aiosmtplib.SMTPRecipientsRefused, aiosmtplib.SMTPSenderRefused):
return 1
finally:
await server.quit()
#code for testing
async def start():
await send_mail('smtp.yandex.ru', '[email protected]', '1234', '[email protected]', '[email protected]', 'Testing', ['Hello', 'plain', 'utf-8'])
print('success')
#emulating work of other asyncio tasks...
await asyncio.sleep(3)
asyncio.run(start())```
```Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
>>> import mail_test
success
>>> exit()
Future exception was never retrieved
future: <Future finished exception=SMTPServerDisconnected('Unexpected EOF received')>
aiosmtplib.errors.SMTPServerDisconnected: Unexpected EOF received```
If i comment two last lines of my function, it works good.
```>>> import mail_test
success
>>> exit()```
I'd like to use this with email services (e.g. mandrill, sendgrid, Amazon SES) and as a pre-requisite it would need to support authentication.
Ideally it should support TLS for security, which may be a pre-requisite of some email services.
Can you make release 1.1.3?
test_send_message_smtputf8_sender is failing only on i586
Does it look like it is a aiosmtplib issue, or the test runner aiosmtpd, or ...?
[ 110s] ______________________ test_send_message_smtputf8_sender _______________________
[ 110s]
[ 110s] smtp_client = <aiosmtplib.smtp.SMTP object at 0xb485426c>
[ 110s] smtpd_server_smtputf8 = <Server sockets=[<socket.socket fd=15, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 52703)>]>
[ 110s] message = <email.mime.multipart.MIMEMultipart object at 0xb4ac66cc>
[ 110s] received_commands = [('EHLO', 'lamb56'), ('MAIL', 'séndër@exåmple.com', ['SIZE=345', 'SMTPUTF8', 'BODY=8BITMIME']), ('RCPT', '[email protected]', []), ('DATA',), ('QUIT',)]
[ 110s] received_messages = [<email.message.Message object at 0xb64846cc>]
[ 110s]
[ 110s] async def test_send_message_smtputf8_sender(
[ 110s] smtp_client, smtpd_server_smtputf8, message, received_commands, received_messages
[ 110s] ):
[ 110s] del message["From"]
[ 110s] message["From"] = "séndër@exåmple.com"
[ 110s]
[ 110s] async with smtp_client:
[ 110s] errors, response = await smtp_client.send_message(message)
[ 110s]
[ 110s] assert not errors
[ 110s] assert response != ""
[ 110s]
[ 110s] assert received_commands[1][0] == "MAIL"
[ 110s] assert received_commands[1][1] == message["From"]
[ 110s] > assert received_commands[1][2] == ["SIZE=372", "SMTPUTF8", "BODY=8BITMIME"]
[ 110s] E AssertionError: assert ['SIZE=345', ...ODY=8BITMIME'] == ['SIZE=372', '...ODY=8BITMIME']
[ 110s] E At index 0 diff: 'SIZE=345' != 'SIZE=372'
[ 110s] E Full diff:
[ 110s] E - ['SIZE=345', 'SMTPUTF8', 'BODY=8BITMIME']
[ 110s] E ? ^^
[ 110s] E + ['SIZE=372', 'SMTPUTF8', 'BODY=8BITMIME']
[ 110s] E ? ^^
[ 110s]
[ 110s] tests/test_sendmail.py:288: AssertionError
I have a problem with connect operation not terminating after timeout. For example you can try to connect to wrong port:
import asyncio
import aiosmtplib
loop = asyncio.get_event_loop()
smtp = aiosmtplib.SMTP('smtp-mail.outlook.com', 5871, use_tls=True)
async def connect_and_print(smtp):
await smtp.connect()
print('connected')
loop.run_until_complete(connect_and_print(smtp))
This code hangs for a long-long time. I also tried to wrap connect into asyncio.wait_for
but it also doesn't work.
When calling the sendmail method after the open connection timed-out, the exception raised is SMTPSenderRefused, with the message " Error: timeout exceeded".
Probably, the exception shoud be SMTPServerDisconnected.
In the connect() method, if an error occurs (here or here) the connection is not closed since the transport attribute is only set at the end of the method (here). I think that as soon as the connection to the server is made, the transport attribute should be set otherwise the close() method does nothing.
Try the following snippet:
import aiosmtplib, asyncio
async def c():
s = aiosmtplib.SMTP('asd.asd.com')
try:
await s.connect()
except:
print('error raised for the first time')
try:
await s.connect()
except:
print('error raised for the first time, exiting')
return
asyncio.get_event_loop().run_until_complete(c())
I would expect for the same error to be raised twice, but the obtained result was that an error is raised only for the first connection and the second one hangs indefinitely.
I'm running aiosmtplib 1.0.2 under python 3.6.6.
https://github.com/cole/aiosmtplib/blob/master/aiosmtplib/smtp.py#L56
I think the return response code shall be checked, if it's not 220(or store it in attribute so it can be checked later)
@cole Hello cole, thanks for the good library, learned a lot from this cool asyncio library.
As you said in the parallel execution, we can't gain a lot from asynchronous communication since SMTP is sequential protocol, thus even with async, we can only send email one by one, thus we can't solve I/O bound issue except creating a new SMTP client.
so this means we either have lots of emails to send to one smtp server, or emails belongs to different smtp server, thus we gain benefits? and have you done some benchmark some comparing to sync smtp client in threads?
When connecting to port 25 or 587 and using TLS, SMTP.connect() has to initiate a plaintext connection before issuing starttls.
Traceback (most recent call last):
File "/git/dnd/lib64/python3.6/site-packages/aiosmtplib/connection.py", line 46, in create_connection
connect_future, timeout=timeout, loop=loop)
File "/usr/lib64/python3.6/asyncio/tasks.py", line 352, in wait_for
return fut.result()
File "/usr/lib64/python3.6/asyncio/base_events.py", line 802, in create_connection
sock, protocol_factory, ssl, server_hostname)
File "/usr/lib64/python3.6/asyncio/base_events.py", line 828, in _create_connection_transport
yield from waiter
File "/usr/lib64/python3.6/asyncio/sslproto.py", line 503, in data_received
ssldata, appdata = self._sslpipe.feed_ssldata(data)
File "/usr/lib64/python3.6/asyncio/sslproto.py", line 201, in feed_ssldata
self._sslobj.do_handshake()
File "/usr/lib64/python3.6/ssl.py", line 683, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:749)
async with aiosmtplib.SMTP(
loop=cfg.APP.loop,
hostname=cfg.SMTP_HOST,
port=cfg.SMTP_PORT,
use_tls=cfg.SMTP_TLS,
) as smtp:
if cfg.SMTP_TLS:
await smtp.starttls(validate_certs=False)
if cfg.SMTP_USERNAME:
await smtp.login(cfg.SMTP_USERNAME, cfg.SMTP_PASSWORD)
msg = MIMEText(body, 'html')
msg['Subject'] = subject
msg['From'] = cfg.SMTP_SENDER
msg['To'] = recipient
await smtp.send_message(msg)
To be clear, cfg.SMTP_PORT was set to 587, and cfg.SMTP_TLS to True in this case.
Hey, I'm trying to run some code to send some emails, however, I am already using the event loop for another task. When I try running the line loop.run_until_complete(smtp.connect())
I get the following error " RuntimeError: This event loop is already running ".
Could you please add the license file to MANIFEST.in
and setup.cfg
so that it will be included in sdist
s, whl
s, and other packages?
I'm using the last revision (f5ce158
) of the master
branch and getting the following exception:
InvalidStateError: invalid state
File "asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "asyncio/selector_events.py", line 913, in _call_connection_lost
super()._call_connection_lost(exc)
File "asyncio/selector_events.py", line 687, in _call_connection_lost
self._protocol.connection_lost(exc)
File "aiosmtplib/protocol.py", line 79, in connection_lost
self._connection_lost_waiter.set_result(None)
Hi Cole,
I was reading the test and see the test_live.py::test_qq_login has been marked because of utf-8 unsupported. As far as I investigated, the reason is that qq smtp service return non-ascii (and even non utf-8 chars):
535 Error: \xc7\xeb\xca\xb9\xd3\xc3\xca\xda\xc8\xa8\xc2\xeb\xb5\xc7\xc2\xbc\xa1\xa3\xcf\xea\xc7\xe9\xc7\xeb\xbf\xb4: http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256\r\n
I was thinking of 2 posibility to solve this problem:
re
to eliminate non-utf8 (ascii) chars since it is the message, we still have response codeWhat do you think?
I'm specifying "From" header at Message
object but it's not enough, - aiosmtplib.errors.SMTPNotSupported: An address containing non-ASCII characters was provided, but SMTPUTF8 is not supported by this server
is raised.
The code is as follows:
import asyncio
from email.header import Header
from email.message import EmailMessage
import aiosmtplib
async def main():
message = EmailMessage()
message['Subject'] = 'Subject'
sender = Header('Pepé', 'utf-8').encode()
message['From'] = sender
message['To'] = ('[email protected]',)
message.set_content('Body')
# Working
await aiosmtplib.send(message, sender, hostname='smtp.host')
# Not working
await aiosmtplib.send(message, hostname='smtp.host')
asyncio.run(main())
send_message
raise AttributeError
it works on 1.0.6
, failing on 1.1.0
using official docker image python:3.7.4
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/faust/agents/agent.py", line 632, in _execute_task
await coro
File "/usr/local/lib/python3.7/site-packages/faust/agents/agent.py", line 649, in _slurp
async for value in it:
File "/tmp/streams/email/__init__.py", line 120, in process_message
await smtp.send_message(msg, recipients=message['recipients'])
File "/usr/local/lib/python3.7/site-packages/aiosmtplib/smtp.py", line 291, in send_message
flat_message = flatten_message(message, utf8=utf8_required, cte_type=cte_type)
File "/usr/local/lib/python3.7/site-packages/aiosmtplib/email.py", line 84, in flatten_message
generator.flatten(message_copy)
File "/usr/local/lib/python3.7/email/generator.py", line 116, in flatten
self._write(msg)
File "/usr/local/lib/python3.7/email/generator.py", line 195, in _write
self._write_headers(msg)
File "/usr/local/lib/python3.7/email/generator.py", line 418, in _write_headers
self._fp.write(self.policy.fold_binary(h, v))
File "/usr/local/lib/python3.7/email/policy.py", line 200, in fold_binary
folded = self._fold(name, value, refold_binary=self.cte_type=='7bit')
File "/usr/local/lib/python3.7/email/policy.py", line 208, in _fold
lines = value.splitlines()
AttributeError: 'Header' object has no attribute 'splitlines'
I was about to send you guys a PR but looks like the issue of cleaning up the connection when exception occurs has been fixed but has not been published yet. I am waiting on this new version to get unblocked in one of my projects. Could you publish a new version that includes this commit?
Many thanks.
This is not the issue. I have email script in traditional smtp. How I can port to aiosmtplib? Is there any steps can you please help me with that?
If I try something similar to the issue: 112, will it work?
Thanks..
Not sure if it supports cc
and bcc
as I check the code and not found these options.
Hi,
thanks for the great lib, now I use it couple with tornado to send email async.
there is a problem with the check here
https://github.com/cole/aiosmtplib/blob/master/aiosmtplib/smtp.py#L464
it does nothing
I still need to do ehlo() every time to make it work, otherwise I will get 503
async with smtp:
await smtp.ehlo()
await smtp.login(...)
...
await smtp.send_message()
I'm not very familiar with smtp protocol, also I wonder whether there's a plan to simplify the process to be like
smtp = SMTP(host, port, user, pwd)
async with smtp:
...
await smtp.send_message(...)
so I don't need to worry about the login each time
I'm trying to use a remote SMTP server that requires a email and password. Though the SMTP class doesn't appear to take a username and password as it arguments. I did find the SMTP.auth_login
function in the documentation.
I've managed to establish what I think is a secure connection, though I'm unsure if I'm using the API correctly. Here's what I have:
smtp = aiosmtplib.SMTP(
hostname=SMTP_HOSTNAME,
port=SMTP_PORT,
use_tls=False)
_ = await smtp.connect()
_ = await smtp.ehlo()
_ = await smtp.starttls()
_ = await smtp.ehlo()
_ = await smtp.auth_login(SMTP_USERNAME, SMTP_PASSWORD)
I feel like I may be calling internal API stuff or, if I'm meant to, I may be doing it incorrectly. My knowleage of SMTP servers/protocols is between zero and none.
Thanks for the library.
This script that sends using yahoo smtp works:
import smtplib
from email.mime.text import MIMEText
SMTP_SERVER = "smtp.mail.yahoo.com"
SMTP_PORT = 587
SMTP_USERNAME = "foo" # without @yahoo.com
SMTP_PASSWORD = "bar"
EMAIL_FROM = "[email protected]"
EMAIL_TO = "[email protected]"
EMAIL_SUBJECT = "hi from smtplib"
co_msg = """
Hello world!
"""
def send_email():
msg = MIMEText(co_msg)
msg['Subject'] = EMAIL_SUBJECT
msg['From'] = EMAIL_FROM
msg['To'] = EMAIL_TO
debuglevel = True
mail = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
mail.set_debuglevel(debuglevel)
mail.starttls()
mail.login(SMTP_USERNAME, SMTP_PASSWORD)
mail.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string())
mail.quit()
if __name__=='__main__':
send_email()
But using aiosmtplib it always fails with:
File "/home/thijs/.virtualenvs/foo/lib/python3.7/site-packages/aiosmtplib/api.py", line 397, in send
message, sender=sender, recipients=recipients
File "/home/thijs/.virtualenvs/foo/lib/python3.7/site-packages/aiosmtplib/smtp.py", line 299, in send_message
timeout=timeout,
File "/home/thijs/.virtualenvs/foo/lib/python3.7/site-packages/aiosmtplib/smtp.py", line 179, in sendmail
raise exc
File "/home/thijs/.virtualenvs/foo/lib/python3.7/site-packages/aiosmtplib/smtp.py", line 170, in sendmail
response = await self.data(message, timeout=timeout)
File "/home/thijs/.virtualenvs/foo/lib/python3.7/site-packages/aiosmtplib/esmtp.py", line 332, in data
return await self.protocol.execute_data_command(message, timeout=timeout)
File "/home/thijs/.virtualenvs/foo/lib/python3.7/site-packages/aiosmtplib/protocol.py", line 252, in execute_data_command
raise SMTPDataError(response.code, response.message)
aiosmtplib.errors.SMTPDataError: (550, 'Request failed; Mailbox unavailable')
mail:
host: smtp.mail.yahoo.com
port: 587
tls: True
timeout: 300
username: foo
password: foo
sender: [email protected]
recipient: [email protected]
validate_certs: False
await aiosmtplib.send(
message=msg,
hostname=mail_cfg.get('host'),
port=mail_cfg.get('port'),
username=mail_cfg.get('username'),
password=mail_cfg.get('password'),
start_tls=mail_cfg.get('tls'),
timeout=mail_cfg.get('timeout'),
validate_certs=mail_cfg.get('validate_certs')
Any idea? Is there any DEBUG flag I can enable, like mail.set_debuglevel(debuglevel)
in example above?
Today, the aiosmtplib only accepts email body as string or bytes. It means that the mail should be completly loaded in memory before begining to send it.
With asyncio, it is very easy to work with streams (generated on the fly, read from files, pipes, sockets, etc). Moreover, if we want to send more that a few emails, we should either send them sequentially or load all of them in memory. In either case, we loose one of the feature of async programmming.
It would be nice to support email bodies as something else than just static buffers (string or bytes). Have a look at the aiohttp multipart module (http://aiohttp.readthedocs.io/en/stable/multipart.html). It enables to build a MIME Multipart body by attaching string, bytes, but also HTTP Responses, streams, etc. The content is serialized on the fly when using the object, and can be streamed to a socket or the standard output.
It would be nice to allow a streamable object as a message body, allowing not to load the content completly into memory while sending it.
Following the resolution of #42, is it possible to upload a new release to PyPI? I'm asking this because at my work place we rely on PyPI to deploy our softwares.
PS : I'm sorry to use the issue tracker to ask you that but I don't know a better way :(
How to implement this with aiohttp server, example for postgres asyncpg i can create a pool but here duno how at all :(
Hi,
in our production environment, we need a proxy to send email, is there any plan to support it?
thanks,
Especially multipart messages
I'm using uvloop because of the significant speed up that it provides. However this seems to be incompatible with using the starttls method.
minimal example (put in actual connection information before running):
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
import aiosmtplib
async def connect(loop):
smtp = aiosmtplib.SMTP(
loop=loop,
hostname=localhost,
port=port,
use_tls=True)
await smtp.connect(use_tls=False, port=port)
await smtp.starttls(validate_certs=False)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(connect(loop))
result
Traceback (most recent call last):
File "minimal_example.py", line 19, in <module>
loop.run_until_complete(connect(loop))
File "uvloop/loop.pyx", line 1203, in uvloop.loop.Loop.run_until_complete (uvloop/loop.c:25632)
File "minimal_example.py", line 15, in connect
await smtp.starttls(validate_certs=False)
File "/git/dnd/lib64/python3.6/site-packages/aiosmtplib/esmtp.py", line 193, in starttls
tls_context, server_hostname=server_hostname, timeout=timeout)
File "/git/dnd/lib64/python3.6/site-packages/aiosmtplib/protocol.py", line 209, in starttls
tls_context, server_hostname=server_hostname, waiter=waiter)
File "/git/dnd/lib64/python3.6/site-packages/aiosmtplib/protocol.py", line 82, in upgrade_transport
self.reader._transport._protocol = tls_protocol # type: ignore
AttributeError: 'uvloop.loop.TCPTransport' object has no attribute '_protocol'
I created a client
smtp = SMTP(...)
and the code of sending email
async def send_mails(smtp):
async with smtp:
await smtp.ehlo()
await smtp.login()
await smtp.send_message()
if it's called concurrently I will get errors:
aiosmtplib.errors.SMTPResponseException: (250, 'PIPELINING\nSTARTTLS\nAUTH=LOGIN\n8BITMIME')
aiosmtplib.errors.SMTPHeloError: (221, 'smtp.qq.com\nSIZE 73400320\nAUTH LOGIN PLAIN\nMAILCOMPRESS\nBye')
aiosmtplib.errors.SMTPResponseException: (-1, 'Malformed SMTP response: ')
Is there some form of locking implemented in a single instance?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.