In this stream, I worked on a personal AI workflow that I'm building using LangGraph. I discussed human-in-the-loop and how to bring a person into the workflow process.| Matt Layman
Picture this: it’s late and I’m deep in a coding session, wrestling with a chatbot that’s starting to feel more like a living thing than a few lines of Python. Today’s mission? Supercharge the chatbot’s ability to remember and verify user details like names and birthdays using LangGraph. Let’s unpack the journey, from shell commands to Git commits, and see how this bot got a memory upgrade. For clarity, this is my adventure running through the LangGraph docs.| Matt Layman
Glenn will start by providing an overview of Generative AI, a groundbreaking technology that enables machines to produce human-like text, images, and even code. This innovation is transforming various industries by automating tasks, enhancing creativity, and improving efficiency.| Matt Layman
In this episode, I worked on the hard mode of my pong clone game. We tried to improve the CPU AI without much success, then found some simple alternatives to make a fun hard mode.| Matt Layman
In this episode, I worked on my pong clone some more. I made the game work in full screen mode (dealing with scaling) and started to add a menu system.| Matt Layman
In this episode, I played more with Love2d. I tried to use Grok to add more features to my pong clone, then played with the particle system in Love2d. Note: my streaming software crashed after the first 12 minutes of streaming, so the start on this recording is a somewhat abrupt.| Matt Layman
In this episode, I worked on some Love2D code and explored how to use AI tools within my Neovim configuration. Ultimately, I found that working with Grok directly proved to be more useful for my scenario than working with the xAI model through the avante plugin.| Matt Layman
In this episode, I declared to the stream that I’m done working on JourneyInbox as a SaaS product. I didn’t see any meaningful market adoption, so I’ve decided to pivot the project to serve only my personal needs. I used the stream to do a retrospective on the project and then convert the core logic to use Go to simplify when I need to run on my server.| Matt Layman
Unlock the PySpark for Big Data. This is a beginner-friendly course designed to introduce you to Apache Spark, a fast and scalable distributed computing framework. This class covers the fundamentals of PySpark, including:| Matt Layman
In this episode, I updated my new onboarding form on the School Desk app. This form is vital for the first experience of new users, so I spent a lot of time making sure it will do what is needed.| Matt Layman
If you want to know what C# and .net Core is as of 2025 and how open source it really is, or not. What it gets right, what it gets wrong, and an objective comparison to Java, Go, C++, etc. we will give you a quick overview. C# and .net core offer many things that prior versions of .NET did not offer.| Matt Layman
In this episode, I did checking on the email reputation of my SaaS apps because I got feedback from a customer that my emails were going to spam. Along the way, we learned about DMARC as a capability to track and report on email compliance. After making some DNS changes to enable DMARC, I worked on some onboarding changes for my homeschool application. We are going to simplify the onboarding flow so that users have a faster path to success with the app.| Matt Layman
In this episode, I finished up the sign in simplification feature for the homeschool app. I planned to do deploy it quickly and move onto the next thing, but we hit a comedy errors and challenges while trying to get Docker Desktop working again on my dev machine. On the stream, we also began to play with Ollama in preparation of doing some agentic AI framework research.| Matt Layman
In this talk, we explore the Ray library and how it can be used to easily parallelize Python code. We cover the basics of using Ray Core, including installation, spinning up a local Ray cluster, and running remote actors and tasks.| Matt Layman
In this episode, I returned to the homeschooling application and started to improve the sign up and onboarding experience. We simplified signup to eliminate passwords and work via email. I talked through the design changes that I plan to make to the first time experience for new users.| Matt Layman
Experience the magic of game creation! We delved into the enchanting world of Lua, the language that powers the lightweight, open-source Löve game engine. Here's what you'll find:| Matt Layman
In this episode, I completed the simplified sign up process for my JourneyInbox app. I finished off the final features that add account verification and initial engagement features to make sign up and nice and functional experience.| Matt Layman
In this episode, we continued on the sign up workflow simplification. The focus of this stream was on adding the background task that will send the magic link email to allow sign in. This is the second half of the stream because my internet cut out.| Matt Layman
In this episode, we continued on the sign up workflow simplification. The focus of this stream was on adding the background task that will send the magic link email to allow sign in.| Matt Layman
In this episode, we began an update to the signup process to simplify things. I am replacing email and password with just email. Users will receive 'magic links' via their email client to sign in. To do this, we are using django-sesame.| Matt Layman
In this episode, when worked on the newly migrated JourneyInbox site and focused on the database. Since me moved from Postgres to SQLite, I needed to make sure that SQLite was ready for users. We examined common configuration to optimize the database and applied that config to JourneyInbox.| Matt Layman
In this episode, I worked to finish the cloud migration to DigitalOcean for JourneyInbox. We started the stream by bootstrapping Kamal on the server. I hit network issues so this stream is split into multiple parts and is of lower quality than normal.| Matt Layman
In this episode, the second portion of the stream worked on fixing up the Docker image so that we could get the DigitalOcean droplet functional. This is the second stream chunk because I was having network issues and the first stream cut out.| Matt Layman
In this episode, the third portion of the stream covers how I migrated my Heroku-backed Postgres database to SQLite. I finished the migration of my app from running on Heroku to running on DigitalOcean.| Matt Layman
In this episode, I continued a migration of my JourneyInbox app from Heroku to DigitalOcean. We configured the secrets using 1Password and created the droplet that will host the app.| Matt Layman
Dive into the dynamic duo of modern Python development – UV and Ruff!| Matt Layman
In this episode, I continued a migration of my JourneyInbox app from Heroku to DigitalOcean. I switched how environment configuration is pulled and converted cron jobs to use Huey as a background worker. Then I integrated Kamal configuration and walked through what the config means.| Matt Layman
In this episode, I began a migration of my JourneyInbox app from Heroku to DigitalOcean. The first step to this move, since I’m going to use Kamal, is to put the app into a Docker image. We got the whole app into the Docker image, then cleaned up local development and the CI system after making changes that broke those configurations.| Matt Layman
Kamal offers zero-downtime deploys, rolling restarts, asset bridging, remote builds, accessory service management, and everything else you need to deploy and manage your web app in production with Docker. Originally built for Rails apps, Kamal will work with any type of web app that can be containerized. We dig into Kamal, how it works, and how you could use it on your next project.| Matt Layman
In this episode, I dug into an issue with sign up. What I thought was going to be a minor issue to fix turned into a massively intense debugging session. We ended up going very deep with the django-allauth package to understand what was going on.| Matt Layman
In this episode, we worked on the cloud migration’s data strategy. I focused on how to convert a Postgres database into a SQLite database and planned out the process that I will follow to do the actual migration.| Matt Layman
In this episode, we continued on the cloud migration path. We need to build a Docker container with all the necessary static files. Some of these come from Go via Hugo for a content blog. Some comes from JavaScript via Tailwind for CSS. Some come from Python via Sphinx for documentation. All need to built into the same image. That’s what we covered on this stream.| Matt Layman
In this episode, we started down the path of migrating School Desk off of Heroku and onto Digital Ocean. Most of the effort was on tool changes and beginning to make a Dockerfile for deploying the app to the new setup.| Matt Layman
In this episode, we continued working with the Kamal deploy tool. Last time, we build a demo image. With this session, we created a Digital Ocean Droplet (i.e., VM) and deployed to that. Along the journey, we learned a lot about how Kamal operates.| Matt Layman
In this episode, we pulled out a new tool. We spent the session using Kamal, a tool to deploy web apps directly to servers. Kamal offers a complete tool set to get apps running on bare metal or cloud machines. We played with the tool to see how far we go to get an app deployed to a new server.| Matt Layman
How much can you build in Go with zero extra packages? What is possible using nothing more than Go’s standard library? In this talk, you’re going to find out!| Matt Layman
In this episode, we continued the break from JourneyInbox to look through more of the Go standard library. In this session, we talked about middleware, request context, and using databases.| Matt Layman
In this episode, we continued the break from JourneyInbox to look through more of the Go standard library. In this session, we explored JSON serialization, Go template support, and embedding of static files for easy access.| Matt Layman
Is your data locked up in portable document format (PDFs)? In this talk we’re going to explore methods to extract text and other data from PDFs using readily-available, open-source Python tools (such as pypdf), as well as techniques such as OCR (optical character recognition) and table extraction. We will also discuss the philosophy of text extraction as a whole.| Matt Layman
In this episode, we are taking a break from JourneyInbox and exploring what kind of Go app we can make by just using the Go standard library. This is the final continuation after an internet disconnection.| Matt Layman
Continuous Integration / Continuous Delivery (or Deployment), CI/CD, is a set of practices used by engineering organizations to improve the quality of software they deliver, how fast they deliver that software, and detect issues with that software before they affect end users. Unfortunately, the term can mean a lot of different ideas and approaches. So, in this talk we’re going to try to unravel some of those ideas to give you some ideas on how you too can deliver software better.| Matt Layman
In this episode, we chatted about managing dependencies and the cost of maintenance. Then we got into some feature work and began building a job that will send users an email as reminder to activate their account shortly before it expires.| Matt Layman
In this episode, we worked on a trial banner that could persist across all pages on the site. Because the banner needed data that was only available on the index page, we had to refactor the banner into an inclusion template tag to make the tag work consistently.| Matt Layman
In this episode, we hooked up the email confirmation signal to the prompt sending code so that new users can use JourneyInbox immediately. Then we focused on handling all the functionality related to the password reset feature. This meant customizing a bunch of django-allauth forms.| Matt Layman
n this session, we will explore how to use Python to enhance your AI projects with:| Matt Layman
In this episode, we first added the Django debug toolbar to aid future troubleshooting. Then, following some PR cleanup, I added django-denied as the authorization framework for the site. With those two packages integrated, I did some polishing work and began the effort to send prompts immediately following email verification.| Matt Layman
In this episode, we worked on some core pages to round out the JourneyInbox user interface. This led us to work updating UI layout, writing copy, and doing other fundamentals for making templated pages.| Matt Layman
In this episode, I started with cleaning up a few small items. After those warmups, we moved on to building an export feature that will allow users to take their journal entries if they want to leave the service.| Matt Layman
In this episode, I worked on the settings page for the user. This was a vital addition because it allows users to access the Stripe billing portal and close their account if they no longer wish to use JourneyInbox.| Matt Layman
In this episode, I built the import view that is needed to allow users to add their own journal entries to JourneyInbox. After completing that, I handled the pull requests from dependabot, then I worked on some quality of life to do better handling with beta user trials.| Matt Layman
Why would someone pick Django over Flask? That’s the question that I got on stream and here is my answer.| Matt Layman
In this episode, we added flash messages (after a rough start with some networking issues). Then I tracked down a thorny issue. We found that there is a non-breaking space with ’timesince’ that affects the encoding and what links Gmail adds to emails.| Matt Layman
NATS is an awesome open source technology to help connect code together over a network. Whether you’re build a distributed microservice architecture or connecting IoT devices, NATS provides the tools you need to do that easily. In this talk, you’ll learn about NATS via a presentation with plenty of live coding examples.| Matt Layman
In this episode, we attacked the issue list. JourneyInbox is live and serving user and now it’s time to start polishing and building the full set of features. There are so many easy targets to fix that we focused on a few clear improvements to user experience and the user interface.| Matt Layman
In this episode, we had a bunch of issues to resolve post-launch. I set the code that causes trials to expire, made updates to who receives prompt emails, and added some polish to the sign up process and interface to make it clear what will happen in the flow. After those modifications, we worked through a set of smaller changes like setting up Dependabot and adding a missing database index.| Matt Layman
In this episode, we deployed all our user setup and Stripe configuration change to the live site and tested the new flows end to end. Along the way, we found a bug in djstripe as well as some final bugs in the JourneyInbox configuration that prevented things from working. This is why you test!| Matt Layman
In this episode, we completed the final features needed to get the site open for others to sign up. This included some dynamic limiting of the number of people allowed to sign up. We also had to add the template styling for the login page.| Matt Layman
In this episode, we completed the Stripe integration. I added all the necessary test code, incorporated the webhook for handling account activation, and wrote the view that Stripe needed to redirect to on successful signup.| Matt Layman
In this talk, we’re going to start from nothing and build out our own tools for making art in Python, no AI needed! We’ll show how Python’s expressiveness allows us to describe graphics elegantly and use that to make some unique art programmatically.| Matt Layman
In this episode, we did work to get the Stripe checkout session going. We set up Stripe Product and Price objects to get the subscription plan ready and got the Stripe checkout session working mostly end-to-end| Matt Layman
In this episode, we continued on the Stripe integration. I worked on a new payments gateway interface to access the Stripe APIs needed for creating a check out session. We hit some bumps along the way because of djstripe’s new preference for putting the Stripe keys into the database exclusively.| Matt Layman
In this episode, I started with a plan to work on Stripe checkout, but realized that I needed to come up with a better plan and also improve the base template of the app. We ended up doing more design work than working with Stripe, but we ended the stream with a solid plan of what to do next.| Matt Layman
In this episode, we took care of the legal obligations of the site by setting up Terms of Service and a Privacy Policy page. Then we moved on to the next portion of signup, which is to configure Stripe to create customers and prepare, ultimately, to accept subscription payments.| Matt Layman
In this episode, we did some work on the sign up template. In the process, we added some base template styling, talked about branding, and considered the other elements that are required before we can turn on sign up for others. I also cover waffle as a feature flag tool.| Matt Layman
Tailwind CSS is a fantastic tool for making CSS easy to use on your webapps. On the video, I added Tailwind CSS to my Django app and showed how to use it and deploy it to Heroku (which required some extra configuration for JavaScript support).| Matt Layman
This video is all about adding the popular WhiteNoise package into my Django app to serve static files (e.g., CSS, JavaScript, and images) directly from the app. I walk through the process from start to finish and deploy it live to show how things work.| Matt Layman
In this episode, I worked through a couple of issues discovered after having the site be operational for real use. From there, we moved onto some fundamental technology and integrated WhiteNoise to handle static files for the application. After adding WhiteNoise, we hooked up Tailwind CSS.| Matt Layman
I was looking for new thing to do to improve my stream. This is mostly me goofing off.| Matt Layman
On a recent Building SaaS stream, we switched from using flake8, Black, isort, and bandit completely over to a single tool, Ruff. Watch an experienced Pythonista work through many of the options and do a full conversion to this powerful tool| Matt Layman
In this episode, we finished off the core portion of the application by parsing entries out of the messages sent back by SendGrid. We set up the Heroku Scheduler to start the daily flow of emails to get the system started. After completing that, I set up the project to use Ruff instead of the collection of tools used previously.| Matt Layman
In this episode, we switched to the inbound side and parsed an email to transform it into a journal entry. This caused us to look into the dateutil library and look at Python’s standard email module to use EmailMessage.| Matt Layman
In this episode, we cleaned up the email sending job. I had to make some changes based on some discoveries that I made while researching how to track responses and associate the journal entries back to the user. While doing this clean up, we added a new Prompt model to make the email sending job idempotent for each day.| Matt Layman
In this episode, we took advantage of having all the DNS configuration complete and tried to find the path to connect the outgoing prompt email to the incoming journal entry from a user. We did this with some old-school print debugging and logging on production to see exactly what data is provided to the receiver webhook.| Matt Layman
This presentation provides a straightforward overview of the HuggingFace Transformers and Diffusers libraries. Aimed at those without a deep understanding of AI or ML, we’ll focus on practical, hands-on applications. We conclude by setting up a Flask app that generates AI images, demonstrating how these tools can be used to create useful applications.| Matt Layman
In this episode, we returned to our DNS configuration from the previous stream and worked on testing email from end to end on the production site. On the stream, we spent a lot of time looking through SendGrid documentation, digging into layers of DNS, and troubleshooting the challenges that can arise when getting a site online.| Matt Layman
In this episode, we did the work to deploy the site to Heroku to make the site live. We configured the production site, fixed some missing settings, and connected to the relevant DNS configuration.| Matt Layman
In this episode, we worked on the inbound hook to receive email responses from SendGrid using the service’s Inbound Parse feature. We worked through the configuration and addressed the security concerns with opening up a public webhook.| Matt Layman
In this episode, we took another step closer to deploying the service online. The primary goal was to make sure that email sending works. I spent a lot of time explaining email configuration and showing exactly how to wire up SendGrid to Cloudflare to do Domain Authentication that permits email sending from the service’s domain (journeyinbox.com).| Matt Layman
In this episode, I added the deployment checklist and improved the security of the app. Then we moved to work to set up the database to use DATABASE_URL and prepare to use Postgres.| Matt Layman
Inspired by the Practical Business Python blog this Python Frederick meetup will cover how to automate document creation using Python-docx and Jinja.| Matt Layman
In this episode, I started working through the set of issues that I previously identified as necessary to complete before launching the service on Heroku. We add history tracking, soft deletion for the user model, and integration with SendGrid.| Matt Layman
In this episode, I finished the email sending job, then determined which issues will be needed before launching the product. Once we crafted the short list, I added an integration with Sentry.| Matt Layman
In this episode, we added the prompt email that will be the primary way of connecting to users for our email-based journaling service. I spent a fair amount of time thinking about copy writing to craft a compelling email that will resonate with users. Also, I made a bunch of silly mistakes and to keep correcting myself, so this is a good example of programming humility too.| Matt Layman
In this episode, I planned to do the work of sending email prompts for the journal to users. Along the path, we realized that the Account model was missing, so I stopped to build that out before we could proceed. By the end of the stream, we had a working background job that would send email and was 100% unit tested.| Matt Layman
In this episode, we got to work on the core modeling for the application. I started by adding some visualization tooling to see the models in the system, then got to modeling of the primary Entry model that will be used throughout the app. Along the way, we set up the Django admin and did some automated testing.| Matt Layman
One of the powerful things about Python is its ability to connect disparate tools into one common integrated development experience. In this talk, we’ll explore how to create and run a near real-time pipeline where we consume events from a Kafka topic and transform the data before landing them in the lake, using Upsolver through our Python SDK. In this way, we get exactly-once processing, strong ordering and automatic schema evolution out of the box thanks to the powerful Upsolver engine, b...| Matt Layman
In this episode, I continued on the signup flows that started in the previous stream. We configured the email backend and verified that the end to end signup flow worked. Then I set up the templates system and added the initial templates for the confirmation email the index view of the whole site. The stream ended with configuring test coverage and setting up CI with GitHub Actions and pre-commit.ci| Matt Layman
In this episode, we dug into the first portion of the journey SaaS. I acquired the domain name of journeyinbox.com for this service. That service is not live yet. We started at the beginning to set up users and sign up features.| Matt Layman
In this episode, I started a brand new SaaS project from scratch. This new SaaS, a journal service that will be at journeyinbox.com, will allow users to journal via email and be provided with past posts as a engaging prompt.| Matt Layman
In this episode, we covered more intro Python exercises from Exercism. Then I did some behind the scenes work to make some improvements to my stream content.| Matt Layman
In this episode, I went through a few quick exercises on Exercism in the Python track. Then I returned to the features I’m developing that displays course resources connected to tasks in my homeschool app.| Matt Layman
What is your burning web development question? That was the request for April’s event in 2023! We had a panel of web developers who were there to discuss web development questions and talk through the future of web development.| Matt Layman
In this episode, I did another Exercism problem in Python that focused on Python classes. After the exercise, I deployed my model change from last stream and discussed deployment strategy. Then we worked on some of the display pieces for the new feature. Once the feature was added, I discussed performance testing and showed some performance problems that the new feature created that I then fixed. We ended the stream with some Neovim configuration to correct some LSP formatting problems.| Matt Layman
This is a plain language guide to every built-in function in Python, paired with a simple example that shows each function in action.| Matt Layman
How can you make sure, automatically, that all the links to other internal pages within a site continue to work? In this article, we look at how to use Scrapy, a web scraping tool, and GitHub Actions, a Continuous Integration system, to accomplish this goal.| Matt Layman
You are rendering content with Python and want to show some Markdown, but you style your pages with Tailwind. With Tailwind's built-in reset, how can you style the tags of your rendered HTML that come from Markdown? This article shows how that can be done.| Matt Layman
luatest is a brand new test runner that is heavily inspired by pytest. It's got the speed you love about Lua with the DX you love from pytest.| Matt Layman
Code reviews improve the quality of software. But a code review can be done badly. In this post, we'll look at some tools to make your code reviews as effective as possible.| Matt Layman