<?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>Forem: Monazir Muhammad Doha</title>
    <description>The latest articles on Forem by Monazir Muhammad Doha (@itsmmdoha).</description>
    <link>https://forem.com/itsmmdoha</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%2F3487110%2F6f8ffa83-2d1e-43e3-b726-98e3186df5cf.jpg</url>
      <title>Forem: Monazir Muhammad Doha</title>
      <link>https://forem.com/itsmmdoha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/itsmmdoha"/>
    <language>en</language>
    <item>
      <title>Build a $10 DIY Wi-Fi USB Keylogger with ESP32-S3 and MicroPython (DuckLogger)</title>
      <dc:creator>Monazir Muhammad Doha</dc:creator>
      <pubDate>Sun, 01 Mar 2026 15:02:38 +0000</pubDate>
      <link>https://forem.com/itsmmdoha/build-a-10-diy-wi-fi-usb-keylogger-with-esp32-s3-and-micropython-ducklogger-30dl</link>
      <guid>https://forem.com/itsmmdoha/build-a-10-diy-wi-fi-usb-keylogger-with-esp32-s3-and-micropython-ducklogger-30dl</guid>
      <description>&lt;p&gt;Have you ever wanted to build your own hardware keylogger but were deterred by the high cost or the need to design custom PCBs? Meet &lt;strong&gt;&lt;a href="https://github.com/Itsmmdoha/duckLogger" rel="noopener noreferrer"&gt;DuckLogger&lt;/a&gt;&lt;/strong&gt;, an open-source, ESP32-S3–based USB Key Logger that you can build yourself for under $10 using off-the-shelf parts. &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%2Fer9tjg2bptcoxalmo5ka.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%2Fer9tjg2bptcoxalmo5ka.png" alt="DuckLogger DIY Wi-Fi USB Keylogger Setup" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this guide, we'll cover what DuckLogger is, the hardware you need, and how you can assemble and program it yourself in a few simple steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is DuckLogger?
&lt;/h2&gt;

&lt;p&gt;DuckLogger is a MicroPython-powered DIY hardware hacking project. It silently intercepts and logs USB keystrokes into a text file and hosts a built-in Wi-Fi access point, allowing you to easily and wirelessly download your logs through a sleek web UI.&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%2Fnc8pl3mym21c9dniu3fm.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%2Fnc8pl3mym21c9dniu3fm.png" alt="DuckLogger Hardware and Components Overview" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Internal Storage Logging:&lt;/strong&gt; Records keystrokes and safely saves them to the ESP32's internal flash storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wireless Access:&lt;/strong&gt; Automatically spins up a Wi-Fi Access Point when plugged in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web UI:&lt;/strong&gt; Download your log files directly from your browser by navigating to &lt;code&gt;http://192.168.4.1/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Custom PCBs Required:&lt;/strong&gt; Built entirely with widely available breakout boards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(Upcoming features include sending Ducky scripts directly from the web UI and remote keyboard control via your browser!)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Hardware Requirements
&lt;/h2&gt;

&lt;p&gt;To build this DIY keylogger, you only need three easily obtainable components (which can be easily found on AliExpress or Amazon):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ESP32-S3 SuperMini:&lt;/strong&gt; A tiny but powerful microcontroller that handles the Wi-Fi, storage, and logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CH9350 HID Module:&lt;/strong&gt; A specialized module that converts USB keyboard inputs into serial data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 Female Jumper Wires:&lt;/strong&gt; For connecting the modules together.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Total cost? &lt;strong&gt;Less than $10.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Build Your DuckLogger
&lt;/h2&gt;

&lt;p&gt;Ready to build your own? Let's walk through the setup process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Wiring and Schematics
&lt;/h3&gt;

&lt;p&gt;Connecting the ESP32-S3 to the CH9350 module is incredibly straightforward. You only need to make four connections using your jumper wires.&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%2F3flznf9cobtk2yxqylp7.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%2F3flznf9cobtk2yxqylp7.png" alt="DuckLogger ESP32-S3 and CH9350 Wiring Schematic" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ESP32-S3 Pin&lt;/th&gt;
&lt;th&gt;CH9350 Pin&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;5V&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5V&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Power&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GND&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GND&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ground&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GP1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TX&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Receive Keystrokes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GP2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RX&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Send Commands&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: Configure the CH9350 Module
&lt;/h3&gt;

