FLOSS Project Planets
Stack Abuse: Securing Your Email Sending With Python: Authentication and Encryption
Email encryption and authentication are modern security techniques that you can use to protect your emails and their content from unauthorized access.
Everyone, from individuals to business owners, uses emails for official communication, which may contain sensitive information. Therefore, securing emails is important, especially when cyberattacks like phishing, smishing, etc. are soaring high.
In this article, I'll discuss how to send emails in Python securely using email encryption and authentication.
Setting Up Your Python EnvironmentBefore you start creating the code for sending emails, set up your Python environment first with the configurations and libraries you'll need.
You can send emails in Python using:
-
Simple Mail Transfer Protocol (SMTP): This application-level protocol simplifies the process since Python offers an in-built library or module (smtplib) for sending emails. It's suitable for businesses of all sizes as well as individuals to automate secure email sending in Python. We're using the Gmail SMTP service in this article.
-
An email API: You can leverage a third-party API like Mailtrap Python SDK, SendGrid, Gmail API, etc., to dispatch emails in Python. This method offers more features and high email delivery speeds, although it requires some investment.
In this tutorial, we're opting for the first choice - sending emails in Python using SMTP, facilitated by the smtplib library. This library uses the RFC 821 protocol and interacts with SMTP and mail servers to streamline email dispatch from your applications. Additionally, you should install packages to enable Python email encryption, authentication, and formatting.
Step 1: Install PythonInstall the Python programming language on your computer (Windows, macOS, Linux, etc.). You can visit the official Python website and download and install it from there.
If you've already installed it, run this code to verify it:
python --version
Step 2: Install Necessary Modules and Libraries-
smtplib: This handles SMTP communications. Use the code below to import 'smtplib' and connect with your email server:
import smtplib -
email module: This provides classes (Subject, To, From, etc.) to construct and parse emails. It also facilitates email encoding and decoding with Multipurpose Internet Mail Extensions (MIME).
-
MIMEText: It's used for formatting your emails and supports sending emails with text and attachments like images, videos, etc. Import this using the code below:
import MIMEText -
MIMEMultipart: Use this library to add attachments and text sections separately in your email.
import MIMEMultipart -
ssl: It provides Secure Sockets Layer (SSL) encryption.
To send emails using the Gmail SMTP email service, I recommend creating a test account to develop the code. Delete the account once you've tested the code.
The reason is, you'll need to modify the security settings of your Gmail account to enable access from the Python code for sending emails. This might expose the login details, compromising security. In addition, it will flood your account with too many test emails.
So, instead of using your own Gmail account, create a new one for creating and testing the code. Here's how to do this:
- Create a fresh Gmail account
- Set up your app password:
Google Account > Security > Turn on 2-Step Verification > Security > Set up an App Password
Next, define a name for the app password and click on "Generate". You'll get a 16-digit password after following some instructions on the screen. Store the password safely.
Use this password while sending emails in Python. Here, we're using Gmail SMTP, but if you want to use another mail service provider, follow the same process. Alternatively, contact your company's IT team to seek support in accessing your SMTP server.
Email Authentication With PythonEmail authentication is a security mechanism that verifies the sender's identity, ensuring the emails from a domain are legitimate. If you have no email authentication mechanism in place, your emails might land in spam folders, or malicious actors can spoof or intercept them. This could affect your email delivery rates and the sender's reputation.
This is the reason you must enable Python email authentication mechanisms and protocols, such as:
-
SMTP authentication: If you're sending emails using an SMTP server like Gmail SMTP, you can use this method of authentication. It verifies the sender's authenticity when sending emails via a specific mail server.
-
SPF: Stands for Sender Policy Framework and checks whether the IP address of the sending server is among
-
DKIM: Stands for DomainKeys Identified Mail and is used to add a digital signature to emails to ensure no one can alter the email's content while it's in transmission. The receiver's server will then verify the digital signature. Thus, all your emails and their content stay secure and unaltered.
-
DMARC: Stands for Domain-based Message Authentication, Reporting, and Conformance. DMARC instructs mail servers what to do if an email fails authentication. In addition, it provides reports upon detecting any suspicious activities on your domain.
To authenticate your email in Python using SMTP, the smtplib library is useful. Here's how Python SMTP security works:
import smtplib server = smtplib.SMTP('smtp.domain1.com', 587) server.starttls() # Start TLS for secure connection server.login('my_email@domain1.com', 'my_password') message = "Subject: Test Email." server.sendmail('my_email@domain1.com', 'receiver@domain2.com', message) server.quit()Implementing email authentication will add an additional layer of security to your emails and protect them from attackers or from being marked as spam.
Encrypting Emails With PythonEncrypting emails enables you to protect your email's content so that only authorized senders and receivers can access or view the content. Encrypting emails with Python is done using encryption techniques to encode the email message and transform it into a secure and unreadable format (also known as ciphertext).
This way, email encryption secures the message from unauthorized access or attackers even if they intercept the email.
Here are different types of email encryption:
-
SSL: This stands for Secure Sockets Layer, one of the most popular and widely used encryption protocols. SSL ensures email confidentiality by encrypting data transmitted between the mail server and the client.
-
TLS: This stands for Transport Layer Security and is a common email encryption protocol today. Many consider it a great alternative to SSL. It encrypts the connection between an email client and the mail server to prevent anyone from intercepting the email during its transmission.
-
E2EE: This stands for end-to-end encryption, ensuring only the intended recipient with valid credentials can decrypt the email content and read it. It aims to prevent email interception and secure the message.
If your mail server requires SSL encryption, here's how to send an email in Python:
import smtplib import ssl context = ssl.create_default_context() server = smtplib.SMTP_SSL('smtp.domain1.com', 465, context=context) # This is for SSL connections, requiring port number 465 server.login('my_email@domain1.com', 'my_password') message = "Subject: SSL Encrypted Email." server.sendmail('my_email@domain1.com', 'receiver@domain2.com', message) server.quit()For TLS connections, you'll need the smtplib library:
import smtplib server = smtplib.SMTP('smtp.domain1.com', 587) # TLS requires 587 port number server.starttls() # Start TLS encryption server.login('my_email@domain1.com', 'my_password') message = "Subject: TLS Encrypted Email." server.sendmail('my_email@domain1.com', 'receiver@domain2.com', message) server.quit()For end-to-end encryption, you'll need more advanced libraries or tools such as GnuPG, OpenSSL, Signal Protocol, and more.
Combining Authentication and EncryptionEmail Security with Python requires both encryption and authentication. This ensures that mail servers find the email legitimate and it stays safe from cyber attackers and unauthorized access during transmission. For email encryption, you can use either SSL or TLS and combine it with SMTP authentication to establish a robust email connection.
Now that you know how to enable email encryption and authentication in your emails, let's examine some complete code examples to understand how you can send secure emails in Python using Gmail SMTP and email encryption (SSL).
Code Examples
1. Sending a Plain Text Email import smtplib from email.mime.text import MIMEText subject = "Plain Text Email" body = "This is a plain text email using Gmail SMTP and SSL." sender = "sender1@gmail.com" receivers = ["receiver1@gmail.com", "receiver2@gmail.com"] password = "my_password" def send_email(subject, body, sender, receivers, password): msg = MIMEText(body) msg['Subject'] = subject msg['From'] = sender msg['To'] = ', '.join(receivers) with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp_server: smtp_server.login(sender, password) smtp_server.sendmail(sender, receivers, msg.as_string()) print("The plain text email is sent successfully!") send_email(subject, body, sender, receivers, password)Explanation:
- sender: This contains the sender's address.
- receivers: This contains email addresses of receiver 1 and receiver 2.
- msg: This is the content of the email.
- sendmail(): This is the SMTP object's instance method. It takes three parameters - sender, receiver, and msg and sends the message.
- with: This is a context manager that is used to properly close an SMTP connection once an email is sent.
- MIMEText: This holds only plain text.
To send an email in Python with attachments securely, you will need some additional libraries like MIMEBase and encoders. Here's the code for this case:
import smtplib from email import encoders from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText sender = "sender1@gmail.com" password = "my_password" receiver = "receiver1@gmail.com" subject = "Email with Attachments" body = "This is an email with attachments created in Python using Gmail SMTP and SSL." with open("attachment.txt", "rb") as attachment: part = MIMEBase("application", "octet-stream") # Adding the attachment to the email part.set_payload(attachment.read()) encoders.encode_base64(part) part.add_header( "Content-Disposition", # The header indicates that the file name is an attachment. f"attachment; filename='attachment.txt'", ) message = MIMEMultipart() message['Subject'] = subject message['From'] = sender message['To'] = receiver html_part = MIMEText(body) message.attach(html_part) # To attach the file message.attach(part) with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server: server.login(sender, password) server.sendmail(sender, receiver, message.as_string())Explanation:
- MIMEMultipart: This library allows you to add text and attachments both to an email separately.
- 'rb': It represents binary mode for the attachment to be opened and the content to be read.
- MIMEBase: This object is applicable to any file type.
- Encode and Base64: The file will be encoded in Base64 for safe email sending.
To send an HTML email in Python using Gmail SMTP, you need a class - MIMEText.
Here's the full code for Python send HTML email:
import smtplib from email.mime.text import MIMEText sender = "sender1@gmail.com" password = "my_password" receiver = "receiver1@gmail.com" subject = "HTML Email in Python" body = """ <html> <body> <p>HTML email created in Python with SSL and Gmail SMTP.</p> </body> </html> """ message = MIMEText(body, 'html') # To attach the HTML content to the email message['Subject'] = subject message['From'] = sender message['To'] = receiver with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server: server.login(sender, password) server.sendmail(sender, receiver, message.as_string()) Testing Your Email With Authentication and EncryptionTesting your emails before sending them to the recipients is important. It enables you to discover any issues or bugs in sending emails or with the formatting, content, etc.
Thus, always test your emails on a staging server before delivering them to your target recipients, especially when sending emails in bulk. Testing emails provide the following advantages:
- Ensures the email sending functionality is working fine
- Emails have proper formatting and no broken links or attachments
- Prevents flooding the recipient's inbox with a large number of test emails
- Enhances email deliverability and reduces spam rates
- Ensures the email and its contents stay protected from attacks and unauthorized access
To test this combined setup of sending emails in Python with authentication and encryption enabled, use an email testing server like Mailtrap Email Testing. This will capture all the SMTP traffic from the staging environment, and detect and debug your emails before sending them. It will also analyze the email content, validate CSS/HTML, and provide a spam score so you can improve your email sending.
To get started:
- Open Mailtrap Email Testing
- Go to 'My Inbox'
- Click on 'Show Credentials' to get your test credentials - login and password details
Here's the Full Code Example for Testing Your Emails:
import smtplib from socket import gaierror port = 2525 # Define the SMTP server separately smtp_server = "sandbox.smtp.mailtrap.io" login = "xyz123" # Paste your Mailtrap login details password = "abc$$" # Paste your Mailtrap password sender = "test_sender@test.com" receiver = "test_receiver@example.com" message = f"""\ Subject: Hello There! To: {receiver} From: {sender} This is a test email.""" try: with smtplib.SMTP(smtp_server, port) as server: # Use Mailtrap-generated credentials for port, server name, login, and password server.login(login, password) server.sendmail(sender, receiver, message) print('Sent') except (gaierror, ConnectionRefusedError): # In case of errors print('Unable to connect to the server.') except smtplib.SMTPServerDisconnected: print('Server connection failed!') except smtplib.SMTPException as e: print('SMTP error: ' + str(e))If there's no error, you should see this message in the receiver's inbox:
This is a test email. Best Practices for Secure Email SendingConsider the below Python email best practices for secure email sending:
-
Protect data: Take appropriate security measures to protect your sensitive data such as SMTP credentials, API keys, etc. Store them in a secure, private place like config files or environment variables, ensuring no one can access them publicly.
-
Encryption and authentication: Always use email encryption and authentication so that only authorized individuals can access your emails and their content.
For authentication, you can use advanced methods like API keys, two-factor authentication, single sign-on (SSO), etc. Similarly, use advanced encryption techniques like SSL, TLS, E2EE, etc.
-
Error handling: Manage network issues, authentication errors, and other issues by handling errors effectively using except/try blocks in your code.
-
Rate-Limiting: Maintain high email deliverability by rate-limiting the email sending functionality to prevent exceeding your service limits.
-
Validate Emails: Validate email addresses from your list and remove invalid ones to enhance email deliverability and prevent your domain from getting marked as spam. You can use an email validation tool to do this.
-
Educate: Keep your team updated with secure email practices and cybersecurity risks. Monitor your spam score and email deliverability rates, and work to improve them.
Secure email sending with Python using advanced email encryption methods like SSL, TLS, and end-to-end encryption, as well as authentication protocols and techniques such as SPF, DMARC, 2FA, and API keys.
By combining these security measures, you can protect your confidential email information, improve email deliverability, and maintain trust with your target recipients. In this way, only individuals with appropriate credentials can access it. This will help prevent unauthorized access, data breaches, and other cybersecurity attacks.
The Python Show: 47 - Python Projects of 2024
I’ve been working on lots of projects this year. Here are the ones I highlighted in this episode:
JupyterLab 101 Book on Kickstarter
A book on Textual
Oliver Davies' daily list: The two ways of writing PHP code
Something that came up in my discussion with Dave Liddament for the Beyond Blocks podcast was that there seem to be two ways of writing PHP code.
One is writing strict code by enabling strict typing, using parameter and return types, and leveraging tools like PHPStan at a high level to analyze code.
The other is no not use types and to use a more "duck typing" approach.
The term "visual debt" came from a video discussing the pros and cons of these approaches.
The same can be said for JavaScript and TypeScript, but PHP can do both and gives the Developer the choice of how they write their code.
I prefer writing strict code and for my code to be as explicit as possible, but I appreciate not everyone does and I like that PHP caters for both.
How do you write your PHP code?
Armin Ronacher: Accidental Spending: A Case For an Open Source Tax?
Both last week at London tech leaders and this week at the Open Source Summit in Vienna I engaged in various discussions about pledging money to Open Source. At Sentry we have been funding our Open Source dependencies for a few years now and we're trying to encourage others to do the same.
It’s not an easy ask, of course. One quite memorable point raised was what I would call “accidental spending”. The story goes like this: an engineering team spins up a bunch of Kubernetes machines. As the fleet grows in scale some inefficiencies creep in. To troubleshoot or optimize, additional services such as load balancers, firewalls, cloud provider log services, etc. are provisioned with minimal discussion. Initially none of that was part of the plan, but ever so slightly for every computing resource, some extra stuff is paid on top creating largely hidden costs. Ideally all of that pays off (after all, hopefully by debugging quicker you reduce that downtime, by having that load balancer you can auto scale and save on unused computing resources etc.). But often, the payoff feels abstract and are hard to quantify.
I call those purchases “accidental” because they are proportional to the deployed infrastructure and largely acting like a tax on top of everything. Only after a while does the scale of that line item become apparent. On the other hand intentionally purchasing a third party system is a very intentional act. It's very deliberate, requiring conversations and more scrutiny is placed for putting a credit card into a new service. Companies providing services understand this and are positioning themselves accordingly. Their play could be to make the case that that their third party solution is better, cheaper etc.
Open Source funding could be seen through both of these lenses. Today, in many ways, pledging money to Open Source is a very intentional decision. It requires discussions, persuasion and justification. The purpose and the pay-off is not entirely clear. Companies are not used to the idea of funding Open Source and they don't have a strong model to reason about these investments. Likewise many Open Source projects themselves also don't have a good way of dealing with money and might lack the governance to handle funds effectively. After all many of these projects are run by individuals and not formal organizations.
Companies are unlikely to fund something without understanding the return on investment. One better understood idea is to turn that one “random person in Nebraska” maintaining a critical dependency into a well-organized team with good op-sec. But for that to happen, funding needs to scale from pennies to dollars, making it really worthwhile.
My colleague Chad Whitacre floated an idea: what if platforms like AWS or GitHub started splitting the check? By adding a line-item to the invoices of their customers to support Open Source finding. It would turn giving to Open Source into more of a tax like thing. That might leverage the general willingness to just pile up on things to do good things. If we all pay 3% on top of our Cloud or SaaS bills to give to Open Source this would quickly add up.
While I’m intrigued by the idea, I also have my doubts that this would work. It goes back to the problem mentioned earlier that some Open Source projects just have no governance or are not even ready to receive money. How much value you put on a dependency is also very individual. Just because an NPM package has a lot of downloads does not necessarily mean it's critical to the mission of the company. rrweb is a good example for us at Sentry. It sits at the core of our session replay product but since we we vendor a pinned fork, you would not see rrweb in your dependency tree. We also value that package more than some algorithm would be able to determine about how important that package is to us.
So the challenge with the tax — as appealing as it is — is that it might make the “purchase decision” of funding Open Source easier, but it would probably make the distribution problem much worse. Deliberate, intentional funding is key. At least for the moment.
Still, it’s worth considering. The “what if” is a powerful idea. Using a restaurant analogy, the “open-source tax” is like the mandatory VAT or health surcharge on your bill: no choice is involved. Another model could be more like the tip suggestions on a receipt offering a choice but also guidance on what’s appropriate to contribute.
The current model we propose with our upcoming Open Source Pledge is to suggest like a tip what you should give in relation to your developer work force. Take the average number of full time engineers you have over a year, multiply this by 2000. That is the amount in US dollars you should give to your Open Source dependencies.
That sounds like a significant amount! But let's put this in relation for a typical developer you employ: that's less than a fifth of what you would pay for FICA (Federal Insurance Contributions Act in the US) in the US. That's less than the communal tax you would pay in Austria. I'm sure you can think of similar payroll taxes in your country.
I believe that after step one of recognizing there is a funding problem follows an obvious step two: having a baseline funding amount that stands in relation to your business (you own or are a part of) of what the amount should be. Using the size of the development team as a metric offers an objective and quantifiable starting point. The beauty in my mind of the developer count in particular is that it's somewhat independently observable from both the outside and inside [1]. The latter is important! It creates a baseline for people within a company to start a conversation about Open Source funding.
If you have feedback on this, particular the pledge I invite you mail me or to leave a comment on the Pledge's issue tracker.
[1]There is an analogy to historical taxation here. For instance the Window Tax was taxation based on the number of Windows in a building. That made enforcement easy because you could count them from street level. The downside of taht was obviously the unintended consequences that this caused. Something to always keep in mind!Ruqola 2.3.0
Ruqola 2.3.0 is a feature and bugfix release of the Rocket.chat app.
New features:
- Implement Rocket.Chat Marketplace.
- Allow to clean room history.
- Allow to check new version.
- Implement moderation (administrator mode).
- Add welcome page.
- Implement pending users info (administrator mode).
- Use cmark-rc (https://github.com/dfaure/cmark-rc) for markdown support.
- Delete oldest files from some cache directories (file-upload and media) so it doesn't grow forever.
Fixed bugs:
- Clean market application model after 30 minutes (reduce memory footprint).
- Fix show discussion name in completion.
- Fix duplicated messages in search message dialog.
- Add delegate in search rooms in team dialog.
URL: https://download.kde.org/stable/ruqola/
Source: ruqola-2.3.0.tar.xz
SHA256: 051186793b7edc4fb2151c80ceab3bcfd65acb27d38305568fda54553660fdd0
Signed by: E0A3EB202F8E57528E13E72FD7574483BB57B18D Jonathan Riddell jr@jriddell.org
https://jriddell.org/jriddell.pgp
Python Engineering at Microsoft: Announcing the new Python Data Science Extension Pack for VS Code
We’re thrilled to announce the launch of the new Python Data Science Extension Pack for Visual Studio Code! This powerful pack brings together some of the most popular and essential VS Code extensions, making it your one-stop shop for all things data science in Python.
What’s Inside?Our extension pack is designed to streamline your data science journey from start to finish. Whether you’re preparing data, conducting analysis, visualizing results, or building and training machine learning models, we’ve got you covered.
This Data Science extension pack currently includes four extensions:
- Python – Provides rich support for the Python language such as IntelliSense, debugging, formatting, linting, code navigation, refactoring, variable explorer, test explorer, and more.
- Jupyter – Used to create and edit Jupyter Notebooks, add and run code/markdown cells, render plots, create presentation-friendly versions of your notebook by exporting to HTML or PDF and more.
- GitHub Copilot – An AI pair programmer tool that helps you write code faster and smarter.
- Data Wrangler – A code-centric data viewing and cleaning tool to explore, visualize, and clean tabular data.
Dive into the world of data science by installing the Python Data Science Extension Pack for VS Code from the VS Code extension marketplace.
We encourage you to provide feedback and file issues. Additionally, if there are other VS Code extensions that you feel are essential to the data science workflow, please let us know by creating a ticket in our GitHub repo.
The post Announcing the new Python Data Science Extension Pack for VS Code appeared first on Python.
Liip: blökkli Starterkit released
Meet the blökkli starterkit for Drupal.
Spin-up a preconfigured Decoupled Drupal setup with Nuxt 3, GraphQL and blökkli to get started developing within seconds.
Enjoy the powerful and elegant editing experience offered by blokk.li, a fully interactive in-page editor based on the well-known Drupal Paragraphs module.
-
Out of the box support experience with local setup using Lando or DDEV
-
Drupal Backend Setup with GraphQL, Paragraphs and Paragraphs blokk.li module enabled
-
+40 Vue Components and Composables ready to build paragraph based Drupal websites
-
Basic Frontend setup with Nuxt 3 and GraphQL Middleware included
-
Multilanguage support with language negotation and translation support
-
Key-based Texts managed in Drupal combined with translation extraction in the frontend
-
SVG Icon Sprite generation with Drupal Media Library integration
-
rokka.io Image CDN integration and Drupal media library integration
-
Reverse proxy configuration generator included
We are looking forward to getting your feedback in the issue queue and on slack.
If you happen to be in Barcelona for DrupalCon, find us at the following dates:
-
Session: Large-scale content creation with Drupal — Delights, Pitfalls and support structures to help editors by Jonathan Noack (Jonock), Thomas Nagy (Thomnagy)
Wednesday, September 25, 2024 - 11:30 to 12:15
Room 1 (133-134) -
BoF: blökkli - Demo, Q&A for the Interactive page building experience with Nuxt
Thursday, September 26, 2024 - 16:30 to 17:15
Room BoF 1 (118)
Lullabot: Untangling Your Drupal Migration: Lessons from the State of Iowa
Migrating your content to a new CMS can feel daunting. You have years and years of content to sort through and move over, and you have no idea what obstacles might be hiding in the weeds. In the back of your mind, the question looms: “Do we really need all of this content?”
You don’t want to waste time. But you also don’t want to miss anything important.
Dirk Eddelbuettel: Rblpapi 0.3.15: Updated and New BLP Library
Version 0.3.15 of the Rblpapi package arrived on CRAN today. Rblpapi provides a direct interface between R and the Bloomberg Terminal via the C++ API provided by Bloomberg (but note that a valid Bloomberg license and installation is required).
This is the fifteenth release since the package first appeared on CRAN in 2016. This release updates to the current version 3.24.6 of the Bloomberg API, and rounds out a few corners in the packaging from continuous integration to the vignette.
The detailed list of changes follow below.
Changes in Rblpapi version 0.3.15 (2024-09-18)A warning is now issued if more than 1000 results are returned (John in #377 addressing #375)
A few typos in the rblpapi-intro vignette were corrected (Michael Streatfield in #378)
The continuous integration setup was updated (Dirk in #388)
Deprecation warnings over char* where C++ class Name is now preferred have been addressed (Dirk in #391)
Several package files have been updated (Dirk in #392)
The request formation has been corrected, and an example was added (Dirk and John in #394 and #396)
The Bloomberg API has been upgraded to release 3.24.6.1 (Dirk in #397)
Courtesy of my CRANberries, there is also a diffstat report for the this release. As always, more detailed information is at the Rblpapi repo or the Rblpapi page. Questions, comments etc should go to the issue tickets system at the GitHub repo.
If you like this or other open-source work I do, you can sponsor me at GitHub.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. Please report excessive re-aggregation in third-party for-profit settings.
Wim Leers: XB week 17: drag and drop party
We matched last week’s record: again 26 MRs merged! :D
Experience Builder (XB) already had a hierarchy view for a while. Lauri worked with the Acquia UX team to change that to match the more common “layers” pattern (used in Photoshop and Figma). Harumi “hooroomoo” Jang made that a reality:
The new “layers” panel, which also allows moving components.Issue #3458503, image by Harumi.
Ben “bnjmnm” Mullins and I (mostly Ben!) collaborated on integrating Media Library! This required expanding some of the lower-level XB infrastructure but most importantly, it means we proved Drupal core’s most complex field widget 1 can work, which is an important milestone:
Using an image from the Media Library. Note how the alt updates, but the image won’t load — more about that later in this post :)Issue #3454173, image by me.
During the product research phase, Lauri identified that it’s important for Content Creators’ productivity to not have to craft the same combinations of components over and over again. Lauri and the Acquia UX team have labeled such combinations “sections” — similar to Layout Builder’s sections. Creating new ones is out-of-scope for 0.1.0, but conveying what that UX would feel like is in scope. So, Jesse “jessebaker” Baker and Bálint “balintbrews” Kléri worked on a client-only implementation that hardcodes a single section (again: for now):
Using an image from the Media Library. Note how the alt updates, but the image won’t load — more about that later in this post :)Issue #3463300, image by me.
It takes no designer or expert user to observe that in the above images, the drag-and-drop UX and visualization can be improved. The Figma designs do not have an answer for this. But … we have Bálint! :D He thought, tinkered, experimented and gave the Drupal ecosystem this delightful UX:
A blue line now precedes the ghost while dragging, which conveys both the current position and the target position upon dropping.Issue #3470973, image by Bálint.
… which subsequently enabled him together with danielveza and Jesse to also highlight the slot that a component is about to be placed in:
The precise destination of a component is has a thick blue line, the containing slot gets a thin outline.Issue #3469822, image by Bálint.
If that isn’t an epic leap forward on the front end, then I don’t know what is! :D On so many fronts, dragging and dropping components became not only more usable, but also enjoyable.
It doesn’t end there, though:
- Utkarsh “utkarsh_33” updated the styling of text inputs, boolean toggle, etc to match the designs, by mapping more form elements to XB’s React components using the semi-coupled theme engine that Ben introduced in week 10
- Utkarsh, fazilitehreem and Jesse made deleting component instances more intuitive: you can delete the selected one using the keyboard now
- fazilitehreem, Utkarsh and Jesse added right-click support to the selected component
- Jesse fixed a crucial bug that prevented slots in freshly dropped components from working
Missed a prior week? See all posts tagged Experience Builder.
Goal: make it possible to follow high-level progress by reading ~5 minutes/week. I hope this empowers more people to contribute when their unique skills can best be put to use!
For more detail, join the #experience-builder Slack channel. Check out the pinned items at the top!
Back endComparatively, the back end progress this week was very non-visual… with one exception: Ted “tedbow” Bowman and I fixed the visually broken “image” components — this was caused by the buggy PoC code I wrote 14 weeks ago — finally this rose to the top of the priorities!
Images now render as expected in Experience Builder. Compare and contrast with the Media Library image above :)Issue #3469436, image by me.
Feliksas “f.mazeikis” Mazeikis and I discovered a critical bug in the auto-generated Component config entities for Single-Directory Components (SDCs) meeting the criteria: the field type and widget for optional props were missing. How could this happen? Because we’ve been racing ahead to make functionality exist, without the foundations being sufficiently thoroughly checked: the Component config entity’s schema is littered with @todos for adding more validation constraints. One of those would’ve prevented this problem … so we fixed not only the problem at hand, but also ensured that it could never reoccur, by introducing a KeyForEverySdcProp validation constraint first, and then fixing the auto-generation logic.
Dave “longwave” Long, Lee “larowlan” Rowlands and Deepak “deepakkm” Mishra updated XB to declare a runtime rather than development dependency on justinrainbow/json-schema — this is what the SDC subsystem uses to validate that the provided props values are considered acceptable by an SDC, and that’s why XB uses it to validate an XB field is valid (i.e. every SDC in the component tree must be renderable and hence trigger no exceptions for provided SDC props values). So that should’ve been marked as an explicit dependency months ago, but we didn’t spot that. Easy enough!
However … Lee pointed out that this is actually unacceptable for Drupal sites that use JSON:API in production, because it causes automatic validation for every JSON:API response against the JSON:API spec if assertions are enabled. That results in a significant performance regression. That being said, having assertions enabled is also a violation of Drupal best practices (and PHP best practices). Still, Drupal should help users even when they ignore/are unaware of best practices, so the XB module warns on the status report when best practices are violated. A core issue was created to improve this upstream: #3472008.
What a week! :D
Week 17 was September 2–8, 2024.
-
For now, that Media Library dialog looks rather stark, because it is, well … using the Stark theme. We plan to load the Claro/Gin styles, but to ensure style isolation, that requires some non-trivial <iframe> shenanigans in #3471978 to avoid loading that CSS/JS in the context of the XB React app. ↩︎
- The new "layers" panel, which also allows moving components.
- Using an image from the Media Library.
- The sole "section" available right now: one that contains two predefined hero components.
- A blue line now precedes the ghost while dragging, which conveys both the current position and the target position upon dropping
- The precise destination of a component is has a thick blue line, the containing slot gets a thin outline.
- Images now render as expected in Experience Builder.
Real Python: Python 3.13 Preview: Free Threading and a JIT Compiler
Although the final release of Python 3.13 is scheduled for October 2024, you can download and install a preview version today to explore the new features. Notably, the introduction of free threading and a just-in-time (JIT) compiler are among the most exciting enhancements, both designed to give your code a significant performance boost.
In this tutorial, you’ll:
- Compile a custom Python build from source using Docker
- Disable the Global Interpreter Lock (GIL) in Python
- Enable the Just-In-Time (JIT) compiler for Python code
- Determine the availability of new features at runtime
- Assess the performance improvements in Python 3.13
- Make a C extension module targeting Python’s new ABI
Check out what’s new in the Python changelog for a complete list of the upcoming features and improvements. This document contains a quick summary of the release highlights as well as a detailed breakdown of the planned changes.
To download the sample code and other resources accompanying this tutorial, click the link below:
Get Your Code: Click here to download the free sample code that shows you how to work with the experimental free threading and JIT compiler in Python 3.13.
Take the Quiz: Test your knowledge with our interactive “Python 3.13: Free-Threading and a JIT Compiler” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Python 3.13: Free-Threading and a JIT CompilerIn this quiz, you'll test your understanding of the new features in Python 3.13. You'll revisit how to compile a custom Python build, disable the Global Interpreter Lock (GIL), enable the Just-In-Time (JIT) compiler, and more.
Free Threading and JIT in Python 3.13: What’s the Fuss?Before going any further, it’s important to note that the majority of improvements in Python 3.13 will remain invisible to the average Joe. This includes free threading (PEP 703) and the JIT compiler (PEP 744), which have already sparked a lot of excitement in the Python community.
Keep in mind that they’re both experimental features aimed at power users, who must take extra steps to enable them at Python’s build time. None of the official channels will distribute Python 3.13 with these additional features enabled by default. This is to maintain backward compatibility and to prevent potential glitches, which should be expected.
Note: Don’t try to use Python 3.13 with the experimental features in a production environment! It may cause unexpected problems, and the Python Steering Council reserves the right to remove these features entirely from future Python releases if they prove to be unstable. Treat them as an experiment to gather real-world data.
In this section, you’ll get a birds-eye view of these experimental features so you can set the right expectations. You’ll find detailed explanations on how to enable them and evaluate their impact on Python’s performance in the remainder of this tutorial.
Free Threading Makes the GIL OptionalFree threading is an attempt to remove the Global Interpreter Lock (GIL) from CPython, which has traditionally been the biggest obstacle to achieving thread-based parallelism when performing CPU-bound tasks. In short, the GIL allows only one thread of execution to run at any given time, regardless of how many cores your CPU is equipped with. This prevents Python from leveraging the available computing power effectively.
There have been many attempts in the past to bypass the GIL in Python, each with varying levels of success. You can read about these attempts in the tutorial on bypassing the GIL. While previous attempts were made by third parties, this is the first time that the core Python development team has taken similar steps with the permission of the steering council, even if some reservations remain.
Note: Python 3.12 approached the GIL obstacle from a different angle by allowing the individual subinterpreters to have their independent GILs. This can improve Python’s concurrency by letting you run different tasks in parallel, but without the ability to share data cheaply between them due to isolated memory spaces. In Python 3.13, you’ll be able to combine subinterpreters with free threading.
The removal of the GIL would have significant implications for the Python interpreter itself and especially for the large body of third-party code that relies on it. Because free threading essentially breaks backward compatibility, the long-term plan for its implementation is as follows:
- Experimental: Free threading is introduced as an experimental feature and isn’t a part of the official Python distribution. You must make a custom Python build to disable the GIL.
- Enabled: The GIL becomes optional in the official Python distribution but remains enabled by default to allow for a transition period.
- Disabled: The GIL is disabled by default, but you can still enable it if needed for compatibility reasons.
There are no plans to completely remove the GIL from the official Python distribution at the moment, as that would cause significant disruption to legacy codebases and libraries. Note that the steps outlined above are just a proposal subject to change. Also, free threading may not pan out at all if it makes single-threaded Python run slower than without it.
Until the GIL becomes optional in the official Python distribution, which may take a few more years, the Python development team will maintain two incompatible interpreter versions. The vanilla Python build won’t support free threading, while the special free-threaded flavor will have a slightly different Application Binary Interface (ABI) tagged with the letter “t” for threading.
This means that C extension modules built for stock Python won’t be compatible with the free-threaded version and the other way around. Maintainers of those external modules will be expected to distribute two packages with each release. If you’re one of them, and you use the Python/C API, then you’ll learn how to target CPython’s new ABI in the final section of this tutorial.
JIT Compiles Python to Machine CodeAs an interpreted language, Python takes your high-level code and executes it on the fly without the need for prior compilation. This has both pros and cons. Some of the biggest advantages of interpreted languages include better portability across different hardware architectures and a quick development time due to the lack of a compilation step. At the same time, interpretation is much slower than directly executing code native to your machine.
Note: To be more precise, Python interprets bytecode instructions, an intermediate binary representation between pure Python and machine code. The Python interpreter compiles your code to bytecode when you import a module and stores the resulting bytecode in the __pycache__ folder. This doesn’t inherently make your Python scripts run faster, but loading a pre-processed bytecode can indeed speed up their startup time.
Languages like C and C++ leverage Ahead-of-Time (AOT) compilation to translate your high-level code into machine code before you ship your software. The benefit of this is faster execution since the code is already in the computer’s mother tongue. While you no longer need a separate program to interpret the code, you must compile it separately for all target platforms that you want supported. You should also handle platform-specific differences yourself.
Read the full article at https://realpython.com/python313-free-threading-jit/ »[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
Tag1 Consulting: Migrating Your Data from D7 to D10:Migrating view modes and field groups
Today, we're building on our previous work with field widget settings. We will cover migrating view modes, a prerequisite for migrating field groups and field formatter settings. We’ll then walk through migrating field groups. Field formatter settings will be addressed in our next article.
Read more mauricio Wed, 09/18/2024 - 05:36Jamie McClelland: Gmail vs Tor vs Privacy
A legit email went to spam. Here are the redacted, relevant headers:
[redacted] X-Spam-Flag: YES X-Spam-Level: ****** X-Spam-Status: Yes, score=6.3 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, [redacted] * 1.0 RCVD_IN_XBL RBL: Received via a relay in Spamhaus XBL * [185.220.101.64 listed in xxxxxxxxxxxxx.zen.dq.spamhaus.net] * 3.0 RCVD_IN_SBL_CSS Received via a relay in Spamhaus SBL-CSS * 2.5 RCVD_IN_AUTHBL Received via a relay in Spamhaus AuthBL * 0.0 RCVD_IN_PBL Received via a relay in Spamhaus PBL [redacted] [very first received line follows...] Received: from [10.137.0.13] ([185.220.101.64]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-378956d2ee6sm12487760f8f.83.2024.09.11.15.05.52 for <xxxxx@mayfirst.org> (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 11 Sep 2024 15:05:53 -0700 (PDT)At first I though a Gmail IP address was listed in spamhaus - I even opened a ticket. But then I realized it wasn’t the last hop that Spamaus is complaining about, it’s the first hop, specifically the ip 185.220.101.64 which appears to be a Tor exit node.
The sender is using their own client to relay email directly to Gmail. Like any sane person, they don’t trust Gmail to protect their privacy, so they are sending via Tor. But WTF, Gmail is not stripping the sending IP address from the header.
I’m a big fan of harm reduction and have always considered using your own client to relay email with Gmail as a nice way to avoid some of the surveillance tax Google imposes.
However, it seems that if you pursue this option you have two unpleasant choices:
- Embed your IP address in every email message or
- Use Tor and have your email messages go to spam
I supposed you could also use a VPN, but I doubt the IP reputation of most VPN exit nodes are going to be more reliable than Tor.
Drupal Starshot blog: Drupal CMS Update for The Mid September 2024
We are in the middle of September and that means it’s time for our regular update on what’s going on with the Drupal CMS. Let’s check out what’s new!
Documentation
The Drupal Association is on a mission to bring world-class documentation and maintenance software for Drupal CMS launch and beyond. In order to achieve that, we teamed up with Drupalize.me. Our common goal is to make sure that by the time when Drupal CMS hits the market we have an easy to follow user guide suitable for our target audience. Also we prepared an announcement that will be revealed at DrupalCon Barcelona. Stay tuned for the details!
Contact Form
We are happy to announce that we found a track lead for the Contact form! J. Hogue from Oomph joined the team very recently but has already managed to show progress: he and his team are getting busy with the research and MVP mapping. It’s great to have you with us!
Blog
As per the most recent update from Laurens Van Damme and his team, The MVP version has been set up and now the team is busy with the research on how to align with Drupal CMS standards.
Events
While Martin Anderson-Clutz and his team are considering expanding functionality with the options that will not be applied by default, they are working on a different calendar solution that would have more community support, as well as UX improvement for the date widget. We can’t wait to see the result of their work!
Data Privacy / Compliance
Jürgen Haas tells us that information research and framing the scope of the track has been completed and the team agreed on the documentation. Therefore, the following 3 action items has been set as immediate next priorities:
-
continue documentation
-
break down existing feature list into deliverables/recipes and prioritise them
-
define components for the "Compliance Audit" module as an additional deliverable
Trial experience for Starshot
Some exciting news is coming from Matt Glaman: the trial now displays an interactive installer of Drupal CMS. Meanwhile, the work on styling so the trial would look like the Drupal CMS installer while it is being set up, is full steam on.
Dashboard
The team, lead by Christian López Espínola and Matthew Tift has got the wireframes they can rely on hence now it’s time to get things rolling! They are busy looking deeper into the Gin theme, in particular - config actions for adding blocks to the dashboards from other recipes. There is a decision to be made on whether the right sidebar should consist of shortcuts or individual blocks. At the same time, planning for the upcoming activities is in progress and we are waiting patiently to see more details on what’s ahead.
SEO
Great news from Jim Birch and John Doyle with the SEO track team: Basic and Advanced SEO Recipes have been committed to the repository. Next priority is to continue the iteration process on the recipes, documentation, and guidelines for other tracks.
Content Publishing Workflows
We are most excited to announce that we’ve got one more valuable addition to the team - Mohammed Razem from Vardot is joining the Drupal CMS crew as a track lead of the Content Publishing Workflows track. Welcome on board!
Advanced Search
The 1xINTERNET team has been busy finalising the first version of the concept. The next target for them is to get insights from the survey asking Drupalers what they prefer to use in order to confirm earlier findings from the specification.
Media Management
Tony Barker informs that the Media Track team is researching the features of content management systems identified in the Strategy document as well as working through the information and ideas from the earlier released questionnaire. They keep experimenting with modules and configuration to make necessary choices, with the focus on features that can make it into early recipes over the coming weeks.
Accessibility Tools
From Gareth Alexander we learn the following: as the discovery process and gathering insight on common practices has been finalised, the team has published a survey and is now busy reviewing the results. As review of the current module availability has been completed the list has been simmered down to the ones now being reviewed for feasibility.
This will lead to a proposal for the features and recipes for Accessibility Tools to be considered for inclusion in early versions of Drupal CMS.
Proposal creation is underway and the next steps are being generated.
Analytics
Dharizza Espinach meanwhile shares that the team has finished the market research, and is currently wrapping up the work on a comparison with other tools. The selected tools are to be included in the recipes. Another objective the track team is busy with is preparing the list of recommendations for features that should be included later in the project. The proposal document is underway and iterating over a first version of the basic recipe will be the next step.
AI
Jamie Abrahams is working on something very special that will be released during DrupalCon Barcelona. So I will keep the intrigue and will allow you to discover the details for yourself in just 1 week!
New Track Announcement!
As we make progress with the already defined deliverables, we keep discovering the missing parts of the puzzle. In order to close those gaps, we are excited to announce 2 new tracks we not only set up but managed to get staffed as well:
-
NavigationMatthew Oliveira, Pablo López Escobés from Lullabot. >
-
Gin admin theme track - Known by many, a long time maintainer of the Gin, Sascha Eggenberger became track lead for this milestone.
Our heartfelt welcome to all of the newly acquired Drupal CMS track leads - we are excited to have you and looking forward to all the expertise you are bringing along!
I truly hope you find the news outlined above as exciting as we do and look forward to sharing even more at DrupalCon Barcelona. So if you somehow didn’t get your ticket yet - better hurry up!
Django Weblog: Last call for DjangoCon US 2024 tickets!
DjangoCon US starts next week in Durham, NC on September 22nd!
If you aren't able to join in person, please consider purchasing an online ticket: https://ti.to/defna/djangocon-us-2024
The conference is full of a variety of talks with excellent keynote speakers! It's shaping up to be an event you'll want to experience live.
If you'd like to learn more about DjangoCon US visit them at their website or reach out to them at hello@djangocon.us.
Qt for MCUs 2.8.1 LTS released
Qt for MCUs 2.8.1 LTS (Long-Term Support) has been released and is available for download. This first patch release provides bug fixes and other improvements while maintaining source compatibility with Qt for MCUs 2.8. It does not add any new functionality.
LN Webworks: How To Render A Custom Form In Drupal Block
Blocks are basically content containers that are showcased in distinct sections of a website including social sharing buttons, “Who’s online” sections, recently viewed content, and social media feeds. Custom Blocks that are available through GUI operate similarly to node entities. In this guide, you will get a concise overview of their implementations, but primarily focusing on custom blocks developed through the creation of a custom module in Drupal development services.
Step-by-Step Guide To Displaying Custom Forms In Drupal Blocks Step 1: Create a Custom ModuleCreate a directory first by using the following command: =>
mkdir modules/custom/mymodule
Create the Necessary Files
Within the modules/custom/mymodule directory, create the following files:
mymodule.info.yml
src/Plugin/block/CistomBlock.php
src/Form/MyCustomForm.php
Ensure that these files are properly structured to fit the requirements of your module.
1. mymodule.info.yml
Oliver Davies' daily list: De-jargoning Drupal
This week, I learned there is a Drupalisms Working Group - a group focused on de-jargoning Drupal and making it easier for newcomers to Drupal by removing some of the Drupal-specific language.
From the introductory blog post:
If you’re familiar with Drupal, you will have learned its language. You will be familiar with words like Views, Blocks and Paragraphs, and you will appreciate their respective features and functions. But for those new to Drupal, getting to grips with what words mean can mean a steep learning curve.
Drupalisms is something I've discussed on a few episodes of Beyond Blocks, including the most recent episode and the seonc with Eirik Morland.
I didn't realise there were BoF sessions about this at DrupalCon Lille last year, so I'm hoping there will be more next week in Barcelona.
Anything that helps Drupal easier to use and adopt is a good thing.
Spyder IDE: Scientific IDE UX Birds of a Feather session at SciPy 2024
My First Akademy Adventure
This year was my first Akademy, and I was thrilled to be able to attend in person. Even better, some veterans said it was the best Akademy so far. It was great to see some people I had met in April and to meet new people. I arrived on Friday, 6th Sept and left the following Friday. I very much enjoyed staying in the lovely town of Würzburg and doing a day tour of Rothenberg. Now that I've caught up on sleep (the jet lag, it is real), it's time to write about it.
As described in the Akademy 2024 report, the focus this year was resetting priorities, refocusing goals and reorganizing projects. Since I had recently become a more active contributor to KDE, I was keen to learn about the direction things will take over the next year. It was also exciting to see the new design direction in Union and Plasma Next!
A Personal NoteSpeaking of goals, a personal one I've striven toward in my career is to contribute to something that improves the world, even if indirectly. It's not something I've always been able to do. It feels good to be able to work with a project that is open source, and is working to make the computing world more sustainable.
I'd also like to recognize all the wonderful, welcoming folks that make Akademy such a great conference. I've been to a few other tech conferences and events, with varying atmospheres and attitudes. I can say that people at Akademy are so helpful, and so nice - it made being among a lot of new faces in a foreign country a truly great experience.
The ConferenceThe keynote had powerful information about the impacts of improper tech disposal and what we can do to improve the situation. This highlighted the importance of the KDE Eco project, which aims to help to reduce e-waste and make our projects more sustainable. Their new Opt Green initiative is going to take concrete steps toward this.
Some of the talks I attended:
- KDE Goals - one talk about the last 2 years of goals and another revealing the new goals.
- "Adapt or Die" - how containerized packaging affects KDE projects.
- Union and styling in KDE's future.
- Banana OS KDE Linux - why it's being developed and some technical planning.
- Getting Them Early: Teaching Pupils About The Environmental Benefits Of FOSS
This strategy has been powerful for other projects (like Microsoft Windows,
Google Chromebooks, Java), so I'm glad to see it for KDE.
- Why and how to use KDE frameworks in non-KDE apps
- KDE Apps Initiative
- Cutting Gordian's "End-User Focus" vs. "Privacy" Knot - collecting useful user data while respecting privacy and security.
- Plasma Next - Visual Design Evolution for Plasma
- The Road to KDE Neon Core
Some of the BoF sessions I attended:
- Decentralizing KUserFeedback
- Streamlined Application Development Experience
- Organizing the Plasma team, Plasma goals
- Plasma "Next" initiative
- Union: The future of styling in KDE
- KWallet modern replacement
- Video tutorial for BoF best practice (Kieryn roped me into this one)
- Security Team BoF Notes
Thanks to everyone who made this year's Akademy such a wonderful experience. If anyone out there is thinking of attending next year, and can make it, I really recommend it. I'm hoping to be at Akademy 2025!