Sendmail problem

I used a simple program copied from a course book as follows:
msg = MIMEText(“Hallo daar!”)
msg[‘Subject’] = ‘Een testbericht’
msg[‘From’]= ‘pejamide@xs4all.nl’
msg[‘To’] = ‘jamie9ze@xs4all.nl’
s = smtplib.SMTP(‘localhost’)
s.sendmail(‘pejamide@xs4all.nl’, [‘jamie9ze@xs4all.nl’], msg.as_string())
print(“Bericht verstuurd!”)

After run an wait about 15 seconds I gor the errors as follows:
Traceback (most recent call last):
File “…\jan\testsendmail.py”, line 7, in
s = smtplib.SMTP(‘localhost’)
File “C:\Program Files\Python\lib\smtplib.py”, line 255, in init
(code, msg) = self.connect(host, port)
File “C:\Program Files\Python\lib\smtplib.py”, line 341, in connect
self.sock = self._get_socket(host, port, self.timeout)
File “C:\Program Files\Python\lib\smtplib.py”, line 312, in _get_socket
return socket.create_connection((host, port), timeout,
File “C:\Program Files\Python\lib\socket.py”, line 843, in create_connection
raise err
File “C:\Program Files\Python\lib\socket.py”, line 831, in create_connection
sock.connect(sa)
ConnectionRefusedError: [WinError 10061] Kan geen verbinding maken omdat de doelcomputer de verbinding actief heeft geweigerd

What should I have forgotten to do anything extra?

I am using localhost running under XAMPP Apache.

ConnectionRefusedError means that there is no service listening on
‘localhost’ for SMTP. Probably this line:

s = smtplib.SMTP('localhost')

needs to be adjusted to point at a server which will access an SMTP
connection.

Cheers,
Cameron Simpson cs@cskk.id.au

After the correction for SMTP, I got a new error as follows:
<class ‘smtplib.SMTPSenderRefused’>: (550, b’5.1.0 Please authenticate using your username and password [1465]’, ‘pejamide@xs4all.nl’)

I wonder me why I have to give the password for that user. And how and where I can give that password?

That depends on the server. Usually SMTP servers allow unauthenticated
delivery for some trusted networks (localhost, the local LAN network,
for an ISP often the networks of its users) but require authentication
for others if the target of the message is not their own domain i.e.
you can deliver email to the server for local delivery, but not ask the
server to deliver to other places without authentication.

The smtplib module has a login method:

https://docs.python.org/3/library/smtplib.html#smtplib.SMTP.login

BUT… be VERY sure you’re supplying a password to the right server and
DO NOT post the password in any script you post here! You’d be telling
the world your password! Usually we do not like to put passwords in
scripts at all - put it in a special file if you must and read it from
that file.

Cheers,
Cameron Simpson cs@cskk.id.au

I am surprised, that the password is required for the server ‘smtp.xs4all.nl’, because my PHP program running under the same Apache on my laptop donot need the password for sending an e-mail.
Is there maybe another python problem?

I am surprised, that the password is required for the server
‘smtp.xs4all.nl’, because my PHP program running under the same Apache
on my laptop donot need the password for sending an e-mail.

The error plainly asks for authentication. How you investigated the
mechanism used by PHP to send the email - maybe it isn’t using SMTP,
maybe it is using a different server.

Is there maybe another python problem?

Not at this point. The error plainly asks for authentication. Why,
depends on exactly what you’re doing. You haven’t said:

  • exactly what server you’re talking to
  • which smtplib call is producing the error message

Cheers,
Cameron Simpson cs@cskk.id.au

  • Concerning PHP command ‘mail’: it is indeed using SMTP server.

  • I use the specified one ‘smtp.xs4all.nl’.

  • The smtplib.sendmail command (see at the top for my mini code.

Hopefully you solve the code with the specified SMTP server.

Observe this direct conversation with the SMTP server:

[~]fleet2*> telnet smtp.xs4all.nl smtp
Trying 194.109.6.51...
Connected to smtp.xs4all.nl.
Escape character is '^]'.
220 smtp-cloud8.xs4all.net smtp-cloud8.xs4all.net ESMTP server ready
helo fleet
250 smtp-cloud8.xs4all.net hello [1.144.244.145], pleased to meet you
mail from:<pejamide@xs4all.nl>
550 5.1.0 Please authenticate using your username and password [1639]
Connection closed by foreign host.

Have you read the whole page at the URL you cite above? The discussion
section talks about configuring the sendmail.ini file here:

https://www.php.net/manual/en/function.mail.php#118210

which says that there is a PHP configuration section for specifying the
authentication credentials, so that the call code does not need to
bother. You will need to do something equivalent in your programme,
probably using the smtplib.login() method.

Cheers,
Cameron Simpson cs@cskk.id.au

Yeah, with login method it does work fine!
Now I wonder how I can pass the login like in PHP, because I dislike to keep the password in my program.

Very good idea.Keeping this information in a configuration is always to be preferred. Maybe you are spoiled for choice? :wink:
For a .ini file:

For a yaml file:

For a toml file:

This format may appear in the Standard Library, it is being used by pypi packaging.

For json:

You are right to not want to put credentials in the code.

Personally I keep the username/password in my .netrc file. Python has a
“netrc” module which provides access to this file. It is a simple way to
store login/pasword for systems where you want it. I would not use it
for banking access etc because the password is kept in the clear in a
text file.

But I do use it to fetch my email, and for a few other services.

The file itself lives at ~/.netrc, and should be readable ONY BY YOU (it
contails credentials).

This is fine for simple things; I would not use it for my banking
credentials etc etc.

The use is outlines in the netrc modue docs:

https://docs.python.org/3/library/netrc.html#module-netrc

but basicly:

from netrc import netrc
........
entry = netrc().hosts.get("username@service")
if entry is None:
    ... no such entry ...
else:
    login, account, password = entry

The key for hosts.get() is an arbitrary “hostname” (the netrc was
designed around FTP servers) but anything will do. For example, you
might make a clause like:

machine xs4all
    login ************
    password *************

and look this up from your programme as “xs4all”, then use the resulting
login/password in your SMTP login() call.

Cheers,
Cameron Simpson cs@cskk.id.au