&lt;p&gt;The CH9350 supports multiple operating modes. For our keylogger to intercept USB keystrokes, we need to set it to &lt;strong&gt;USB Host Mode&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%2Foy99j97plr7akhz7dcsw.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%2Foy99j97plr7akhz7dcsw.png" alt="CH9350 DIP Switch Configuration for USB Host Mode" width="800" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the onboard DIP switches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;S0&lt;/code&gt; to the &lt;strong&gt;GND position (0)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Keep all other switches in the &lt;strong&gt;opposite position (1)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This converts the USB keyboard inputs into serial data sent via UART at a default baud rate of 115200.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Flash MicroPython to the ESP32-S3
&lt;/h3&gt;

&lt;p&gt;DuckLogger runs on Python. If your board isn't already running it, you'll need to flash the latest MicroPython firmware.&lt;br&gt;
You can find the official ESP32-S3 Generic flashing instructions &lt;a href="https://micropython.org/download/ESP32_GENERIC_S3/" rel="noopener noreferrer"&gt;on the MicroPython website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Once flashed, disconnect and reconnect the board via USB.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Install Dependencies
&lt;/h3&gt;

&lt;p&gt;On your computer, install &lt;code&gt;mpremote&lt;/code&gt;, a handy CLI tool for interacting with MicroPython devices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;mpremote
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify your board is detected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mpremote connect list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, install the required USB packages directly onto the ESP32-S3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mpremote mip &lt;span class="nb"&gt;install &lt;/span&gt;usb-device
mpremote mip &lt;span class="nb"&gt;install &lt;/span&gt;usb-device-keyboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Upload the DuckLogger Code
&lt;/h3&gt;

