<?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.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 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="Image description" 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="Image description" 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="Image description" 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="Image description" 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="Image description" 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="Image description" width="800" height="35"&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="227"&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="69"&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="397"&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="435"&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="Image description" 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 
&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  ~/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>
