<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aissa Laribi</title>
    <description>The latest articles on DEV Community by Aissa Laribi (@aissalaribi).</description>
    <link>https://dev.to/aissalaribi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F813730%2F2452ae88-b595-4cbf-861b-eb63bb42c34d.png</url>
      <title>DEV Community: Aissa Laribi</title>
      <link>https://dev.to/aissalaribi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aissalaribi"/>
    <language>en</language>
    <item>
      <title>StudyQuiz v1.2.0 — AI-Assisted Quiz Generation from PDFs</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Fri, 12 Jun 2026 10:48:27 +0000</pubDate>
      <link>https://dev.to/aissalaribi/studyquiz-v120-ai-assisted-quiz-generation-from-pdfs-2ph5</link>
      <guid>https://dev.to/aissalaribi/studyquiz-v120-ai-assisted-quiz-generation-from-pdfs-2ph5</guid>
      <description>&lt;p&gt;StudyQuiz has reached a significant milestone since the previous UX and reliability improvement release. &lt;br&gt;
This update focuses on a complete learning flow: users can now upload their study notes as a PDF, let AI generate a structured quiz, take the quiz, and receive the next review date for recall-based revision.&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;


  


&lt;p&gt;`&lt;/p&gt;

&lt;h3&gt;
  
  
  What's New
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Upload PDF study materials and generate structured quizzes automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dedicated URLs for quiz creation and quiz editing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Highlighted late reviews&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Visual homepage animation showcasing the user experience flow.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Improved
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Improved quiz creation UX by replacing the modal with a conditional form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved module creation UX by replacing the modal with a conditional form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Displayed next review timing as relative days instead of calendar dates.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fixed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fixed clearTimeout handling on the login page.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Removed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Removed modals for module and quiz creation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why This Release Matters
&lt;/h3&gt;

&lt;p&gt;Previously, users had to rely on external tools to transform study material into quiz content. With this release, StudyQuiz starts bringing that process directly into the app.&lt;/p&gt;

&lt;p&gt;The goal is not just to generate questions, but to connect AI-generated quizzes with spaced repetition, review scheduling, and active recall.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coming Next
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Profile definition.&lt;/li&gt;
&lt;li&gt;Account creation.&lt;/li&gt;
&lt;li&gt;User plans.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repo: &lt;a href="//github.com/aissa-laribi/studyquiz"&gt;github.com/aissa-laribi/studyquiz&lt;/a&gt;&lt;br&gt;
Live app: &lt;a href="https://www.studyquiz.co" rel="noopener noreferrer"&gt;https://www.studyquiz.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>🚀 StudyQuiz v1.1.0 — UX Enhancements, Integration Tests, and Reliability Improvements</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Wed, 03 Jun 2026 09:38:28 +0000</pubDate>
      <link>https://dev.to/aissalaribi/studyquiz-v110-ux-enhancements-integration-tests-and-reliability-improvements-2e9f</link>
      <guid>https://dev.to/aissalaribi/studyquiz-v110-ux-enhancements-integration-tests-and-reliability-improvements-2e9f</guid>
      <description>&lt;p&gt;StudyQuiz has moved forward since the first frontend MVP release. This update focuses less on adding major new features and more on making the app smoother to use, safer to change, and more reliable in production.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnya85bgp0fxcaqtjun0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnya85bgp0fxcaqtjun0.png" alt=" " width="799" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fmho7tm8h3r3nl6lj5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fmho7tm8h3r3nl6lj5o.png" alt=" " width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzmrvee4dn0d57nuvyan.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzmrvee4dn0d57nuvyan.png" alt=" " width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbxyzv3gf0d54yn1v52mr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbxyzv3gf0d54yn1v52mr.png" alt=" " width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s New
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Logout functionality&lt;/li&gt;
&lt;li&gt;Call-to-action section on the user dashboard&lt;/li&gt;
&lt;li&gt;Edit and delete functionality for questions and answers&lt;/li&gt;
&lt;li&gt;Guest Mode restrictions for editing and deleting questions and answers&lt;/li&gt;
&lt;li&gt;Integration tests for core backend workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Improved
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enhanced quiz user experience and feedback&lt;/li&gt;
&lt;li&gt;Improved quiz creation user experience&lt;/li&gt;
&lt;li&gt;Improved navigation across the application&lt;/li&gt;
&lt;li&gt;More reliable page reload behavior for protected routes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fixed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fixed 500 errors when reloading protected frontend pages&lt;/li&gt;
&lt;li&gt;Fixed production database session configuration issues&lt;/li&gt;
&lt;li&gt;Improved reliability around authentication-protected routes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why This Release Matters
&lt;/h3&gt;

&lt;p&gt;This release is mainly about stability and maintainability. I added integration tests and a GitHub Actions workflow so future changes are checked automatically before they silently break existing behaviour.&lt;/p&gt;

&lt;p&gt;StudyQuiz now feels closer to a maintainable product rather than just a working prototype.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coming Next
&lt;/h3&gt;

&lt;p&gt;The next major focus is slide upload and AI-assisted quiz generation, allowing users to generate structured quizzes more directly from their study materials.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="//github.com/aissa-laribi/studyquiz"&gt;github.com/aissa-laribi/studyquiz&lt;/a&gt;&lt;br&gt;
Live app: &lt;a href="https://www.studyquiz.co" rel="noopener noreferrer"&gt;https://www.studyquiz.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>learning</category>
      <category>showdev</category>
    </item>
    <item>
      <title>🚀 StudyQuiz v0.1.0 — FastAPI Quiz Engine with Spaced Repetition &amp; CLI Quiz Attempts</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Sat, 21 Jun 2025 23:11:21 +0000</pubDate>
      <link>https://dev.to/aissalaribi/studyquiz-v010-fastapi-quiz-engine-with-spaced-repetition-cli-quiz-attempts-3a8</link>
      <guid>https://dev.to/aissalaribi/studyquiz-v010-fastapi-quiz-engine-with-spaced-repetition-cli-quiz-attempts-3a8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A CLI-based learning tool with Fisher-Yates shuffling and SuperMemo 2 — built to help me (and maybe you) study smarter, not harder.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizy9c4rq3k7nsqfca3q7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizy9c4rq3k7nsqfca3q7.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Why I Built StudyQuiz
&lt;/h2&gt;

&lt;p&gt;Flashcards helped me memorize, but they didn't help with deep understanding.&lt;br&gt;&lt;br&gt;
I tried Anki, Quizlet, even Python scripts but nothing clicked.&lt;/p&gt;

&lt;p&gt;What I needed was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple-choice quizzes per &lt;strong&gt;chapter&lt;/strong&gt;, not per flashcard.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;learning algorithm&lt;/strong&gt; like SuperMemo 2 for spaced repetition.&lt;/li&gt;
&lt;li&gt;A fast, testable backend I could expand over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I built &lt;strong&gt;StudyQuiz&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  🔧 Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🐍 &lt;strong&gt;Python&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;FastAPI&lt;/strong&gt; + &lt;strong&gt;Async SQLAlchemy&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🐘 &lt;strong&gt;PostgreSQL&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🧪 &lt;strong&gt;Pytest&lt;/strong&gt; + test DB reset fixture&lt;/li&gt;
&lt;li&gt;💡 CLI-based quiz attempts for now (browser UI coming soon)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ✅ What’s in &lt;code&gt;v0.1.0&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Batch creation of:

&lt;ul&gt;
&lt;li&gt;Users&lt;/li&gt;
&lt;li&gt;Modules&lt;/li&gt;
&lt;li&gt;Quizzes&lt;/li&gt;
&lt;li&gt;Questions + Answers (nested JSON)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;✅ Fisher-Yates question shuffling&lt;/li&gt;
&lt;li&gt;✅ SuperMemo 2 spaced repetition&lt;/li&gt;
&lt;li&gt;✅ Quiz attempts that:

&lt;ul&gt;
&lt;li&gt;Record scores&lt;/li&gt;
&lt;li&gt;Schedule follow-ups&lt;/li&gt;
&lt;li&gt;Run in the &lt;strong&gt;terminal&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;✅ Fully tested core&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🖥️ How to Run
&lt;/h2&gt;

&lt;p&gt;1) Clone the repo &lt;br&gt;
2) Install dependencies&lt;br&gt;&lt;br&gt;
3) Run the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn app.main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Use Swagger UI:&lt;br&gt;&lt;br&gt;
Visit &lt;a href="http://127.0.0.1:8000/docs" rel="noopener noreferrer"&gt;http://127.0.0.1:8000/docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjml9ju7aniuhiajjrdht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjml9ju7aniuhiajjrdht.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎮 The quiz runs &lt;strong&gt;interactively in your terminal&lt;/strong&gt; after the POST is triggered.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 Next: A Guide for CLI + Leveraging ChatGPT for Batch Queries
&lt;/h2&gt;

&lt;p&gt;Before building the UI, I’ll publish a step-by-step guide on:&lt;/p&gt;

&lt;p&gt;🖥️ How to use StudyQuiz from the terminal&lt;/p&gt;

&lt;p&gt;🧠 How to leverage ChatGPT to:&lt;/p&gt;

&lt;p&gt;Generate quiz questions and answers in batch&lt;/p&gt;

&lt;p&gt;Summarize slides and course material&lt;/p&gt;

&lt;p&gt;Study smarter, faster, and with deeper understanding&lt;/p&gt;

&lt;p&gt;🎯 The goal: help early adopters get real value before the full frontend arrives&lt;/p&gt;




&lt;h2&gt;
  
  
  🔜 What’s Coming in v0.2.0
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Full browser UI with Svelte + TailwindCSS&lt;/li&gt;
&lt;li&gt;🧪 More test coverage (attempts, followups)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⭐ Try It + Feedback
&lt;/h2&gt;

&lt;p&gt;Here’s the repo:&lt;br&gt;&lt;br&gt;
🔗 &lt;a href="https://github.com/aissa-laribi/StudyQuiz/" rel="noopener noreferrer"&gt;github.com/aissa-laribi/studyquiz&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Star it ⭐ if you like it
&lt;/li&gt;
&lt;li&gt;Raise issues 💬 if something breaks
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💬 Let’s Connect
&lt;/h2&gt;

&lt;p&gt;Ask me questions here or find me on &lt;a href="https://github.com/aissa-laribi" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading 🙏&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>🚀 Introducing StudyQuiz: A Project Born from Struggle &amp; Curiosity</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Thu, 05 Jun 2025 21:12:35 +0000</pubDate>
      <link>https://dev.to/aissalaribi/introducing-studyquiz-a-project-born-from-struggle-curiosity-aj</link>
      <guid>https://dev.to/aissalaribi/introducing-studyquiz-a-project-born-from-struggle-curiosity-aj</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Why I Built StudyQuiz: A Spaced Repetition Tool for Real Learning
&lt;/h2&gt;

&lt;p&gt;This academic year, I wanted to improve how I learn, not just how much. I turned to the proven technique of &lt;strong&gt;spaced repetition&lt;/strong&gt; and started using &lt;strong&gt;Anki&lt;/strong&gt;. At first, it was exciting: I could organize flashcards by chapter and review them based on performance (Again, Hard, Good, Easy).&lt;/p&gt;

&lt;p&gt;But in the long run, it didn’t work for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  ❌ Why Flashcards Fell Short
&lt;/h2&gt;

&lt;p&gt;The spaced repetition applied to &lt;strong&gt;individual flashcards&lt;/strong&gt;, not chapters or topics.&lt;/p&gt;

&lt;p&gt;Flashcards encouraged &lt;strong&gt;memorization&lt;/strong&gt;, but CS requires &lt;strong&gt;deep understanding&lt;/strong&gt; of systems, logic, and code.&lt;/p&gt;

&lt;p&gt;Each module had ~100 slides per week, and I had 6 modules.As result, I couldn’t keep up with both flashcard creation and proper study.&lt;/p&gt;

&lt;p&gt;So I gave up on flashcards.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Enter: MCQs + ChatGPT (Free Tier)
&lt;/h2&gt;

&lt;p&gt;Some modules used &lt;strong&gt;MCQs&lt;/strong&gt; for continuous assessment. That sparked an idea:&lt;br&gt;
I wrote a &lt;strong&gt;Python script&lt;/strong&gt; to run simple True/False quizzes in the terminal — powered by ChatGPT-generated questions.&lt;/p&gt;

&lt;p&gt;It wasn’t perfect, but it was &lt;strong&gt;fast, effective&lt;/strong&gt;, and helped me score well.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Then Came the Trigger (Paid Tier)
&lt;/h2&gt;

&lt;p&gt;In one final exam, the MCQs had &lt;strong&gt;two plausible answers&lt;/strong&gt;, &lt;strong&gt;three distractors&lt;/strong&gt;, and &lt;strong&gt;only one correct&lt;/strong&gt;. The lecturer even encouraged us to &lt;strong&gt;use ChatGPT&lt;/strong&gt; to generate practice questions.&lt;/p&gt;

&lt;p&gt;That’s when it clicked:&lt;/p&gt;

&lt;p&gt;ChatGPT wasn’t just for brainstorming, it was a tool for &lt;strong&gt;deep learning&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It helped me &lt;strong&gt;understand&lt;/strong&gt; the material by summarizing slides, explaining concepts, providing examples, and testing me.&lt;/p&gt;

&lt;p&gt;Still, something was missing: &lt;strong&gt;spaced repetition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I explored Quizlet, Kahoot, and others but none of them offered what I needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ So I Built It Myself
&lt;/h2&gt;

&lt;p&gt;I had experience with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python, HTML/CSS, Java, WordPress, WooCommerce API&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A bit of &lt;strong&gt;JavaScript, PHP, MySQL&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Projects using &lt;strong&gt;Flask&lt;/strong&gt; and &lt;strong&gt;Django&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for this project, I needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A fast development cycle&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;A framework suitable for &lt;strong&gt;frequent user input&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple DB mapping&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s why I chose &lt;strong&gt;FastAPI&lt;/strong&gt; and built &lt;strong&gt;StudyQuiz&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 What StudyQuiz Does
&lt;/h2&gt;

&lt;p&gt;A web app that combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ MCQ-based quizzes&lt;/li&gt;
&lt;li&gt;🔄 Fisher-Yates question shuffling&lt;/li&gt;
&lt;li&gt;🧠 Spaced repetition (SuperMemo 2)&lt;/li&gt;
&lt;li&gt;💻 CLI-based quiz taking&lt;/li&gt;
&lt;li&gt;🌐 Soon: full browser-based UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/aissa-laribi/StudyQuiz" rel="noopener noreferrer"&gt;GitHub link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 I’d love feedback — especially from folks in &lt;strong&gt;edtech,&lt;/strong&gt; &lt;strong&gt;CS education&lt;/strong&gt;, or &lt;strong&gt;backend development&lt;/strong&gt;!&lt;/p&gt;

</description>
      <category>learning</category>
      <category>webdev</category>
      <category>computerscience</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>cmagick v.0.1.4</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Tue, 08 Nov 2022 17:14:49 +0000</pubDate>
      <link>https://dev.to/aissalaribi/cmagick-v014-13o2</link>
      <guid>https://dev.to/aissalaribi/cmagick-v014-13o2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hi guys!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just sharing the new release of cmagick. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's new?&lt;/strong&gt;&lt;br&gt;
The functionalities are exactly the same:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convert images&lt;/li&gt;
&lt;li&gt;Resize images&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main difference is about the test coverage of 100% and the removal of hard sys exit command that is unnecessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsea6p9i07xdmqnx5um0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsea6p9i07xdmqnx5um0k.png" alt=" " width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I have build cmagick?&lt;/strong&gt;&lt;br&gt;
I explained the reasons in the following post &lt;a href="https://dev.to/aissalaribi/cmagick-v012-hn8"&gt;https://dev.to/aissalaribi/cmagick-v012-hn8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd04e4ux2y2r1rau62ccu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd04e4ux2y2r1rau62ccu.png" alt=" " width="800" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The main features of cmagick v.0.1.4&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Converting images to the following formats (&lt;strong&gt;bmp,eps,gif,tiff,webp,wbmp,tga,png,jpg,jpeg,hdr,exr&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Resizing Images&lt;/li&gt;
&lt;li&gt;Support path arguments &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Simple usage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;p&gt;To convert images&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from cmagick import cmagick

cmagick.convert('website.jpg', 'website.webp')

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To resize images&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from cmagick import cmagick

cmagick.resize('website.jpg','100x100','website.jpg')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To convert and save in a defined directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from cmagick import cmagick

cmagick.convert('website.jpg', '/Desktop/newname.webp')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you for reading this small post🙏!&lt;/p&gt;

&lt;p&gt;Connect with me on &lt;a href="https://github.com/aissa-laribi" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and pls put ✨star✨ for this &lt;a href="https://github.com/aissa-laribi/cmagick" rel="noopener noreferrer"&gt;package&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>devops</category>
      <category>linux</category>
      <category>opensource</category>
    </item>
    <item>
      <title>cmagick v.0.1.2</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Tue, 12 Apr 2022 00:04:52 +0000</pubDate>
      <link>https://dev.to/aissalaribi/cmagick-v012-hn8</link>
      <guid>https://dev.to/aissalaribi/cmagick-v012-hn8</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hi guys!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have just built a Python package that converts, and resizes images&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I have build cmagick?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before I have used &lt;a href="https://pypi.org/project/Pillow/" rel="noopener noreferrer"&gt;Pillow&lt;/a&gt; and I had problems importing the "convert" module in &lt;strong&gt;AWS Lambda&lt;/strong&gt;, then I have used &lt;a href="https://pypi.org/project/Wand/" rel="noopener noreferrer"&gt;Wand&lt;/a&gt; which was amazing because I have managed to build a &lt;a href="https://github.com/aissa-laribi/awsops/tree/main/S3/Resizing-Images" rel="noopener noreferrer"&gt;serverless image resizer on AWS Lambda&lt;/a&gt;, and then I wanted to build a serverless application that converts to &lt;strong&gt;WebP&lt;/strong&gt; and I have struggled with Wand to link with libwebp in the Lambda runtime.&lt;/p&gt;

&lt;p&gt;As a result, I have decided to do roughly the same thing as Wand &lt;strong&gt;but instead of binding C programming language with Python, I am binding the input of the commands on the Linux CLI and Python.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd04e4ux2y2r1rau62ccu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd04e4ux2y2r1rau62ccu.png" alt=" " width="800" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The main features of cmagick v.0.1.2&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Converting images to the following formats (&lt;strong&gt;bmp,eps,gif,tiff,webp,wbmp,tga,png,jpg,jpeg,hdr,exr&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Resizing Images&lt;/li&gt;
&lt;li&gt;Support path arguments &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Simple usage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;p&gt;To convert images&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from cmagick import cmagick

cmagick.convert('website.jpg', 'website.webp')

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To resize images&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from cmagick import cmagick

cmagick.resize('website.jpg','100x100','website.jpg')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To convert and save in a defined directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from cmagick import cmagick

cmagick.convert('website.jpg', '/Desktop/newname.webp')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you for reading this small post🙏!&lt;/p&gt;

&lt;p&gt;Connect with me on &lt;a href="https://github.com/aissa-laribi" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and pls put ✨star✨ for this &lt;a href="https://github.com/aissa-laribi/cmagick" rel="noopener noreferrer"&gt;package&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>linux</category>
      <category>devops</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How to Backup Locally a Remote Mysql Database on Linux</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Wed, 16 Mar 2022 20:22:31 +0000</pubDate>
      <link>https://dev.to/aissalaribi/how-to-backup-locally-a-remote-mysql-database-on-linux-5e8e</link>
      <guid>https://dev.to/aissalaribi/how-to-backup-locally-a-remote-mysql-database-on-linux-5e8e</guid>
      <description>&lt;h2&gt;
  
  
  1) Make sure the Mysql server can listen for connections from the Internet
&lt;/h2&gt;

&lt;p&gt;The Mysql server uses the &lt;a href="https://serversforhackers.com/c/mysql-network-security" rel="noopener noreferrer"&gt;MySQL Bind-Address&lt;/a&gt; tool that enables to determine which connections the server listens.&lt;br&gt;
&lt;strong&gt;For Debian-based distros:&lt;/strong&gt;&lt;br&gt;
The Mysql bind-address is explicitly configured in /etc/mysql/mysql.conf.d/mysqld/mysqld.cnf&lt;br&gt;
 &lt;strong&gt;For RedHat-based distros:&lt;/strong&gt;&lt;br&gt;
The Mysql bind-address has to be configured in /etc/my.cnf&lt;/p&gt;

&lt;p&gt;There are three basic ways to configure bind-address:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bind-address = 127.0.0.1 which means the server listen on only connections from the server itself&lt;/li&gt;
&lt;li&gt;bind-address = 0.0.0.0 which means the server listen on any connections from the Internet&lt;/li&gt;
&lt;li&gt;bind-address = A defined IP address or range which means the server will listen on connections from the defined IP address or range.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For security reasons, it would make sense to set the bind-address to a defined address. However, in addition to the bind-address tool there is a another feature that set where users are allowed to connect from. We will set it after having configured the bind-address.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your Public IP address (Ignore this step if you want to let the server to listen on any connections over the Internet)
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl ifconfig.me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;2.Set the bind-address to listen on the desired network&lt;br&gt;
&lt;strong&gt;For Debian-based distros:&lt;/strong&gt;&lt;br&gt;
For nano editor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano /etc/mysql/mysql.conf.d/mysqld.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For vim editor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vi /etc/mysql/mysql.conf.d/mysqld.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the bind-address line and set it either on&lt;br&gt;
bind-address = Your IP address or bind-address = 0.0.0.0&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For RedHat-based distros:&lt;/strong&gt;&lt;br&gt;
For nano editor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano /etc/my.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For vim editor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vi /etc/my.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under [mysqld]&lt;br&gt;
Add bind-address = Your IP address or bind-address = 0.0.0.0&lt;/p&gt;

&lt;p&gt;Now the bind-address is set, we still cannot backup the data&lt;br&gt;
base remotely&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqic79dxvfmd9t57fbp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqic79dxvfmd9t57fbp9.png" alt=" " width="800" height="36"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2) Allowing The Database to Get Accessed From Your Public IP Address
&lt;/h2&gt;

&lt;p&gt;1.Check what users exist&lt;/p&gt;

&lt;p&gt;Log in your Mysql Server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mysql -u &amp;lt;user-name&amp;gt; -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then enter your password.&lt;/p&gt;

&lt;p&gt;Now check the users registered in the database&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT User, Host from mysql.user;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdn858ulxi60my7udosoc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdn858ulxi60my7udosoc.png" alt="Check Database Users " width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can see only a root user allowed to connect from 127.0.0.1 ==&amp;gt; IPv4 Localhost, ::1 ==&amp;gt; IPv6 Localhost, ip-172-31-84-33.ec2.internal ==&amp;gt; Private IP address allocated by AWS to this instance; and localhost.&lt;/p&gt;

&lt;p&gt;As a result, there is no user that can access from the Internet(0.0.0.0) to the server. So you need to register a new user with a specific host (IP address) &lt;/p&gt;

&lt;p&gt;Open a new tab in your terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl ifconfig.me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now go back to the previous tab and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE USER 'user_name'@'Your_Public_IP_Address' IDENTIFIED BY 'Your_Password';
GRANT ALL PRIVILEGES ON *.* TO 'user_name'@'Your_Public_IP_Address' WITH GRANT OPTION;
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpvarqki1u6mkt32xfaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpvarqki1u6mkt32xfaq.png" alt="Register New Mysql User" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let see our databases&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHOW DATABASES;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And backup a database, in this example I want to backup the sample database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dbf5s4ylmlt2lwaggaa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0dbf5s4ylmlt2lwaggaa.png" alt="Databases list" width="383" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To do so, execute the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mysqldump --user &amp;lt;username&amp;gt; -h &amp;lt;IP_server&amp;gt; -p &amp;lt;database_name&amp;gt; &amp;gt; &amp;lt;file_name&amp;gt;.sql

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlb0h3ez5yd76i4ygjcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlb0h3ez5yd76i4ygjcx.png" alt="Mysql backup command " width="800" height="70"&gt;&lt;/a&gt;&lt;br&gt;
Check the file where the database has been dumped&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;lt;file_name&amp;gt;.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following picture shows the beginning of the database &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgje4yzopbckbfrg64eib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgje4yzopbckbfrg64eib.png" alt="Database dumped" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following picture shows some content of the database; and we can see some Personal Informations such as (Age,First Name,Surname,email address,Gender, Favorite Color)&lt;br&gt;
&lt;strong&gt;Those Personal Informations are fictive and been randomly created&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhhlgh4zvzgvry3975vp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhhlgh4zvzgvry3975vp.png" alt="Database dumped2" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>linux</category>
      <category>security</category>
      <category>networking</category>
    </item>
    <item>
      <title>Creating Unique IDs programmatically on DynamoDB</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Mon, 21 Feb 2022 15:08:14 +0000</pubDate>
      <link>https://dev.to/aissalaribi/creating-unique-ids-programmatically-on-dynamodb-486f</link>
      <guid>https://dev.to/aissalaribi/creating-unique-ids-programmatically-on-dynamodb-486f</guid>
      <description>&lt;p&gt;&lt;strong&gt;Create a DynamoDB Table&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbndm3dwsyn4nvd6tt7m0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbndm3dwsyn4nvd6tt7m0.png" alt="DynamoDB Table" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leave the Partition Key Set To String, this way it will be easier to create Unique Ids Identifiers because &lt;strong&gt;unlike MySQL Databases DynamoDB will not generate an auto increment ID&lt;/strong&gt;. Furthermore, if we select Number or Binaries, there will be a conflict between DynamoDB and the &lt;br&gt;
uuid library because they respectively use different decimal calculation.&lt;/p&gt;

&lt;p&gt;Go to the Terminal and create an uuid&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu90lvuipybuagpeueq2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu90lvuipybuagpeueq2.png" alt="Terminal UUID" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy and paste the uuid, and create the item on the table&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6b6l16s1wmxr0sxmxcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6b6l16s1wmxr0sxmxcp.png" alt="Item" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a put_dynamodb function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclfjhph1c0f9302evu69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fclfjhph1c0f9302evu69.png" alt="put_dynamodb Lambda function" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to Configuration Permissions, Click on the Role Name and Attach the DynamoDbFullAccess policy to this Role&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fxwd5yjhjscve952aay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fxwd5yjhjscve952aay.png" alt="Role Lambda" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvst1kbmmlfyd0zplsbqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvst1kbmmlfyd0zplsbqi.png" alt="Attach Dynamodb Policy To Lambda Role" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First check if we can retrieve the data&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import json
import uuid
import boto3

db = boto3.client('dynamodb')


def lambda_handler(event, context):
    data = db.scan(TableName='database')
    return {
        'statusCode': 200,
        'body': json.dumps('Success')
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test the function&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwoxpti2dcpiye5y5rbo3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwoxpti2dcpiye5y5rbo3.png" alt="Test function" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's add a new item and an auto generated id with uuid module, and test the function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import json
import uuid
import boto3

db = boto3.client('dynamodb')
id_db=uuid.uuid4()


def lambda_handler(event, context):
    data= db.put_item(TableName='database', Item={'id':{'S':str(id_db)},'item':{'S':'iphone-10'},'available':{'BOOL': False}})
    return {
        'statusCode': 200,
        'body': json.dumps('Success')
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy65vegkssvcl346znyh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy65vegkssvcl346znyh5.png" alt=" " width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's write the exact same code except that we are going to add a color attribute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import json
import uuid
import boto3

db = boto3.client('dynamodb')
id_db=uuid.uuid4()


def lambda_handler(event, context):
    data= db.put_item(TableName='database', Item={'id':{'S':str(id_db)},'item':{'S':'iphone-10'},'available':{'BOOL': False},'color':{'S':'pink'}})
    return {
        'statusCode': 200,
        'body': json.dumps('Success')
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now let's check our database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nhqj0yz7zw1mumo3jz0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nhqj0yz7zw1mumo3jz0.png" alt="DynamoDb updated" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see we haven't entered any id manually, and they have been generated programmatically.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>python</category>
      <category>database</category>
    </item>
    <item>
      <title>How to use Beautiful Soup in AWS Lambda for Web Scraping</title>
      <dc:creator>Aissa Laribi</dc:creator>
      <pubDate>Sun, 20 Feb 2022 00:59:19 +0000</pubDate>
      <link>https://dev.to/aissalaribi/how-to-use-beautiful-soup-in-aws-lambda-for-web-scrapping-1gh8</link>
      <guid>https://dev.to/aissalaribi/how-to-use-beautiful-soup-in-aws-lambda-for-web-scrapping-1gh8</guid>
      <description>&lt;p&gt;The purpose of this post is to show how to use the Beautiful Soup module in AWS Lambda with Python Runtimes.Keep in mind, AWS Lambda is not integrated with all the modules available for Python. And the only way to import the modules to Lambda is to bundle the lambda function alongside the modules in an isolated environment.&lt;/p&gt;

&lt;p&gt;The idea is similar to containers, we create an isolated environment, we import only the dependencies we need to make our application working, we write our code, we bundle it and we export it to the Cloud.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Install Pipenv&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pipenv is the module that will enable us to create an isolated environment for our lambda function.&lt;/p&gt;

&lt;p&gt;For Debian:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update -y
sudo apt upgrade -y
sudo apt install python-pip
pip3 install pipenv&amp;nbsp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For RPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update -y
sudo apt upgrade -y
sudo yum install python-pip
pip3 install pipenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2) Create a Python 3.8 environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the time I am writing, the documentation for Beautiful Soup has been written for Python 3.8 &lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/" rel="noopener noreferrer"&gt;https://www.crummy.com/software/BeautifulSoup/bs4/doc/&lt;/a&gt; . As result,we need a Python 3.8 isolated environment. Let's create it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pipenv --python 3.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkszi6s2u7izj4lhhqxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkszi6s2u7izj4lhhqxw.png" alt="Creating Python Environment" width="800" height="435"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pipenv shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wxfzfdi5uoiey7f1u42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wxfzfdi5uoiey7f1u42.png" alt="Log in the Virtual Environment " width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) Install our bs4 dependency&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install bs4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbffmmnw8aw83xdwf1ubi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbffmmnw8aw83xdwf1ubi.png" alt="Installing bs4" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4) Write the Lambda function&lt;/strong&gt;&lt;br&gt;
Create a file name lambda_function.py, &lt;strong&gt;it's very important to name it "lambda_function.py", otherwise the Lambda handler will not work&lt;/strong&gt;&lt;br&gt;
Copy the code supplied in the following link, paste it onto the the lambda_function.py file, and save it. &lt;a href="https://github.com/aissa-laribi/bs4-in-lambda/blob/main/lambda_function.py" rel="noopener noreferrer"&gt;https://github.com/aissa-laribi/bs4-in-lambda/blob/main/lambda_function.py&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5t8aycd4l4c4lawlefk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5t8aycd4l4c4lawlefk.png" alt="Lambda function" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5) Bundle up the lambda function and the dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now it's time to move the lambda function alongside the dependencies of our environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp lambda_function.py ~/.local/share/virtualenvs/&amp;lt;yourenvname&amp;gt;/lib/python3.8/site-packages
cd ~/.local/share/virtualenvs/&amp;lt;yourenvname&amp;gt;/lib/python3.8/site-packages
ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And normally, you should be able to see your lambda function alongside the dependencies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F183xk4efijimb1rfme8j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F183xk4efijimb1rfme8j.png" alt="Lambda function &amp;amp; dependencies" width="800" height="435"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now, we need to zip the whole directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zip -r9 bs4_in_lambda.zip *
cp bs4_in_lambda.zip ~/Desktop
cd &amp;nbsp;~/Desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvovgzguq3selyvbbsfk3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvovgzguq3selyvbbsfk3.png" alt="Zipping The Lambda Function" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;**&lt;br&gt;
6) Upload the Zip File to your Lambda Function****&lt;/p&gt;

&lt;p&gt;Then, create a Lambda Function, and make sure that Python 3.8 Runtime is selected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnomjydkyoo6jq8utbbmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnomjydkyoo6jq8utbbmg.png" alt="Creating the Lambda function" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to Code and in the top right corner, click on Upload from&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qa6b4j67ynj2cmaiqn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qa6b4j67ynj2cmaiqn8.png" alt="Lambda function uploading zip file" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And select the Zip file we have created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F50957hwb56akpfsw3eio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F50957hwb56akpfsw3eio.png" alt="Lambda function uploading zip file" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Lambda function will show up and we can see on the left side all the pip packages stored in folders.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwkt14oihoax85knjlc1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwkt14oihoax85knjlc1.png" alt="Imgur Image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then go to Configuration and increase the runtime because there are 10 pages to be scraped.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faa9x9zte1o0dsg5oit4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faa9x9zte1o0dsg5oit4q.png" alt="Lambda Configuration" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's set a 5 minute runtime to make sure it will scrape all the pages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsdza9mqrql2q275u8y5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsdza9mqrql2q275u8y5.png" alt="Lambda Runtime" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then,return to Code &amp;gt; Test.&lt;/p&gt;

&lt;p&gt;Leave the Configuration Test content by default and add any name to the Event Name and Save.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0enndgjps88bjr1nmfiu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0enndgjps88bjr1nmfiu.png" alt="Configuratio Test" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on Test.&lt;/p&gt;

&lt;p&gt;And sometimes we will get this error message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps0jx88a0v69u8ox4fu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps0jx88a0v69u8ox4fu2.png" alt="Test Failing" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The trick is to switch between http and https in our function.&lt;/p&gt;

&lt;p&gt;Press Ctrl + F Scroll Down and replace all "https" with "http", Deploy and test the function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjopejvepwuasd3np9j1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjopejvepwuasd3np9j1r.png" alt="Tweak the function" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et Voila!&lt;br&gt;
We have a list of websites.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjlnicfk33wfra0xh8fe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjlnicfk33wfra0xh8fe.png" alt="Imgur Image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then go to Monitor &amp;gt; Logs &amp;gt; Click in the LogStream of the first invocation.Then, a new window will open, and you will get access to the full list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq7z7gysdtaja6ilbii4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq7z7gysdtaja6ilbii4.png" alt="Imgur Image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcppn8659176tcq5fqz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcppn8659176tcq5fqz5.png" alt="Imgur Image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>serverless</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