&lt;p&gt;Clone the official DuckLogger repository to your computer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Itsmmdoha/duckLogger.git
&lt;span class="nb"&gt;cd &lt;/span&gt;duckLogger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With your board connected via USB, copy the project files over to the microcontroller:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Copy all library files to the &lt;code&gt;/lib&lt;/code&gt; directory on the device:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mpremote &lt;span class="nb"&gt;cp &lt;/span&gt;lib/&lt;span class="k"&gt;*&lt;/span&gt;.py :/lib/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Copy the main execution file to the root of the device:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mpremote &lt;span class="nb"&gt;cp &lt;/span&gt;main.py :
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Reboot the board to start DuckLogger:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mpremote reset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How to Use Your New Keylogger
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Plug the target USB keyboard&lt;/strong&gt; directly into the CH9350 HID module.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect the ESP32-S3 SuperMini&lt;/strong&gt; to the target computer using a USB-C to USB-A cable. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The device will automatically power on, pass through the keystrokes to the computer (so the computer behaves normally), and simultaneously save those keystrokes to its internal flash memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To retrieve your logs:&lt;/strong&gt;&lt;br&gt;
From your smartphone or laptop, look for the newly created Wi-Fi Access Point.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connect to the Wi-Fi Network&lt;/strong&gt; (Default Password: &lt;code&gt;duckPass1234&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open your browser&lt;/strong&gt; and navigate to: &lt;code&gt;http://192.168.4.1/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Boom! You now have a low-cost, stealthy, Wi-Fi enabled hardware keylogger. &lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;DuckLogger is an awesome example of how accessible hardware hacking and cybersecurity projects have become. Using MicroPython and cheap microcontrollers, you can build testing tools that previously cost hundreds of dollars. &lt;/p&gt;

&lt;p&gt;Check out the full source code, contribute, or drop a star on the &lt;a href="https://github.com/Itsmmdoha/duckLogger" rel="noopener noreferrer"&gt;DuckLogger GitHub Repository&lt;/a&gt;!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclaimer: This project is strictly for educational purposes, security research, and personal use on your own devices. Always ensure you have explicit, documented permission before using keystroke logging tools.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>esp32</category>
      <category>python</category>
      <category>cybersecurity</category>
      <category>hardware</category>
    </item>
    <item>
      <title>How to Integrate bKash Payment Gateway in Python (The Easy Way)</title>
      <dc:creator>Monazir Muhammad Doha</dc:creator>
      <pubDate>Fri, 27 Feb 2026 13:14:45 +0000</pubDate>
      <link>https://forem.com/itsmmdoha/how-to-integrate-bkash-payment-gateway-in-python-the-easy-way-1997</link>
      <guid>https://forem.com/itsmmdoha/how-to-integrate-bkash-payment-gateway-in-python-the-easy-way-1997</guid>
      <description>&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%2Fqp670dd9isdgoiro8ige.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%2Fqp670dd9isdgoiro8ige.png" alt="An image with example usage of pybkash" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are building a web application for the Bangladeshi market, integrating bKash is an absolute necessity. As the largest mobile financial service (MFS) in Bangladesh, bKash is the go-to payment method for millions of users. &lt;/p&gt;

&lt;p&gt;However, integrating the bKash API using Python has historically been a headache. Developers often have to write boilerplate code, manually handle token expiration, and deal with raw HTTP requests. Whether you are using Django, Flask, or FastAPI, you just want a clean, Pythonic way to accept payments.&lt;/p&gt;

&lt;p&gt;That’s where &lt;a href="https://github.com/Itsmmdoha/pybkash" rel="noopener noreferrer"&gt;&lt;strong&gt;pybkash&lt;/strong&gt;&lt;/a&gt; comes in. &lt;code&gt;pybkash&lt;/code&gt; is a modern, fully-typed Python SDK for the bKash payment gateway that handles all the heavy lifting for you. It covers the entire bKash API surface and uniquely supports both &lt;strong&gt;synchronous&lt;/strong&gt; (Django/Flask) and &lt;strong&gt;asynchronous&lt;/strong&gt; (FastAPI) operations out of the box.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will walk through how to easily integrate the bKash payment gateway into your Python application using &lt;code&gt;pybkash&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we start writing code, you will need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Python 3.x&lt;/strong&gt; installed on your system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;bKash Sandbox/Merchant Credentials&lt;/strong&gt;: You need a &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt;, &lt;code&gt;app_key&lt;/code&gt;, and &lt;code&gt;app_secret&lt;/code&gt;. You can get these by registering on the bKash Developer Portal&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 1: Installation
&lt;/h2&gt;

&lt;p&gt;Installing the package is straightforward. Open your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pybkash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Authenticating with the bKash API
&lt;/h2&gt;

&lt;p&gt;To communicate with bKash, you need to generate an authentication token. Traditionally, you would have to request a token and manage its lifecycle. With &lt;code&gt;pybkash&lt;/code&gt;, you just pass your credentials into a &lt;code&gt;Token&lt;/code&gt; object, and the &lt;code&gt;Client&lt;/code&gt; handles the rest automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pybkash&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Token&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Initialize the Token with your bKash credentials
&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;app_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_app_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;app_secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_app_secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sandbox&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;  &lt;span class="c1"&gt;# Important: Set to False when moving to production!
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Create the bKash Client
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: Always keep your credentials safe using environment variables (e.g., using &lt;code&gt;python-dotenv&lt;/code&gt;). Never hardcode them in your production codebase!&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Creating a Payment (Redirecting the User)
&lt;/h2&gt;

&lt;p&gt;The bKash checkout process follows a redirect-based flow: &lt;code&gt;Create → Execute → Query&lt;/code&gt;. First, you create a payment intent on your server. bKash will return a secure URL. You then redirect your customer to this URL to enter their bKash number, OTP, and PIN.&lt;/p&gt;

&lt;p&gt;Here is how you create that payment URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 3. Create the payment intent
&lt;/span&gt;&lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;callback_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://yoursite.com/api/bkash/callback&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Where bKash sends the user after paying
&lt;/span&gt;    &lt;span class="n"&gt;payer_reference&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CUSTOMER_001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Optional: Pre-populates the bKash number on the checkout page
&lt;/span&gt;    &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;  &lt;span class="c1"&gt;# The amount to charge in BDT
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Payment ID: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payment_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Redirect User To: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bkash_url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens here?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;payment.payment_id&lt;/code&gt;: Store this ID in your database. You will need it to verify the payment later.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;payment.bkash_url&lt;/code&gt;: Return this URL to your frontend or issue an HTTP redirect so the user can complete the payment.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 4: Handling the Callback &amp;amp; Executing the Payment
&lt;/h2&gt;

&lt;p&gt;After the user completes, fails, or cancels the transaction on the bKash page, bKash redirects the user back to the base &lt;code&gt;callback_url&lt;/code&gt; you provided in Step 3, appending several &lt;strong&gt;query parameters&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;For example, a successful redirection looks like this:&lt;br&gt;
&lt;code&gt;https://yoursite.com/api/bkash/callback?paymentID=TR0011...&amp;amp;status=success&amp;amp;signature=...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These query parameters act as a &lt;strong&gt;signal&lt;/strong&gt; indicating that the user has finished interacting with the bKash page. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Crucial Security Warning:&lt;/strong&gt; The callback redirection alone should &lt;strong&gt;not&lt;/strong&gt; be treated as final confirmation of a successful transaction, as malicious users can manipulate URLs. You &lt;strong&gt;must&lt;/strong&gt; execute the payment server-side to actually deduct the funds and securely verify the final state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the user hits your callback endpoint, extract the &lt;code&gt;status&lt;/code&gt; and &lt;code&gt;paymentID&lt;/code&gt; from the URL query parameters, and execute the payment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 4. Extract query parameters from your web framework's request object
&lt;/span&gt;&lt;span class="n"&gt;status_from_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# Extracted from ?status=success
&lt;/span&gt;&lt;span class="n"&gt;payment_id_from_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment_id_received_from_query_params&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; 

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status_from_url&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# 5. Execute the payment server-side to finalize the transaction
&lt;/span&gt;    &lt;span class="n"&gt;execution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_id_from_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 6. Verify if the execution was successful
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;execution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_complete&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Payment successful! Transaction ID (TrxID): &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;execution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trx_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# TODO: Update your database, mark the order as paid, and send a receipt!
&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Execution failed. Status: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;execution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User cancelled or failed the payment. Status: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status_from_url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! You've successfully integrated bKash into your Python application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: Asynchronous Support for FastAPI Developers
&lt;/h2&gt;

&lt;p&gt;If you are building a high-performance web API using &lt;strong&gt;FastAPI&lt;/strong&gt; or &lt;strong&gt;Starlette&lt;/strong&gt;, blocking synchronous calls can slow down your application. &lt;code&gt;pybkash&lt;/code&gt; was built with modern Python in mind and provides first-class &lt;code&gt;async&lt;/code&gt; support.&lt;/p&gt;

&lt;p&gt;You can simply import the asynchronous client and &lt;code&gt;await&lt;/code&gt; your payment methods for non-blocking I/O:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pybkash&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AsyncClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AsyncToken&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_bkash_payment&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AsyncToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;app_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_app_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;app_secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_app_secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;sandbox&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Initialize the Async client
&lt;/span&gt;    &lt;span class="n"&gt;async_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AsyncClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Create payment asynchronously
&lt;/span&gt;    &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;async_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;callback_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://yoursite.com/api/bkash/callback&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Redirect to: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bkash_url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Run the async function
&lt;/span&gt;&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;process_bkash_payment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Integrating the bKash payment gateway in Python doesn't have to be complicated. By using the &lt;code&gt;pybkash&lt;/code&gt; SDK, you can implement secure, production-ready payment flows in just a few lines of code, whether you are using Django, Flask, or FastAPI.&lt;/p&gt;

&lt;p&gt;Beyond basic payments, &lt;code&gt;pybkash&lt;/code&gt; also supports advanced features like &lt;strong&gt;Agreement Creation (Tokenized Checkout)&lt;/strong&gt;, &lt;strong&gt;Refunds&lt;/strong&gt;, and &lt;strong&gt;Transaction Searching&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  📖 Dive Deeper into the Documentation
&lt;/h3&gt;

&lt;p&gt;This tutorial covered the standard checkout flow, but there is much more! For an in-depth look at all available methods, return types, and operational rules, check out the &lt;a href="https://github.com/Itsmmdoha/pybkash/blob/main/docs/detailed_usage.md" rel="noopener noreferrer"&gt;&lt;strong&gt;Detailed Usage Documentation&lt;/strong&gt;&lt;/a&gt; directly in the repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌟 Call to Action
&lt;/h3&gt;

&lt;p&gt;If this guide helped you save time, please consider dropping a star (⭐) on the &lt;a href="https://github.com/Itsmmdoha/pybkash" rel="noopener noreferrer"&gt;&lt;strong&gt;pybkash GitHub Repository&lt;/strong&gt;&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you find any bugs, have feature requests, or want to contribute to making the best bKash Python SDK even better, feel free to open an issue or submit a pull request!&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>python</category>
      <category>fastapi</category>
      <category>bkash</category>
      <category>gateway</category>
    </item>
    <item>
      <title>ipasnmatcher - Python Package for Fast IP-to-ASN Matching</title>
      <dc:creator>Monazir Muhammad Doha</dc:creator>
      <pubDate>Mon, 08 Sep 2025 13:33:57 +0000</pubDate>
      <link>https://forem.com/itsmmdoha/ipasnmatcher-python-package-for-fast-ip-to-asn-matching-5bpm</link>
      <guid>https://forem.com/itsmmdoha/ipasnmatcher-python-package-for-fast-ip-to-asn-matching-5bpm</guid>
      <description>&lt;p&gt;Recently, an idea popped into my head. It’s about a website, and this site will have some features that are exclusive to BRACU students.&lt;br&gt;
Upon looking for ways to restrict the rest of the world from accessing those features, I figured I could limit them to people connected to the University WiFi. But then again, how do I do that? I can’t host things locally on the University network.&lt;/p&gt;

&lt;p&gt;But what if I could distinguish IP addresses from BRACU’s internet? Then I could allow just those IPs and block the rest of the world.&lt;br&gt;
After digging a little deeper into networking, I found out that every organization connected to the internet has something called an ASN number—think of it like an ID. This ID is then used to distinguish organizations by whoever runs the internet, and every organization is given a range of IP addresses.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Organization A with ASN 1234 has the IP range &lt;code&gt;192.168.0.9–27&lt;/code&gt;.&lt;br&gt;
That means this organization is allowed to have &lt;code&gt;192.168.0.9&lt;/code&gt;, &lt;code&gt;192.168.0.10&lt;/code&gt;, &lt;code&gt;192.168.0.11&lt;/code&gt; up to &lt;code&gt;192.168.0.27&lt;/code&gt;, but not &lt;code&gt;192.168.0.28&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In reality, this is a little more complex, but you get the idea.&lt;br&gt;
ASN numbers and their IP ranges for every organization are public information—you can look them up easily. For instance, just Google “BRACU ASN” and you’ll find it!&lt;/p&gt;

&lt;p&gt;Based on this logic, I made a simple Python package that takes the ASN number of an organization and lets you check if any given IP address falls within its IP range.&lt;/p&gt;

&lt;p&gt;Hope you like this! I’d really appreciate a fork or a star on GitHub—the.&lt;/p&gt;
&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fast IP-to-ASN matching with optimized network ranges&lt;/li&gt;
&lt;li&gt;Built-in caching to minimize API requests&lt;/li&gt;
&lt;li&gt;Optional strict mode to consider only active prefixes&lt;/li&gt;
&lt;li&gt;Uses accurate data from RIPE NCC&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;ipasnmatcher
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ipasnmatcher&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ASN&lt;/span&gt;

&lt;span class="c1"&gt;# Creating an ASN object fetches prefix data from the RIPEstat API and caches it locally
&lt;/span&gt;&lt;span class="n"&gt;asn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ASN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AS151981&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Check if an IP belongs to this ASN
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;153.53.148.45&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# True or False
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Advanced Usage
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;asn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ASN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;asn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AS15169&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;# ASN (e.g., Google)
&lt;/span&gt;    &lt;span class="n"&gt;strict&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;# Only consider active prefixes
&lt;/span&gt;    &lt;span class="n"&gt;cache_max_age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7200&lt;/span&gt;  &lt;span class="c1"&gt;# Cache duration in seconds (2 hours)
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  Combine ASN objects
&lt;/h3&gt;

&lt;p&gt;Merge multiple ASNs with &lt;code&gt;+&lt;/code&gt; to check IPs against all their prefixes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ipasnmatcher&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ASN&lt;/span&gt;

&lt;span class="n"&gt;google&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ASN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AS15169&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# Google
&lt;/span&gt;&lt;span class="n"&gt;cloudflare&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ASN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AS13335&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Cloudflare
&lt;/span&gt;
&lt;span class="n"&gt;combined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;google&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cloudflare&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8.8.8.8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# True (Google)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.1.1.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# True (Cloudflare)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;repr()&lt;/code&gt; shows the full combination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ASN(asn='AS15169', strict=False, cache_max_age=3600) + ASN(asn='AS13335', strict=False, cache_max_age=3600)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Parameters
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;ASN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cache_max_age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;asn&lt;/code&gt;: ASN identifier in format &lt;code&gt;"AS12345"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;strict&lt;/code&gt;: If &lt;code&gt;True&lt;/code&gt;, only prefixes currently active are considered (default: &lt;code&gt;False&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cache_max_age&lt;/code&gt;: Cache lifetime in seconds (default: &lt;code&gt;3600&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;On initialization, the &lt;code&gt;ASN&lt;/code&gt; object fetches announced prefixes from the RIPEstat API and caches them locally in &lt;code&gt;.ipasnmatcher_cache/{asn}.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Subsequent uses load data from cache if it is fresh (not older than &lt;code&gt;cache_max_age&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Matching IPs against ASN prefixes is done efficiently using Python's &lt;code&gt;ipaddress&lt;/code&gt; module.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Network security and traffic validation&lt;/li&gt;
&lt;li&gt;CDN traffic routing based on ASN ownership&lt;/li&gt;
&lt;li&gt;IP classification by network operators&lt;/li&gt;
&lt;li&gt;Compliance monitoring of network connections&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitHub
&lt;/h2&gt;

&lt;p&gt;Star or fork this project on &lt;a href="https://github.com/Itsmmdoha/ipasnmatcher" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>asn</category>
    </item>
  </channel>
</rss>
