[{"content":" Published: June 2026\nStack: Django · Django REST Framework · Python 3.11+ · eSewa Intent API v2\nTable of Contents Background \u0026amp; Motivation Understanding the eSewa Intent Payment Flow Project Structure \u0026amp; Environment Setup Step 1 — Booking a Payment Intent Step 2 — HMAC-SHA256 Signatures Step 3 — Handling the Callback Step 4 — Server-Side Status Verification Step 5 — Django Routing The Bug: Silent Callback Failures in Production Integration Checklist 1. Background \u0026amp; Motivation eSewa is Nepal\u0026rsquo;s most widely used digital payment wallet. For any product targeting Nepali users, eSewa integration is essentially mandatory.\neSewa offers two integration modes:\nMode Mechanism Best for Legacy v1 HTML form redirect, browser-based Web apps Intent API v2 REST API + app deep-link Mobile apps The Intent API v2 eliminates the browser redirect chain entirely. Instead, your backend books a payment intent, gets a deeplink, and the mobile client opens the eSewa app directly. The result is a seamless native-to-native handoff that feels far more polished.\nThis post documents a full production integration of the Intent API v2 — including a production-only failure that took us hours to root-cause.\n2. Understanding the eSewa Intent Payment Flow Mobile Client Your Backend eSewa Gateway ────────────── ──────────── ───────────── │ │ │ │── POST /initiate ──\u0026gt;│ │ │ │── POST /intent/book ───\u0026gt;│ │ │\u0026lt;── { booking_id, │ │ │ deeplink, │ │ │ correlation_id } ───│ │\u0026lt;── { deeplink } ────│ │ │ │ │ │─── open deeplink ──────────────────────────\u0026gt; │ │ (user confirms payment in eSewa) │ │ │ │ │ │\u0026lt;── POST callback_url ───│ ← server push │ │ { signature, ... } │ │ │ │ │ │── POST /intent/status ─\u0026gt;│ ← server verify │ │\u0026lt;── { status: SUCCESS } ─│ │ │ │ │\u0026lt;── 200 OK ──────────│ │ │ (app polls status │ │ │ via redirect_url) │ │ Three IDs, one transaction Every payment involves three identifiers that you need to store and later reconstruct:\nIdentifier Origin Used for transaction_uuid Generated by you before booking Linking the intent to your DB record booking_id Returned by eSewa on /intent/book Included in the status check signature correlation_id Returned by eSewa on /intent/book Primary key for status checks We persist these as a composite string {transaction_uuid}:{booking_id}:{correlation_id} in a single DB column, making reconstruction deterministic without schema changes.\n3. Project Structure \u0026amp; Environment Setup We isolate everything eSewa-related into a self-contained package. Drop it anywhere in your Django project and register the URLs — nothing else needs to change.\nesewa/ # standalone package — drop anywhere in your project ├── __init__.py ├── constants.py # Enums, response codes, signed-field-name constants ├── exceptions.py # Typed domain exceptions ├── service.py # All eSewa API logic (signing, booking, status check) ├── views.py # DRF views — thin HTTP controllers only └── urls.py # URL patterns to include() in your root router Every import inside the package uses relative paths (from . import ...), so the package name is completely decoupled from your host project\u0026rsquo;s module layout.\nEnvironment variables # .env ESEWA_INTENT_KEY=\u0026lt;your_base64_hmac_key\u0026gt; ESEWA_INTENT_PRODUCT_CODE=\u0026lt;your_product_code\u0026gt; ESEWA_INTENT_BOOK_URL=https://checkout.esewa.com.np/api/client/intent/payment/book ESEWA_INTENT_STATUS_URL=https://checkout.esewa.com.np/api/client/intent/payment/status BACKEND_API_URL=https://api.yourdomain.com [!IMPORTANT] The Intent API uses the same URLs for both sandbox and production. The environment is determined entirely by which product_code and ESEWA_INTENT_KEY pair you use. Request separate credentials from eSewa for each environment.\n4. Step 1 — Booking a Payment Intent constants.py from enum import StrEnum class EsewaResponseCode(StrEnum): SUCCESS = \u0026#34;IP-200\u0026#34; CREATED = \u0026#34;IP-201\u0026#34; class EsewaPaymentStatus(StrEnum): SUCCESS = \u0026#34;SUCCESS\u0026#34; FAILED = \u0026#34;FAILED\u0026#34; CANCELED = \u0026#34;CANCELED\u0026#34; PENDING = \u0026#34;PENDING\u0026#34; # Exact field order for signing — must match signed_field_names BOOKING_SIGNED_FIELDS = \u0026#34;product_code,amount,transaction_uuid\u0026#34; STATUS_SIGNED_FIELDS = \u0026#34;booking_id,product_code,correlation_id\u0026#34; exceptions.py class EsewaIntentError(Exception): \u0026#34;\u0026#34;\u0026#34;Base exception for all eSewa Intent API errors.\u0026#34;\u0026#34;\u0026#34; class EsewaBookingError(EsewaIntentError): \u0026#34;\u0026#34;\u0026#34;Raised when the /intent/book call fails or returns a non-success code.\u0026#34;\u0026#34;\u0026#34; class EsewaStatusCheckError(EsewaIntentError): \u0026#34;\u0026#34;\u0026#34;Raised when the /intent/status call fails or returns a non-success code.\u0026#34;\u0026#34;\u0026#34; class EsewaSignatureError(EsewaIntentError): \u0026#34;\u0026#34;\u0026#34;Raised when HMAC signature verification fails.\u0026#34;\u0026#34;\u0026#34; services/esewa_service.py — config \u0026amp; crypto layer from __future__ import annotations import base64 import hashlib import hmac import logging import os import uuid from dataclasses import dataclass from typing import TYPE_CHECKING import requests from requests import Response, Timeout, HTTPError from payment_management.constants import ( BOOKING_SIGNED_FIELDS, STATUS_SIGNED_FIELDS, EsewaPaymentStatus, EsewaResponseCode, ) from payment_management.exceptions import ( EsewaBookingError, EsewaSignatureError, EsewaStatusCheckError, ) if TYPE_CHECKING: pass logger = logging.getLogger(\u0026#34;payment.esewa\u0026#34;) _ESEWA_REQUEST_TIMEOUT = 20 # seconds # ─── Config ─────────────────────────────────────────────────────────────────── def _get_env(key: str, default: str = \u0026#34;\u0026#34;) -\u0026gt; str: value = os.getenv(key, default).strip() if not value: raise EnvironmentError(f\u0026#34;Required environment variable \u0026#39;{key}\u0026#39; is not set.\u0026#34;) return value class EsewaConfig: \u0026#34;\u0026#34;\u0026#34;Lazy-loaded, centralised access to eSewa environment configuration.\u0026#34;\u0026#34;\u0026#34; @staticmethod def book_url() -\u0026gt; str: return os.getenv( \u0026#34;ESEWA_INTENT_BOOK_URL\u0026#34;, \u0026#34;https://checkout.esewa.com.np/api/client/intent/payment/book\u0026#34;, ).strip() @staticmethod def status_url() -\u0026gt; str: return os.getenv( \u0026#34;ESEWA_INTENT_STATUS_URL\u0026#34;, \u0026#34;https://checkout.esewa.com.np/api/client/intent/payment/status\u0026#34;, ).strip() @staticmethod def product_code() -\u0026gt; str: return _get_env(\u0026#34;ESEWA_INTENT_PRODUCT_CODE\u0026#34;) @staticmethod def secret_key() -\u0026gt; str: return _get_env(\u0026#34;ESEWA_INTENT_KEY\u0026#34;) @staticmethod def backend_url() -\u0026gt; str: return os.getenv(\u0026#34;BACKEND_API_URL\u0026#34;, \u0026#34;https://api.yourdomain.com\u0026#34;).rstrip(\u0026#34;/\u0026#34;) Booking the intent @dataclass(frozen=True, slots=True) class EsewaBookingResult: transaction_uuid: str booking_id: str deeplink: str correlation_id: str @property def composite_id(self) -\u0026gt; str: \u0026#34;\u0026#34;\u0026#34;Compact string suitable for storing in a single DB column.\u0026#34;\u0026#34;\u0026#34; return f\u0026#34;{self.transaction_uuid}:{self.booking_id}:{self.correlation_id}\u0026#34; @classmethod def from_composite(cls, value: str) -\u0026gt; \u0026#34;EsewaBookingResult\u0026#34;: parts = value.split(\u0026#34;:\u0026#34;) if len(parts) \u0026lt; 3: # noqa: PLR2004 raise ValueError(f\u0026#34;Cannot reconstruct EsewaBookingResult from \u0026#39;{value}\u0026#39;\u0026#34;) return cls( transaction_uuid=parts[0], booking_id=parts[1], correlation_id=parts[2], deeplink=\u0026#34;\u0026#34;, # not persisted — only needed at booking time ) def book_payment_intent( *, amount_npr: int, customer_id: str, purpose: str, app_scheme: str = \u0026#34;yourapp\u0026#34;, ) -\u0026gt; EsewaBookingResult: \u0026#34;\u0026#34;\u0026#34; Create a payment intent on eSewa and return the booking result. Args: amount_npr: Amount in Nepalese Rupees (integer). customer_id: An opaque identifier for the customer (never PII). purpose: Human-readable description shown in eSewa UI. app_scheme: Your mobile app\u0026#39;s deep-link URL scheme. Returns: EsewaBookingResult dataclass with all identifiers and the deeplink. Raises: EsewaBookingError: If eSewa returns a non-success response code. requests.HTTPError: If the HTTP request itself fails (4xx/5xx). requests.Timeout: If the request exceeds the timeout threshold. \u0026#34;\u0026#34;\u0026#34; config = EsewaConfig product_code = config.product_code() transaction_uuid = str(uuid.uuid4()) signature = _build_signature( secret=config.secret_key(), fields={ \u0026#34;product_code\u0026#34;: product_code, \u0026#34;amount\u0026#34;: str(amount_npr), \u0026#34;transaction_uuid\u0026#34;: transaction_uuid, }, field_order=BOOKING_SIGNED_FIELDS, ) callback_url = ( f\u0026#34;{config.backend_url()}/api/payments/esewa-intent/callback/\u0026#34; f\u0026#34;?transaction_uuid={transaction_uuid}\u0026#34; ) redirect_url = f\u0026#34;{app_scheme}://payment-callback/?transaction_uuid={transaction_uuid}\u0026#34; payload = { \u0026#34;product_code\u0026#34;: product_code, \u0026#34;amount\u0026#34;: amount_npr, \u0026#34;transaction_uuid\u0026#34;: transaction_uuid, \u0026#34;signed_field_names\u0026#34;: BOOKING_SIGNED_FIELDS, \u0026#34;signature\u0026#34;: signature, \u0026#34;callback_url\u0026#34;: callback_url, \u0026#34;redirect_url\u0026#34;: redirect_url, \u0026#34;properties\u0026#34;: { \u0026#34;customer_id\u0026#34;: customer_id, \u0026#34;remarks\u0026#34;: purpose, }, } logger.info( \u0026#34;Booking eSewa intent\u0026#34;, extra={\u0026#34;transaction_uuid\u0026#34;: transaction_uuid, \u0026#34;amount_npr\u0026#34;: amount_npr}, ) response = _post_to_esewa(config.book_url(), payload) result = response.json() if result.get(\u0026#34;code\u0026#34;) not in {EsewaResponseCode.SUCCESS, EsewaResponseCode.CREATED}: error_msg = result.get(\u0026#34;error_message\u0026#34;) or result.get(\u0026#34;message\u0026#34;) or str(result) raise EsewaBookingError(f\u0026#34;eSewa booking rejected: {error_msg} (raw={result!r})\u0026#34;) data = result[\u0026#34;data\u0026#34;] booking = EsewaBookingResult( transaction_uuid=transaction_uuid, booking_id=data[\u0026#34;booking_id\u0026#34;], deeplink=data[\u0026#34;deeplink\u0026#34;], correlation_id=data[\u0026#34;correlation_id\u0026#34;], ) logger.info( \u0026#34;eSewa intent booked successfully\u0026#34;, extra={\u0026#34;booking_id\u0026#34;: booking.booking_id, \u0026#34;transaction_uuid\u0026#34;: transaction_uuid}, ) return booking Your mobile client receives booking.deeplink and opens it:\n// iOS — Swift guard let url = URL(string: deeplink) else { return } UIApplication.shared.open(url) // Android — Kotlin startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(deeplink))) 5. Step 2 — HMAC-SHA256 Signatures Signatures authenticate both outbound requests (to eSewa) and inbound callbacks (from eSewa). The algorithm is identical in both directions: HMAC-SHA256 over a comma-separated field=value string, Base64-encoded.\ndef _build_signature(secret: str, fields: dict[str, str], field_order: str) -\u0026gt; str: \u0026#34;\u0026#34;\u0026#34; Construct the HMAC-SHA256 / Base64 signature required by eSewa. The message is built from `fields` in the exact order defined by `field_order` (a comma-separated list of field names). Field order is not negotiable — a mismatch will produce a different digest and eSewa will reject the request. Args: secret: The raw ESEWA_INTENT_KEY string (Base64, not decoded). fields: Mapping of field name → string value. field_order: Comma-separated field names defining message construction order. Returns: Base64-encoded HMAC-SHA256 digest. \u0026#34;\u0026#34;\u0026#34; ordered_names = [name.strip() for name in field_order.split(\u0026#34;,\u0026#34;)] message_parts = [] for name in ordered_names: value = fields.get(name) if value is None: raise ValueError(f\u0026#34;Field \u0026#39;{name}\u0026#39; listed in field_order but not present in fields dict.\u0026#34;) message_parts.append(f\u0026#34;{name}={value}\u0026#34;) message = \u0026#34;,\u0026#34;.join(message_parts) digest = hmac.new( secret.encode(\u0026#34;utf-8\u0026#34;), message.encode(\u0026#34;utf-8\u0026#34;), hashlib.sha256, ).digest() return base64.b64encode(digest).decode(\u0026#34;utf-8\u0026#34;) Verifying an inbound callback signature When eSewa POSTs to your callback URL the body looks like:\n{ \u0026#34;transaction_uuid\u0026#34;: \u0026#34;550e8400-e29b-41d4-a716-446655440000\u0026#34;, \u0026#34;booking_id\u0026#34;: \u0026#34;BK-2024-XXXXXXX\u0026#34;, \u0026#34;correlation_id\u0026#34;: \u0026#34;CID-XXXXXXX\u0026#34;, \u0026#34;amount\u0026#34;: \u0026#34;500\u0026#34;, \u0026#34;status\u0026#34;: \u0026#34;SUCCESS\u0026#34;, \u0026#34;signed_field_names\u0026#34;: \u0026#34;transaction_uuid,booking_id,correlation_id,amount,status\u0026#34;, \u0026#34;signature\u0026#34;: \u0026#34;abc123base64==\u0026#34; } def verify_callback_signature(payload: dict) -\u0026gt; bool: \u0026#34;\u0026#34;\u0026#34; Verify the HMAC-SHA256 signature on an inbound eSewa callback payload. Key subtleties: - The `amount` field may arrive as \u0026#34;500.0\u0026#34; even if you sent 500 (integer). It must be normalised to \u0026#34;500\u0026#34; before building the message string. - Use hmac.compare_digest() — never == — to prevent timing-oracle attacks. - Fields are processed in the exact order declared by `signed_field_names`. Returns: True if the signature is valid, False otherwise. Raises: EsewaSignatureError: If required fields (`signature`, `signed_field_names`) are absent from the payload. \u0026#34;\u0026#34;\u0026#34; raw_signature = payload.get(\u0026#34;signature\u0026#34;) field_names = payload.get(\u0026#34;signed_field_names\u0026#34;) if not raw_signature or not field_names: raise EsewaSignatureError( \u0026#34;Callback payload is missing \u0026#39;signature\u0026#39; or \u0026#39;signed_field_names\u0026#39;.\u0026#34; ) message_parts: list[str] = [] for field in (f.strip() for f in field_names.split(\u0026#34;,\u0026#34;)): raw_value = payload.get(field) if raw_value is None: logger.warning(\u0026#34;Signature field \u0026#39;%s\u0026#39; declared but absent in payload.\u0026#34;, field) return False value = _normalise_amount(raw_value) if field == \u0026#34;amount\u0026#34; else str(raw_value) message_parts.append(f\u0026#34;{field}={value}\u0026#34;) message = \u0026#34;,\u0026#34;.join(message_parts) expected = _build_signature( secret=EsewaConfig.secret_key(), fields=dict(zip( [f.strip() for f in field_names.split(\u0026#34;,\u0026#34;)], [p.split(\u0026#34;=\u0026#34;, 1)[1] for p in message_parts], )), field_order=field_names, ) valid = hmac.compare_digest(raw_signature, expected) if not valid: logger.warning( \u0026#34;eSewa signature mismatch.\u0026#34;, extra={\u0026#34;message\u0026#34;: message, \u0026#34;received\u0026#34;: raw_signature}, ) return valid def _normalise_amount(value: str | int | float) -\u0026gt; str: \u0026#34;\u0026#34;\u0026#34; Normalise an amount value to a plain integer string. eSewa may send amount as \u0026#34;500.0\u0026#34; in callback payloads even when the booking was made with integer 500. Both representations must produce the same signature message byte string. \u0026#34;\u0026#34;\u0026#34; try: parsed = float(value) return str(int(parsed)) if parsed.is_integer() else str(parsed) except (TypeError, ValueError): return str(value) [!CAUTION] Never use == for signature comparison. Python\u0026rsquo;s == on strings short-circuits on the first differing byte, leaking timing information an attacker can exploit to forge signatures. hmac.compare_digest() runs in constant time regardless of where the strings diverge.\n[!WARNING] Do not decode the ESEWA_INTENT_KEY from Base64 before passing it to the HMAC function. The key is used as the raw string secret. Decoding it will produce the wrong digest on every request.\n6. Step 3 — Handling the Callback After the user confirms or cancels in the eSewa app, eSewa POSTs to your callback_url. Your endpoint must be:\nPublicly reachable over HTTPS (not localhost, not an internal VPC address). Unauthenticated — eSewa does not send any auth headers. Fast — acknowledge with 200 OK before doing heavy work. esewa/views.py from __future__ import annotations import logging from django.views.decorators.csrf import csrf_exempt from rest_framework import status from rest_framework.decorators import api_view, authentication_classes, permission_classes from rest_framework.permissions import AllowAny from rest_framework.request import Request from rest_framework.response import Response from .exceptions import EsewaSignatureError from .service import verify_callback_signature, resolve_payment_status logger = logging.getLogger(\u0026#34;esewa.views\u0026#34;) @api_view([\u0026#34;POST\u0026#34;]) @authentication_classes([]) # eSewa does not send auth credentials @permission_classes([AllowAny]) # public webhook receiver @csrf_exempt # webhook — no browser session involved def esewa_intent_callback_view(request: Request) -\u0026gt; Response: \u0026#34;\u0026#34;\u0026#34; Webhook receiver for eSewa Intent payment outcomes. eSewa POSTs here after the user completes or cancels payment. We verify the HMAC signature before doing anything with the payload, then delegate to the service layer for status resolution and fulfilment. Query param: transaction_uuid — appended to callback_url at booking time so we can locate the transaction even before parsing the body. \u0026#34;\u0026#34;\u0026#34; payload = request.data logger.info( \u0026#34;eSewa callback received\u0026#34;, extra={\u0026#34;query_params\u0026#34;: dict(request.GET), \u0026#34;payload_keys\u0026#34;: list(payload.keys())}, ) try: if not verify_callback_signature(payload): return Response( {\u0026#34;detail\u0026#34;: \u0026#34;Signature verification failed.\u0026#34;}, status=status.HTTP_400_BAD_REQUEST, ) except EsewaSignatureError as exc: logger.warning(\u0026#34;Malformed eSewa callback: %s\u0026#34;, exc) return Response({\u0026#34;detail\u0026#34;: str(exc)}, status=status.HTTP_400_BAD_REQUEST) result, http_status = resolve_payment_status( correlation_id=payload.get(\u0026#34;correlation_id\u0026#34;), transaction_uuid=request.GET.get(\u0026#34;transaction_uuid\u0026#34;), ) return Response(result, status=http_status) @api_view([\u0026#34;GET\u0026#34;]) @permission_classes([AllowAny]) def esewa_intent_redirect_view(request: Request) -\u0026gt; Response: \u0026#34;\u0026#34;\u0026#34; Mobile-side status polling endpoint. Called by the mobile app\u0026#39;s deep-link handler when the user returns from the eSewa app. Acts as a fallback for cases where the server-side callback was not delivered (e.g. network issue, IP not whitelisted). Query params: correlation_id — from the eSewa deep-link redirect parameters. transaction_uuid — from the original booking. \u0026#34;\u0026#34;\u0026#34; logger.info( \u0026#34;eSewa redirect poll\u0026#34;, extra={ \u0026#34;correlation_id\u0026#34;: request.GET.get(\u0026#34;correlation_id\u0026#34;), \u0026#34;transaction_uuid\u0026#34;: request.GET.get(\u0026#34;transaction_uuid\u0026#34;), }, ) result, http_status = resolve_payment_status( correlation_id=request.GET.get(\u0026#34;correlation_id\u0026#34;), transaction_uuid=request.GET.get(\u0026#34;transaction_uuid\u0026#34;), ) return Response(result, status=http_status) 7. Step 4 — Server-Side Status Verification [!IMPORTANT] Always verify payment status server-side via the eSewa status API. Do not mark a transaction as complete based solely on the callback body — the callback can be spoofed or replayed. The status API call is the authoritative source of truth.\ndef _check_payment_status(booking_id: str, correlation_id: str) -\u0026gt; EsewaPaymentStatus: \u0026#34;\u0026#34;\u0026#34; Query the eSewa Intent status API and return the canonical payment status. Args: booking_id: From the original booking result. correlation_id: From the original booking result. Returns: EsewaPaymentStatus enum member. Raises: EsewaStatusCheckError: If the API returns a non-IP-200 response code. requests.HTTPError: On 4xx/5xx HTTP errors. requests.Timeout: If the request exceeds the timeout threshold. \u0026#34;\u0026#34;\u0026#34; product_code = EsewaConfig.product_code() signature = _build_signature( secret=EsewaConfig.secret_key(), fields={ \u0026#34;booking_id\u0026#34;: booking_id, \u0026#34;product_code\u0026#34;: product_code, \u0026#34;correlation_id\u0026#34;: correlation_id, }, field_order=STATUS_SIGNED_FIELDS, ) payload = { \u0026#34;booking_id\u0026#34;: booking_id, \u0026#34;product_code\u0026#34;: product_code, \u0026#34;correlation_id\u0026#34;: correlation_id, \u0026#34;signed_field_names\u0026#34;: STATUS_SIGNED_FIELDS, \u0026#34;signature\u0026#34;: signature, } logger.debug( \u0026#34;Calling eSewa status API\u0026#34;, extra={\u0026#34;booking_id\u0026#34;: booking_id, \u0026#34;correlation_id\u0026#34;: correlation_id}, ) response = _post_to_esewa(EsewaConfig.status_url(), payload) result = response.json() if result.get(\u0026#34;code\u0026#34;) != EsewaResponseCode.SUCCESS: raise EsewaStatusCheckError( f\u0026#34;eSewa status API returned code={result.get(\u0026#39;code\u0026#39;)!r}. \u0026#34; f\u0026#34;Full response: {result!r}\u0026#34; ) raw_status = result[\u0026#34;data\u0026#34;][\u0026#34;status\u0026#34;] try: return EsewaPaymentStatus(raw_status) except ValueError: logger.error(\u0026#34;Unrecognised eSewa payment status: %s\u0026#34;, raw_status) return EsewaPaymentStatus.PENDING def resolve_payment_status( *, correlation_id: str | None, transaction_uuid: str | None, ) -\u0026gt; tuple[dict, int]: \u0026#34;\u0026#34;\u0026#34; Core orchestration: locate the transaction, verify its status with eSewa, apply fulfilment logic, and return a response tuple. This function is called by both the server-side callback view and the mobile-side redirect polling view — ensuring both paths share identical business logic. Returns: A (response_dict, http_status_code) tuple. \u0026#34;\u0026#34;\u0026#34; if not correlation_id and not transaction_uuid: return {\u0026#34;detail\u0026#34;: \u0026#34;Missing correlation_id and transaction_uuid.\u0026#34;}, 400 transaction, is_subscription = _find_transaction( correlation_id=correlation_id, transaction_uuid=transaction_uuid, ) if transaction is None: logger.warning( \u0026#34;Transaction not found\u0026#34;, extra={\u0026#34;correlation_id\u0026#34;: correlation_id, \u0026#34;transaction_uuid\u0026#34;: transaction_uuid}, ) return {\u0026#34;detail\u0026#34;: \u0026#34;Transaction not found.\u0026#34;}, 404 # ── Idempotency guard ──────────────────────────────────────────────────── # If this transaction was already approved by a prior callback delivery, # acknowledge success without re-running fulfilment logic. if _is_already_approved(transaction, is_subscription): logger.info(\u0026#34;Transaction already approved — returning cached success.\u0026#34;) return {\u0026#34;detail\u0026#34;: \u0026#34;Payment already confirmed.\u0026#34;}, 200 # ── Reconstruct booking identifiers ───────────────────────────────────── raw_id = _get_raw_id(transaction, is_subscription) try: booking_result = EsewaBookingResult.from_composite(raw_id) except ValueError: logger.error(\u0026#34;Could not reconstruct booking identifiers from \u0026#39;%s\u0026#39;\u0026#34;, raw_id) return {\u0026#34;detail\u0026#34;: \u0026#34;Transaction data is malformed.\u0026#34;}, 500 # ── Verify with eSewa ──────────────────────────────────────────────────── try: payment_status = _check_payment_status( booking_id=booking_result.booking_id, correlation_id=correlation_id or booking_result.correlation_id, ) except (EsewaStatusCheckError, HTTPError, Timeout) as exc: logger.exception(\u0026#34;eSewa status check failed: %s\u0026#34;, exc) return {\u0026#34;detail\u0026#34;: \u0026#34;Could not verify payment status. Please try again.\u0026#34;}, 502 # ── Act on status ──────────────────────────────────────────────────────── if payment_status is EsewaPaymentStatus.SUCCESS: _mark_approved(transaction, is_subscription) _run_fulfilment(transaction, is_subscription) logger.info( \u0026#34;Transaction approved\u0026#34;, extra={\u0026#34;transaction\u0026#34;: str(transaction), \u0026#34;is_subscription\u0026#34;: is_subscription}, ) return {\u0026#34;detail\u0026#34;: \u0026#34;Payment confirmed.\u0026#34;}, 200 if payment_status in {EsewaPaymentStatus.FAILED, EsewaPaymentStatus.CANCELED}: _mark_failed(transaction, is_subscription) return {\u0026#34;detail\u0026#34;: f\u0026#34;Payment {payment_status.value.lower()}.\u0026#34;}, 400 return {\u0026#34;detail\u0026#34;: f\u0026#34;Payment status is {payment_status.value}.\u0026#34;}, 202 Shared HTTP helper def _post_to_esewa(url: str, payload: dict) -\u0026gt; Response: \u0026#34;\u0026#34;\u0026#34; POST JSON to an eSewa API endpoint with consistent timeout and error handling. Raises: requests.HTTPError: On 4xx/5xx responses. requests.Timeout: If no response within _ESEWA_REQUEST_TIMEOUT seconds. \u0026#34;\u0026#34;\u0026#34; try: response = requests.post( url, json=payload, headers={\u0026#34;Content-Type\u0026#34;: \u0026#34;application/json\u0026#34;}, timeout=_ESEWA_REQUEST_TIMEOUT, ) response.raise_for_status() return response except Timeout: logger.error(\u0026#34;eSewa API timed out after %ds — URL: %s\u0026#34;, _ESEWA_REQUEST_TIMEOUT, url) raise except HTTPError as exc: logger.error( \u0026#34;eSewa API returned HTTP %s — URL: %s — Body: %s\u0026#34;, exc.response.status_code, url, exc.response.text[:500], ) raise 8. Step 5 — Django Routing # payment_management/urls.py from django.urls import path from payment_management.views.esewa_views import ( esewa_intent_callback_view, esewa_intent_redirect_view, ) app_name = \u0026#34;payment_management\u0026#34; urlpatterns = [ # Server-side webhook — called by eSewa after payment path( \u0026#34;esewa-intent/callback/\u0026#34;, esewa_intent_callback_view, name=\u0026#34;esewa_intent_callback\u0026#34;, ), # Mobile-side polling — called by your app on return from eSewa path( \u0026#34;esewa-intent/redirect/\u0026#34;, esewa_intent_redirect_view, name=\u0026#34;esewa_intent_redirect\u0026#34;, ), ] # project/urls.py urlpatterns = [ ... path(\u0026#34;api/payments/\u0026#34;, include(\u0026#34;payment_management.urls\u0026#34;, namespace=\u0026#34;payment_management\u0026#34;)), ] Your callback URL at runtime:\nhttps://api.yourdomain.com/api/payments/esewa-intent/callback/?transaction_uuid=\u0026lt;uuid\u0026gt; Django settings (proxy-aware) # settings.py ALLOWED_HOSTS = [\u0026#34;api.yourdomain.com\u0026#34;] # Required if behind nginx / AWS ALB — lets Django resolve https:// correctly SECURE_PROXY_SSL_HEADER = (\u0026#34;HTTP_X_FORWARDED_PROTO\u0026#34;, \u0026#34;https\u0026#34;) USE_X_FORWARDED_HOST = True 9. The Bug: Silent Callback Failures in Production This section is the reason we wrote this post.\nThe symptom After deploying to production, payments appeared to complete successfully on the user\u0026rsquo;s side — the eSewa app showed \u0026ldquo;Payment Successful\u0026rdquo; — but our backend never received the callback. Transactions sat in pending indefinitely.\nProduction logs from our callback endpoint: [nothing] Manual curl to the same endpoint: HTTP 200 OK ←← endpoint is alive and reachable The debugging timeline Check Result Callback endpoint responds to manual POST ✅ Works nginx access log — any request from eSewa IPs ❌ Zero hits Firewall — port 443 open to public ✅ Open callback_url in booking payload — correct domain ✅ Correct SSL certificate — valid, no errors ✅ Valid Sandbox environment — callbacks arriving ✅ Works The divergence between sandbox (working) and production (silent) was the key signal. Everything on our infrastructure was correct.\nRoot cause We contacted the eSewa merchant support team and asked them to inspect their callback delivery logs for our domain.\nTheir response: our production server\u0026rsquo;s IP address was not present in eSewa\u0026rsquo;s outbound callback allowlist.\neSewa\u0026rsquo;s callback dispatcher restricts which destination IPs it will attempt to deliver to. This allowlist is not documented in any public API reference. Our sandbox environment shared an IP that was already on the list. Our production server\u0026rsquo;s IP was not.\nThe fix # Run this on your production server to find your outbound IP curl -s https://api.ipify.org # Cross-check curl -s https://ifconfig.me Provide this IP to the eSewa merchant support team — via email or their merchant portal — and ask them to whitelist it for callback delivery. In our case, the turnaround was same-day.\nOnce whitelisted, callbacks began arriving immediately without any code changes.\n[!IMPORTANT] If your eSewa callback endpoint never receives requests in production but works perfectly in sandbox, assume IP whitelisting first. Contact eSewa support before spending time investigating your own infrastructure — there is nothing to fix on your end.\nThe failsafe: mobile-side polling Because server-side callbacks can fail silently for many reasons (IP not whitelisted, transient network issues, deployment restarts), always implement a client-side fallback:\n1. User is returned to your app via redirect_url (deep-link) 2. Mobile app immediately calls: GET /api/payments/esewa-intent/redirect/?transaction_uuid=\u0026lt;uuid\u0026gt; 3. Backend calls eSewa status API → returns authoritative result 4. App renders success or failure screen Both the callback endpoint and the redirect endpoint route through the same resolve_payment_status() function, so business logic is never duplicated and idempotency is guaranteed by the same guard clause.\n10. Integration Checklist Before going live ESEWA_INTENT_KEY is the raw Base64 string — pass it as-is to HMAC, never decode it. amount is an integer in NPR in the booking payload — no floats, no decimals. Message string field order matches signed_field_names exactly — wrong order = wrong digest. amount normalisation in signature verification: \u0026quot;500.0\u0026quot; → \u0026quot;500\u0026quot;. Callback view is @csrf_exempt with @permission_classes([AllowAny]). callback_url is a public HTTPS URL — not localhost, not a private IP. redirect_url is your mobile app deep-link scheme (yourapp://...). Contact eSewa and confirm your production server\u0026rsquo;s outbound IP is whitelisted. Implement idempotency — re-processing an already-approved transaction must be a no-op. Always re-verify status via the status API after receiving a callback. Store all three identifiers: transaction_uuid, booking_id, correlation_id. Mobile app polls your redirect endpoint as a fallback when returning from eSewa. Signature comparison uses hmac.compare_digest() — never ==. eSewa API response codes Code Meaning IP-200 Success IP-201 Intent created (success for /book) anything else Failure — inspect error_message field Payment status values Value Meaning SUCCESS Payment confirmed — fulfil the order FAILED Payment failed — notify user CANCELED User cancelled — allow retry PENDING Not yet resolved — poll again later ","permalink":"http://www.rishavdahal.com.np/blogs/esewa-intent-api-v2-django/","summary":"A complete production engineering guide to integrating eSewa Intent API v2 in Django, covering HMAC-SHA256 signatures, silent callback failures, and verification.","title":"Integrating eSewa Intent API v2 in a Django Backend"},{"content":"Getting Google AdSense approval in 2026 is less about perfect traffic and more about proving your site is a high-quality, professional resource. Approval standards are strict, so following a clear checklist helps reduce the chance of Low Value Content or Policy Violation rejection.\n1) Essential Pages (Trust Signals) Before applying, make sure these pages are visible in your header or footer. Without them, your site can look incomplete or untrustworthy.\nPrivacy Policy: Explain how you handle user data, cookies, and analytics. About Us: Clearly describe who you are and what value your site provides. Contact Us: Add a working contact form or professional email address. Terms and Conditions: Optional, but strongly recommended for professionalism. 2) Content Quality (Most Common Rejection Area) Google’s standards prioritize genuinely helpful content.\nQuantity: Aim for around 15–20 high-quality posts before applying. Length: Keep most posts in the 800–1,200+ word range. Originality: Avoid generic AI fluff. If you use AI for research, add your own insights, examples, and experience. Niche Focus: Stick to one clear topic to build topical authority. Formatting: Use proper H1, H2, and H3 structure, bullets, and original images. 3) Technical \u0026amp; User Experience If the site is hard to use, approval chances drop.\nCustom Domain: Prefer your own domain (.com, .org, etc.). Mobile Friendly: Use a responsive theme and test on mobile screens. Navigation: Keep menus clean and remove broken or incomplete pages. Speed: Improve load time with image optimization and caching. SSL/HTTPS: Ensure your site is fully secure. 4) Traffic \u0026amp; Indexing You don’t need huge traffic, but your site should show real activity.\nGoogle Search Console: Submit your domain and XML sitemap. Indexing Check: Confirm key pages are indexed and discoverable. Organic Visits: Even modest real search traffic helps signal usefulness. Avoid Fake Traffic: Never use bots or traffic-buying schemes. 5) Prohibited Content (Instant Rejection Risks) Make sure your site does not include:\nAdult or sexually explicit content. Pirated or copyrighted material. Hate speech or illegal activity promotion. Thin pages with very little useful text. If You Get “Low Value Content” Rejection Usually this means content is too short, too generic, or too similar to what already exists online.\nTry this before reapplying:\nPublish 4–6 deeper articles (around 1,200–1,500+ words). Add unique visuals, examples, and practical insights. Improve internal linking and page structure. Wait about 2 weeks, then reapply. ","permalink":"http://www.rishavdahal.com.np/blogs/google-adsense-approval-checklist-2026/","summary":"A practical AdSense approval checklist to avoid low-value content and policy rejection issues in 2026.","title":"Google AdSense Approval Checklist for 2026"},{"content":"By accessing this website, you agree to these terms.\nUse of Content Content on this site is for informational and educational purposes. Unless otherwise stated, text and media are owned by the site owner. You may reference content with proper attribution and a link to the source page. Prohibited Use You agree not to:\nUse this website for unlawful purposes. Attempt unauthorized access to any part of the site or its infrastructure. Reproduce content in bulk without permission. External Links This website may include links to third-party resources. We are not responsible for the availability, accuracy, or practices of those external sites.\nDisclaimer Information is provided \u0026ldquo;as is\u0026rdquo; without warranties of any kind. While content is prepared carefully, we do not guarantee absolute completeness or accuracy.\nLimitation of Liability To the maximum extent permitted by law, the site owner is not liable for any indirect or consequential loss from use of this website.\nChanges to Terms These terms may be updated at any time. Continued use of the website indicates acceptance of the updated terms.\nContact For questions regarding these terms, contact:\nworkwithrisaav@gmail.com ","permalink":"http://www.rishavdahal.com.np/terms-and-conditions/","summary":"\u003cp\u003eBy accessing this website, you agree to these terms.\u003c/p\u003e\n\u003ch2 id=\"use-of-content\"\u003eUse of Content\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eContent on this site is for informational and educational purposes.\u003c/li\u003e\n\u003cli\u003eUnless otherwise stated, text and media are owned by the site owner.\u003c/li\u003e\n\u003cli\u003eYou may reference content with proper attribution and a link to the source page.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"prohibited-use\"\u003eProhibited Use\u003c/h2\u003e\n\u003cp\u003eYou agree not to:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eUse this website for unlawful purposes.\u003c/li\u003e\n\u003cli\u003eAttempt unauthorized access to any part of the site or its infrastructure.\u003c/li\u003e\n\u003cli\u003eReproduce content in bulk without permission.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"external-links\"\u003eExternal Links\u003c/h2\u003e\n\u003cp\u003eThis website may include links to third-party resources. We are not responsible for the availability, accuracy, or practices of those external sites.\u003c/p\u003e","title":"Terms and Conditions"},{"content":" Available for projects \u0026amp; tech lead roles 📍 Kathmandu, Nepal \u0026bull; 🕒 Local Time: --:--:-- (UTC+5:45) ⚡ Response commitment: \u0026lt; 24 hours Whether you’re looking to build an MVP from scratch, scale your backend microservices, automate cloud infrastructure, or discuss engineering architecture—my inbox is always open. Direct Email workwithrisaav@gmail.com\nBest for detailed project briefs, architectural inquiries, or formal communication. Send Email ↗ Copy Address LinkedIn Professional Networking\nConnect for professional updates, recommendations, and direct messaging. Connect on LinkedIn ↗ GitHub @rishav-dahal\nExplore active repositories, open-source work, and software engineering experiments. View GitHub Profile ↗ Technical Advisory Architecture \u0026amp; Cloud\nConsulting on backend API design (Django/FastAPI/Go), Docker pipelines, or cloud deployments. Compose Inquiry ↓ Quick Message Composer Draft your message below to instantly launch your preferred email app or copy a formatted briefing to your clipboard.\nYour Name / Organization Your Email Address Inquiry Topic Startup MVP / Greenfield Project Backend Architecture \u0026amp; API Design (Django / FastAPI / Go) DevOps \u0026amp; Cloud Infrastructure (Docker / CI/CD / AWS / GCP) Machine Learning / Vision Integration (OpenCV / NLP) Technical Advisory / Consulting General Inquiry / Other Project Scope or Message Send via Email Client ↗ Copy Draft to Clipboard 📋 Draft copied to clipboard! ✓ 🔒 Runs 100% locally in your browser. No third-party data tracking or intermediate servers. ","permalink":"http://www.rishavdahal.com.np/contact/","summary":"\u003cdiv class=\"contact-hub\"\u003e\n\u003cdiv class=\"contact-status-bar\"\u003e\n\u003cdiv class=\"status-pill\"\u003e\n\u003cspan class=\"status-dot\"\u003e\u003c/span\u003e\n\u003cspan\u003eAvailable for projects \u0026amp; tech lead roles\u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv class=\"status-pill\"\u003e\n\u003cspan\u003e📍 Kathmandu, Nepal\u003c/span\u003e\n\u003cspan class=\"footer-divider\"\u003e\u0026bull;\u003c/span\u003e\n\u003cspan\u003e🕒 Local Time: \u003cstrong id=\"npt-time\"\u003e--:--:--\u003c/strong\u003e (UTC+5:45)\u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv class=\"status-pill\"\u003e\n\u003cspan\u003e⚡ Response commitment: \u003cstrong\u003e\u0026lt; 24 hours\u003c/strong\u003e\u003c/span\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp style=\"font-size: 1.12rem; line-height: 1.65; color: var(--secondary); margin-bottom: 2rem;\"\u003e\nWhether you’re looking to build an MVP from scratch, scale your backend microservices, automate cloud infrastructure, or discuss engineering architecture—my inbox is always open.\n\u003c/p\u003e\n\u003cdiv class=\"contact-cards-grid\"\u003e\n\u003cdiv class=\"contact-card\"\u003e\n\u003cdiv\u003e\n\u003cdiv class=\"contact-card-header\"\u003e\n\u003cdiv class=\"contact-card-icon\"\u003e\n\u003csvg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e\n\u003crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u003e\u003c/rect\u003e\n\u003cpath d=\"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\u003c/div\u003e\n\u003cdiv class=\"contact-card-info\"\u003e\n\u003ch3\u003eDirect Email\u003c/h3\u003e\n\u003cp\u003eworkwithrisaav@gmail.com\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp style=\"font-size: 0.9rem; color: var(--secondary); margin-bottom: 1.25rem;\"\u003e\nBest for detailed project briefs, architectural inquiries, or formal communication.\n\u003c/p\u003e","title":"Contact"},{"content":"This Privacy Policy explains how information is handled on this website.\nWho We Are This website is operated by Rishav Dahal and publishes blogs, project updates, and portfolio content.\nInformation We Collect This site may collect limited data through:\nBasic analytics tools (such as page views, device/browser type, and referral source). Cookies used for site functionality and performance measurement. Direct communication when you contact us by email. We do not sell personal data.\nCookies and Advertising This website may display ads served by Google AdSense or other advertising partners.\nThird-party vendors, including Google, may use cookies to serve ads based on prior visits to this and other websites. Google may use the DoubleClick cookie to show personalized ads where applicable. You can manage ad personalization in Google Ad Settings. How We Use Information Collected information is used to:\nImprove website performance and content quality. Understand which content is most helpful. Respond to inquiries sent via email. Third-Party Services This site may link to third-party websites and services. Their privacy practices are governed by their own policies.\nData Security Reasonable technical measures are used to protect this website, but no method of internet transmission is 100% secure.\nChildren’s Privacy This website is not intentionally directed to children under 13, and we do not knowingly collect personal information from children.\nUpdates to This Policy This policy may be updated from time to time. Any updates will be posted on this page.\nContact For privacy questions, contact:\nEmail: workwithrisaav@gmail.com ","permalink":"http://www.rishavdahal.com.np/privacy-policy/","summary":"\u003cp\u003eThis Privacy Policy explains how information is handled on this website.\u003c/p\u003e\n\u003ch2 id=\"who-we-are\"\u003eWho We Are\u003c/h2\u003e\n\u003cp\u003eThis website is operated by \u003cstrong\u003eRishav Dahal\u003c/strong\u003e and publishes blogs, project updates, and portfolio content.\u003c/p\u003e\n\u003ch2 id=\"information-we-collect\"\u003eInformation We Collect\u003c/h2\u003e\n\u003cp\u003eThis site may collect limited data through:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eBasic analytics tools (such as page views, device/browser type, and referral source).\u003c/li\u003e\n\u003cli\u003eCookies used for site functionality and performance measurement.\u003c/li\u003e\n\u003cli\u003eDirect communication when you contact us by email.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eWe do not sell personal data.\u003c/p\u003e","title":"Privacy Policy"},{"content":"A fast, searchable open-access digital archive documenting 700+ verified Nepali surnames, gotras, ancestral lineages, and kuldevtas. Designed to preserve cultural heritage and demographic clarity through clean, accessible web software and automated data pipelines.\n🚀 Live Interactive Web App: Launch Cast in Nepal Archive (/cast-in-nepal/) ↗\n🌟 Overview Nepal\u0026rsquo;s social and cultural landscape comprises a rich tapestry of ethnic groups, clans, gotras, and ancestral traditions. However, finding accurate, structured information about surname origins, gotras, and associated kuldevtas has traditionally been scattered across fragmented physical texts or unverified forum posts.\nCast in Nepal solves this by providing:\nA single centralized, verified repository of 700+ Nepali surnames. Detailed mappings of Gotra (गोत्र) and Kuldevta (कुलदेवता) for each clan. Cultural lineage, ethnic community affiliation, and regional roots. An instantaneous, zero-latency client-side search experience. 🚀 Key Features 1. Instant Real-Time Search \u0026amp; Filtering Search across English transliterations and Nepali Devanagari script. Instant filtering by surname, gotra, caste category, or kuldevta with sub-millisecond response time. Responsive card and table views optimized for mobile and desktop screens. 2. Verified Genealogical \u0026amp; Demographic Data Detailed breakdown of 700+ verified surnames categorized across communities. Lineage associations tracing historical clan branches and ancestral ties. Clear distinction of gotra traditions and clan deity (कुलदेवता) observances. 3. Automated Dataset Engineering Data ingestion and transformation pipelines powered by Python (build_dataset.py). Automated data normalization, duplicate reconciliation, and JSON schema validation. SEO-optimized architecture with automated sitemaps and structured metadata. 🛠️ Tech Stack \u0026amp; Architecture Component Technology Purpose Frontend Vanilla HTML5, CSS3, JavaScript Lightweight, zero-dependency, ultra-fast client-side indexing Data Processing Python Dataset compilation, cleansing, and schema validation (build_dataset.py) Data Format JSON / Static Dataset Fast client-side querying without requiring an expensive backend server SEO \u0026amp; Indexing Semantic HTML, XML Sitemap Maximum discoverability on search engines 🌐 Explore the Project 🔗 Live Website: Launch Cast in Nepal Web App ↗ 🐙 Source Code: GitHub Repository ","permalink":"http://www.rishavdahal.com.np/projects/cast-in-nepal/","summary":"Comprehensive open archive of 700+ verified Nepali surnames, gotras, ethnic affiliations, and kuldevtas with instant client-side search.","title":"Cast in Nepal — Surnames, Gotra \u0026 Kuldevta Archive"},{"content":"A real-time, collaborative task management system built from scratch using C++ socket programming. This project demonstrates fundamental network programming concepts by implementing a TCP-based client-server architecture where multiple users can manage shared tasks with priority levels across a Local Area Network.\nOverview Modern collaboration tools often abstract away the underlying network mechanisms. This project takes a lower-level approach, implementing direct TCP socket communication to create a functional todo list manager that:\nHandles multiple concurrent client connections Maintains a shared task list across all connected users Implements priority-based task organization Provides real-time updates to all clients Demonstrates core network programming principles This is an excellent educational project for understanding how networked applications work at the socket level.\nKey Features 1. Real-Time TCP Communication Direct implementation of Berkeley/POSIX socket APIs:\nServer listens on a specified port Accepts multiple client connections Maintains persistent connections for real-time updates Handles graceful disconnection and reconnection 2. Multi-Client Architecture Concurrent client handling using:\nThread-based approach for each client connection Shared task storage accessible by all clients Thread-safe operations on shared data structures Synchronization mechanisms to prevent race conditions 3. Priority-Based Task Management Implements priority queue data structure:\nTasks organized by priority levels (High, Medium, Low) Due date tracking for deadline management Automatic sorting by priority and date Status tracking (Pending, Completed) 4. Command-Line Interface Clean terminal-based interaction:\nUser authentication with usernames Intuitive command system Clear task display and formatting Real-time feedback on operations Technical Architecture Server Component (server.cpp) Responsibilities:\nListen for incoming client connections Spawn threads for each connected client Manage shared task data structure Broadcast task updates to all clients Handle client disconnections gracefully Key Implementation Details:\n// Server socket setup int server_fd = socket(AF_INET, SOCK_STREAM, 0); bind(server_fd, (struct sockaddr*)\u0026amp;address, sizeof(address)); listen(server_fd, MAX_CLIENTS); // Accept clients in loop while (true) { int client_socket = accept(server_fd, ...); pthread_create(\u0026amp;thread_id, NULL, handle_client, \u0026amp;client_socket); } Client Component (client.cpp) Responsibilities:\nConnect to server Send user commands to server Receive and display task updates Handle user input and command parsing Key Implementation Details:\n// Client connection int sock = socket(AF_INET, SOCK_STREAM, 0); connect(sock, (struct sockaddr*)\u0026amp;serv_addr, sizeof(serv_addr)); // Separate threads for sending and receiving pthread_create(\u0026amp;send_thread, NULL, send_messages, \u0026amp;sock); pthread_create(\u0026amp;recv_thread, NULL, receive_messages, \u0026amp;sock); Supported Commands ADD priority|YYYY-MM-DD|description Adds a new task with specified parameters.\nExample:\n\u0026gt; ADD high|2026-03-01|Complete network programming assignment Task added successfully! Parameters:\npriority: high, medium, or low YYYY-MM-DD: Due date in ISO format description: Task details (space-separated) LIST Displays all active (pending) tasks sorted by priority.\nExample Output:\n=== Current Tasks === [1] [HIGH] 2026-03-01: Complete network programming assignment [2] [MEDIUM] 2026-03-05: Review C++ socket documentation [3] [LOW] 2026-03-10: Refactor client connection code LIST COMPLETED Shows all completed tasks.\nLIST ALL Displays both pending and completed tasks.\nMARK \u0026lt;index\u0026gt; Marks a task as completed by its index number.\nExample:\n\u0026gt; MARK 1 Task #1 marked as completed. exit Disconnects from server and exits the client application.\nTechnology Stack Programming Language C++: Core application logic Standard C++11: Modern C++ features Networking POSIX Sockets (Berkeley Sockets): Cross-platform socket API TCP/IP Protocol: Reliable connection-oriented communication Concurrency POSIX Threads (pthread): Multi-threading support Mutex Locks: Thread synchronization Platform Support Linux/UNIX: Primary development platform macOS: POSIX-compliant support Windows: With WSL (Windows Subsystem for Linux) or MinGW Installation \u0026amp; Usage Prerequisites C++ compiler (g++ recommended) UNIX-based system or WSL on Windows Basic terminal/console access Compilation For Linux/macOS:\n# Clone the repository git clone https://github.com/rishav-dahal/LAN-TODO.git cd LAN-TODO # Compile server g++ server.cpp -o server -pthread # Compile client g++ client.cpp -o client -pthread For Windows:\n# Using MinGW or WSL g++ -std=c++11 server.cpp -o server.exe -lws2_32 g++ -std=c++11 client.cpp -o client.exe -lws2_32 Running the Application Step 1: Start the Server\n./server # Server output: # [SERVER] Listening on port 8080... # [SERVER] Waiting for connections... Step 2: Connect Clients (in separate terminals)\n./client # Connected to server. # Enter your username: alice # # Commands: # - ADD priority|YYYY-MM-DD|description # - LIST # - LIST COMPLETED # - LIST ALL # - MARK \u0026lt;index\u0026gt; # - exit # # \u0026gt; Welcome, alice! Step 3: Interact with Task Manager\n\u0026gt; ADD high|2026-03-15|Finish project documentation \u0026gt; LIST \u0026gt; MARK 1 \u0026gt; exit Network Programming Concepts Demonstrated 1. Socket Creation and Configuration Understanding file descriptors, address families (AF_INET), and socket types (SOCK_STREAM for TCP).\n2. Binding and Listening Server binds to a specific port and listens for incoming connections.\n3. Connection Establishment Three-way TCP handshake managed by operating system, application handles accept().\n4. Concurrent Client Handling Using threads to handle multiple clients simultaneously without blocking.\n5. Data Serialization Converting data structures to byte streams for network transmission.\n6. Error Handling Proper handling of network errors, timeouts, and disconnections.\n7. Resource Management Closing sockets, cleaning up threads, releasing resources properly.\nUse Cases Educational Projects Learn socket programming fundamentals Understand client-server architecture Practice multi-threaded programming Study network protocol implementation Team Collaboration Small team task tracking on local network Lab or office environment task management Real-time collaboration without internet dependency Prototyping Foundation for building networked applications Testing ground for network security concepts Base for implementing custom protocols Challenges \u0026amp; Solutions Challenge 1: Thread Synchronization Problem: Multiple clients accessing shared task list simultaneously.\nSolution:\nImplemented mutex locks around critical sections Used RAII pattern for automatic lock management Designed lock-free read operations where possible Challenge 2: Client Disconnection Handling Problem: Server crashes when client disconnects unexpectedly.\nSolution:\nAdded signal handling for broken pipe (SIGPIPE) Implemented heartbeat mechanism Graceful cleanup of disconnected client resources Challenge 3: Input Buffer Management Problem: Reading variable-length messages from TCP stream.\nSolution:\nImplemented message framing with delimiters Used circular buffers for efficient memory use Added message validation before processing Project Contributors Developed collaboratively by:\nRishav Dahal - Server architecture, network protocol design Bishnu Timilsena - Client implementation, command parsing Madhav - Testing, documentation, bug fixes Future Enhancements Persistent Storage: Save tasks to database or file User Authentication: Password-protected user accounts Encryption: TLS/SSL for secure communication GUI Client: Graphical interface using Qt or similar Task Notifications: Reminders for approaching deadlines Task Assignment: Assign specific tasks to specific users Web Interface: Browser-based client access Mobile App: Android/iOS client applications Technical Learnings This project provided deep understanding of:\nLow-level socket programming in C++ TCP/IP protocol mechanics Multi-threaded server design patterns Network byte ordering (endianness) Concurrency and synchronization Command-line tool development Cross-platform compatibility considerations Conclusion The LAN-Based Shared Todo Manager demonstrates core network programming principles through a practical application. By implementing TCP socket communication from scratch in C++, this project provides valuable insights into how networked applications work at the fundamental level.\nWhile modern applications often use higher-level frameworks, understanding these low-level concepts is crucial for any serious software engineer working on networked systems, distributed applications, or performance-critical software.\nGitHub Repository: LAN-TODO\nDocumentation: Includes project proposal, final report, and presentation materials\nTopics: Network Programming, C++, Socket Programming, TCP/IP, Multi-threading\n","permalink":"http://www.rishavdahal.com.np/projects/lan-todo-manager/","summary":"Real-time collaborative task manager using TCP socket programming in C++","title":"LAN-Based Shared Todo Manager"},{"content":"A sophisticated web-based application that revolutionizes search experiences by using Natural Language Processing (NLP) to refine user queries intelligently. By analyzing intent, context, and semantics, this system transforms vague or poorly structured queries into precise search terms that deliver more relevant results.\nOverview Traditional keyword-based search engines often fail to capture the nuanced intent behind user queries. This Modular Query Refinement system addresses these limitations by:\nAnalyzing the semantic meaning and context of user queries Identifying user intent beyond literal keywords Refining queries based on personalized context Generating more precise and relevant search results Adapting to various domains from e-commerce to academic research The project demonstrates how NLP techniques can bridge the gap between how users naturally express their needs and how search engines process queries.\nKey Features 1. NLP-Powered Query Analysis Uses advanced natural language processing to understand query semantics:\nIntent Detection: Identifies whether the user wants information, comparison, purchase options, or troubleshooting Entity Recognition: Extracts key entities, concepts, and relationships from queries Contextual Understanding: Considers previous queries and user behavior Synonym Expansion: Suggests related terms to broaden or narrow search scope 2. Modular Architecture Flexible, component-based design that allows:\nEasy integration with existing search systems Customization for specific domains or industries Independent scaling of processing modules Simple addition of new refinement techniques Reusable components across different applications 3. Personalized Adjustments Tailors query refinements based on:\nUser search history and preferences Domain-specific context and terminology Geographic and cultural relevance Time-sensitive information needs User expertise level 4. Cross-Domain Utility Applicable across various sectors:\nE-commerce: Product discovery and comparison Academic Research: Scientific literature search Legal: Case law and document retrieval Healthcare: Medical information lookup News \u0026amp; Media: Content discovery Technical Architecture System Components Frontend Layer (Next.js + Vue.js) Modern, responsive user interface Real-time query refinement suggestions Interactive feedback mechanism Search result visualization Backend Layer (Django) RESTful API architecture Query processing pipeline NLP model integration User session management Database Layer (PostgreSQL) Query logs and analytics User preferences and history Domain-specific knowledge bases Refinement pattern storage Deployment Infrastructure Docker: Containerized microservices Nginx: Reverse proxy and load balancing Production-ready: Scalable deployment configuration How It Works Query Refinement Pipeline Input Reception\nUser submits search query through interface System captures query text and context Preprocessing\nTokenization and normalization Stopword removal Spell checking and correction Intent Analysis\nQuery classification (informational, transactional, navigational) User goal identification Context extraction Semantic Processing\nWord embedding generation Concept extraction Relationship mapping Refinement Generation\nQuery expansion or narrowing suggestions Alternative phrasings Related concept suggestions Result Enhancement\nRefined query passed to search engine Results ranked by relevance Personalized result filtering Technology Stack Frontend Next.js: React-based framework for server-side rendering Vue.js: Progressive JavaScript framework TypeScript: Type-safe JavaScript development HTML/CSS: Semantic markup and responsive styling Backend Django: High-level Python web framework Django REST Framework: API development Python: Core processing logic NLP \u0026amp; ML NLTK: Natural Language Toolkit spaCy: Industrial-strength NLP Transformers: Pretrained language models Word2Vec/GloVe: Word embeddings Infrastructure Docker: Container orchestration Nginx: Web server and reverse proxy PostgreSQL: Relational database Redis: Caching layer (optional) Use Cases E-commerce Search Problem: User searches \u0026ldquo;comfortable running shoes under 100\u0026rdquo;\nRefinement Process:\nExtracts: product type (shoes), activity (running), price constraint (\u0026lt;$100), quality attribute (comfortable) Expands: adds related terms like \u0026ldquo;athletic footwear\u0026rdquo;, \u0026ldquo;jogging shoes\u0026rdquo; Filters: price range, customer ratings, comfort features Result: More targeted product listings matching all criteria\nAcademic Research Problem: Student searches \u0026ldquo;AI ethics problems\u0026rdquo;\nRefinement Process:\nDisambiguates: \u0026ldquo;AI\u0026rdquo; = Artificial Intelligence Expands context: moral implications, bias, privacy concerns Suggests: related concepts like algorithmic fairness, transparency Adds temporal filter: recent publications Result: Relevant research papers and articles on AI ethics\nMedical Information Problem: Patient searches \u0026ldquo;headache behind eyes\u0026rdquo;\nRefinement Process:\nMedical entity recognition: symptom = headache, location = retro-orbital Context: potential conditions (migraine, sinus, eye strain) Safety filter: emphasizes professional medical advice Removes jargon: simplifies medical terminology Result: Informative health articles with appropriate disclaimers\nInstallation \u0026amp; Setup Prerequisites Docker and Docker Compose Node.js 16+ (for frontend development) Python 3.8+ (for backend development) PostgreSQL 13+ Quick Start with Docker # Clone the repository git clone https://github.com/rishav-dahal/Modular-Query-Refinement.git cd Modular-Query-Refinement # Start development environment docker-compose -f docker-compose.dev.yml up --build # Access the application # Frontend: http://localhost:3000 # Backend API: http://localhost:8000 Manual Setup # Backend setup cd backend python -m venv venv source venv/bin/activate pip install -r requirements.txt python manage.py migrate python manage.py runserver # Frontend setup cd MQR-frontend npm install npm run dev Project Contributors This project was developed as a collaborative effort:\nRishav Dahal - Backend architecture, NLP implementation Sandhya Gautam - Frontend development, UI/UX design Dhiraj Poudel - Database design, API development Binit Bikram KC - DevOps, deployment, testing Challenges \u0026amp; Solutions Challenge 1: Query Ambiguity Problem: Same query can have multiple interpretations.\nSolution:\nImplemented context-aware disambiguation Used user history to infer likely intent Provided multiple refinement options for user selection Challenge 2: Real-Time Performance Problem: NLP processing can be computationally expensive.\nSolution:\nCached common query patterns Used lightweight models for initial processing Implemented async processing for complex refinements Optimized database queries with indexing Challenge 3: Domain Adaptation Problem: Different domains require different refinement strategies.\nSolution:\nModular plugin architecture for domain-specific rules Configurable refinement pipelines Domain-specific knowledge base integration Transfer learning from general to specific domains Future Enhancements Multilingual Support: Query refinement in multiple languages Voice Interface: Voice-to-text query input Advanced Personalization: Deep learning-based user modeling Explainable AI: Show why specific refinements were suggested A/B Testing Framework: Evaluate refinement effectiveness Mobile Applications: Native iOS and Android apps Browser Extension: In-browser query enhancement Technical Learnings This project provided hands-on experience with:\nNatural language processing and understanding Full-stack web development (Next.js, Django) Microservices architecture with Docker Database optimization for text search RESTful API design patterns Frontend state management Production deployment with Nginx Collaborative software development Conclusion Modular Query Refinement demonstrates how NLP can transform search experiences by understanding user intent beyond literal keywords. The modular architecture makes it adaptable to various domains, while the sophisticated processing pipeline ensures accurate and relevant results.\nThis system represents a meaningful step toward more intelligent, context-aware search experiences that better serve user needs across e-commerce, research, healthcare, and other domains requiring precise information retrieval.\nGitHub Repository: Modular-Query-Refinement\nLive Demo: Modular-Query-Refinement\nContact: For inquiries, reach out at contact@rishavdahal.com.np\nLicense: Proprietary - Contributor License Agreement (CLA)\n","permalink":"http://www.rishavdahal.com.np/projects/modular-query-refinement/","summary":"NLP-powered search enhancement system for improving query accuracy and relevance","title":"Modular Query Refinement"},{"content":"A practical academic tool designed to simplify the process of calculating Semester Grade Point Average (SGPA) and Cumulative Grade Point Average (CGPA) for students. This software eliminates manual calculation errors and provides instant, accurate grade point calculations across multiple semesters.\nOverview For students tracking academic performance, manually calculating SGPA and CGPA can be tedious and error-prone. This CGPA Calculator automates the entire process with:\nIntuitive course entry interface Support for both Bachelor\u0026rsquo;s and Master\u0026rsquo;s level grade scales Automatic SGPA calculation per semester Cumulative CGPA across all semesters Clean, web-based interface Key Features 1. Flexible Course Entry Add any number of courses per semester Input course name, credit hours, and grade Edit or remove courses before calculation Save semester data for future reference 2. Dual Grade Scale Support Bachelor Level Grading:\nA (4.00) - Excellent A- (3.70) B+ (3.30) B (3.00) - Good B- (2.70) C+ (2.30) C (2.00) - Fair C- (1.70) D+ (1.30) D (1.00) - Minimum Requirement F (0.00) - Fail Master Level Grading:\nA (4.00) - Excellent A- (3.70) B+ (3.30) - Good B (3.00) - Fair B- (2.70) C+ (2.30) C (2.00) - Minimum Requirement F (0.00) - Fail 3. Automatic Calculations SGPA calculated instantly per semester CGPA automatically updated across all semesters Weighted average based on credit hours Precision to two decimal places 4. User-Friendly Interface Built with modern web technologies:\nClean, responsive design Easy data entry and modification Clear result display Mobile-friendly layout How to Use Step 1: Enter Number of Courses Input the total number of courses you took in the semester.\nStep 2: Fill Course Details For each course, provide:\nCourse Name: e.g., \u0026ldquo;Advanced Mathematics\u0026rdquo; Credit Hours: Typically 1-4 credits Grade Obtained: Select from A, A-, B+, B, etc. Step 3: Calculate SGPA Click the \u0026ldquo;Calculate SGPA\u0026rdquo; button to get your semester grade point average.\nStep 4: Add More Semesters Repeat the process for each semester. The software automatically calculates your overall CGPA.\nExample Calculation Let\u0026rsquo;s calculate SGPA for a semester with 5 courses:\nCourse Name Credit Hours Grade Grade Point Math 3 A- 3.70 English 3 B+ 3.30 Physics 4 A 4.00 Economics 3 B- 2.70 Project 2 C+ 2.30 Calculation Formula:\nSGPA = Σ(Credit Hours × Grade Point) / Σ(Credit Hours) SGPA = (3×3.70 + 3×3.30 + 4×4.00 + 3×2.70 + 2×2.30) / (3+3+4+3+2) = (11.10 + 9.90 + 16.00 + 8.10 + 4.60) / 15 = 49.70 / 15 = 3.31 Your SGPA for this semester would be 3.31.\nTechnical Architecture Technology Stack Python: Backend logic and calculations HTML/CSS: Frontend interface JavaScript: Dynamic form handling Flask/Django: (If web app) Server framework Core Algorithm def calculate_sgpa(courses): total_points = 0 total_credits = 0 for course in courses: grade_point = get_grade_point(course.grade) total_points += course.credits * grade_point total_credits += course.credits return round(total_points / total_credits, 2) def calculate_cgpa(semesters): all_points = sum(sem.sgpa * sem.total_credits for sem in semesters) all_credits = sum(sem.total_credits for sem in semesters) return round(all_points / all_credits, 2) Use Cases For Students Track academic performance semester by semester Plan course selection to maintain desired CGPA Prepare for scholarship applications Monitor progress toward graduation requirements For Academic Advisors Quick CGPA verification Student performance counseling Academic standing determination Graduation eligibility checks For Institutions Automated grade processing Academic report generation Consistent calculation standards Reduced administrative workload Installation For End Users Access the web application directly or download the standalone version.\nFor Developers # Clone the repository git clone https://github.com/rishav-dahal/CGPA-Calculator.git cd CGPA-Calculator # Create virtual environment python -m venv venv source ./venv/bin/activate # Windows: .\\venv\\Scripts\\activate # Install dependencies pip install -r requirements.txt # Run the application python app.py Key Benefits Accuracy Eliminates human calculation errors with automated, tested algorithms.\nSpeed Instant results compared to manual calculation.\nConvenience Calculate anytime, anywhere with web access.\nRecord Keeping Save and review past semester calculations.\nGrade Planning Experiment with different grade scenarios to plan future performance.\nFuture Enhancements Grade Prediction: Suggest required grades to achieve target CGPA Transcript Generation: Export professional academic transcripts Mobile App: Native Android/iOS applications Cloud Sync: Save data across devices Multiple Institutions: Support various university grading systems Visualization: Charts showing grade trends over time Export Options: PDF, CSV, Excel format exports Technical Learnings This project provided experience with:\nFrontend development with modern HTML/CSS Form validation and dynamic UI updates Mathematical algorithm implementation Data persistence and storage Responsive web design principles User experience optimization Conclusion The CGPA Calculator simplifies academic grade tracking for students across all levels of education. By automating the calculation process and supporting multiple grading systems, it provides a reliable tool for academic performance management.\nWhether you\u0026rsquo;re a student tracking your progress, an advisor helping students, or an institution processing grades, this calculator offers a fast, accurate, and user-friendly solution.\nGitHub Repository: CGPA-Calculator\nLicense: Open source under project license terms.\n","permalink":"http://www.rishavdahal.com.np/projects/cgpa-calculator/","summary":"Academic grade management tool for calculating SGPA and CGPA across semesters","title":"CGPA Calculator"},{"content":"Hi, I\u0026rsquo;m Rishav Dahal 👋 I am the Chief Technology Officer (CTO) at DLPlatforms Pty Ltd and a Backend \u0026amp; DevOps Engineer based in Kathmandu, Nepal. I specialize in architecting resilient cloud infrastructure, high-concurrency APIs, and distributed backend systems.\nWhether scaling production platforms across DLSurf, FitHisaab, and Automyc, automating multi-cloud container pipelines, or publishing peer-reviewed research on unsupervised query refinement (ICICSET 2025), I build software engineered for resilience, performance, and automated scale.\n💼 Leadership \u0026amp; Professional Roles Chief Technology Officer (CTO) — DLPlatforms Pty Ltd Leading technical strategy, cloud infrastructure, and backend engineering across three core products: DLSurf: High-performance digital content delivery and monetization platform. FitHisaab: Comprehensive mobile health, gym, and diet tracking ecosystem. Automyc: Intelligent workflow automation and system integration platform. Architecting high-availability API stacks, distributed caching layers, and automated multi-cloud deployment pipelines. 🎓 Education \u0026amp; Academic Research B.E. in Software Engineering — Nepal College of Information Technology (NCIT) Affiliated with Pokhara University, Nepal. Focus areas: Distributed Systems, Database Management, Algorithms, and Software Architecture. Published Research Paper (ICICSET 2025): \u0026ldquo;Query Refinement using Latent Dirichlet Allocation\u0026rdquo;\nPresented and published at the International Conference on Innovation in Computing, Science, Engineering and Technology (ICICSET 2025). Investigated unsupervised query expansion techniques, utilizing Latent Dirichlet Allocation (LDA) topic modeling and semantic coherence evaluation to improve search relevance in unstructured text corpora. 🏆 Honors, Awards \u0026amp; Hackathons 🥇 Winner — Hult Prize NCIT 2023 (Team Weaver) Championed a circular-economy enterprise model aimed at reducing textile waste by upcycling used clothing into sustainable modular fashion. 🏆 Winner — Hacademia (1st Edition) at King\u0026rsquo;s College Developed and won with Sikshya, an NLP-based lecture summarization and learning assistant platform. 🎨 Best UI/UX Award — Sagarmatha Hackathon (Sagarmatha Tech Fest) Won the Best UI/UX award with Swasthya, a centralized healthcare record management and accessible medical platform. 🛠️ Core Technical Specializations Backend Architecture \u0026amp; Distributed Systems: Architecting modular microservices and high-concurrency APIs using Python (Django, FastAPI) and Go (Fiber) with asynchronous task queues (Celery, Redis). DevOps, CI/CD \u0026amp; Cloud Infrastructure: Containerizing production workloads with Docker, configuring automated delivery pipelines with GitHub Actions, and managing cloud infrastructure across AWS, GCP, Linux (Ubuntu/Debian), and reverse proxies (Nginx). Information Retrieval \u0026amp; Document Processing: Researching unsupervised query expansion and topic modeling (LDA) along with image processing pipelines using OpenCV and Tesseract OCR. Data Engineering \u0026amp; Performance Optimization: Relational database modeling, query tuning, connection pooling, and multi-tier caching with PostgreSQL, MySQL, and Redis. 🧰 Technical Toolbox Domain Technologies \u0026amp; Frameworks Programming Languages Python, Go (Golang), Java, C, C++, SQL, JavaScript Backend Frameworks Django, Django REST Framework, FastAPI, Go Fiber, Flask DevOps \u0026amp; Cloud Docker, Docker Compose, GitHub Actions, Linux Administration, Nginx, AWS, GCP, Cloudflare Databases \u0026amp; Caching PostgreSQL, Redis, MySQL, SQLite Algorithms \u0026amp; Vision Latent Dirichlet Allocation (LDA), NLP, OpenCV, Tesseract OCR, Scikit-learn Tooling \u0026amp; Workflows Git / GitHub, Postman, Linux Shell / Bash, Figma, Jira 🚀 Featured Engineering Projects \u0026amp; Deep Dives Cast in Nepal — Surnames \u0026amp; Gotra Archive: Open-access digital archive documenting 700+ verified Nepali surnames, gotras, ethnic affiliations, and kuldevtas with instant real-time search (Project Details). eSewa Intent Payment Gateway Integration: Authored a complete production architectural guide for implementing eSewa v2 Intent APIs in Django with HMAC-SHA256 cryptography and webhook failover mechanisms. Modular Query Refinement (NLP \u0026amp; Semantic Search): Researched and developed an unsupervised query enhancement engine leveraging LDA topic coherence. OCR Code Compiler 2.0: Developed an end-to-end computer vision pipeline for extracting source code from document images with perspective correction and sandboxed code execution. Face Recognition Attendance System: Built an automated attendance tracking pipeline using deep face embeddings and OpenCV real-time video streams. 🤝 Strategic Collaboration \u0026amp; Consulting I actively collaborate with startups, tech companies, and engineering teams looking for technical leadership in:\nTaking scalable software MVPs from idea to production-grade deployment. Modernizing backend architectures, decoupling legacy monolithic apps, and scaling APIs. Establishing automated CI/CD pipelines, Docker containerization, and cloud infrastructure. Designing high-reliability distributed databases and caching strategies. 📬 Connect With Me 💼 LinkedIn: linkedin.com/in/risaavdahal 🐙 GitHub: github.com/rishav-dahal 📧 Direct Email: workwithrisaav@gmail.com 💬 Interactive Contact Hub: Get in touch on the Contact Page ","permalink":"http://www.rishavdahal.com.np/about/","summary":"\u003ch2 id=\"hi-im-rishav-dahal-\"\u003eHi, I\u0026rsquo;m Rishav Dahal 👋\u003c/h2\u003e\n\u003cp\u003eI am the \u003cstrong\u003eChief Technology Officer (CTO)\u003c/strong\u003e at \u003cstrong\u003eDLPlatforms Pty Ltd\u003c/strong\u003e and a \u003cstrong\u003eBackend \u0026amp; DevOps Engineer\u003c/strong\u003e based in Kathmandu, Nepal. I specialize in architecting resilient cloud infrastructure, high-concurrency APIs, and distributed backend systems.\u003c/p\u003e\n\u003cp\u003eWhether scaling production platforms across \u003cstrong\u003eDLSurf\u003c/strong\u003e, \u003cstrong\u003eFitHisaab\u003c/strong\u003e, and \u003cstrong\u003eAutomyc\u003c/strong\u003e, automating multi-cloud container pipelines, or publishing peer-reviewed research on unsupervised query refinement (ICICSET 2025), I build software engineered for \u003cstrong\u003eresilience, performance, and automated scale\u003c/strong\u003e.\u003c/p\u003e","title":"About Me"},{"content":"An automated attendance tracking system that uses computer vision and machine learning to recognize faces in real-time and log attendance automatically. Built with Python, OpenCV, and the Face Recognition API, this project demonstrates practical application of AI in solving everyday problems.\nOverview Manual attendance systems are time-consuming and prone to errors. This Face Recognition Attendance System automates the entire process by:\nDetecting faces in real-time using a webcam Recognizing registered individuals with high accuracy Logging attendance automatically with timestamps Providing a web interface for face registration and attendance management The system is deployed at attendance-system-blue.vercel.app for easy access.\nKey Features 1. Real-Time Face Detection Uses Haar Cascade classifiers for fast and accurate face detection from webcam streams. The cascade approach provides:\nLow computational overhead Reliable detection even in varying lighting conditions Fast processing suitable for real-time applications 2. Face Recognition with Face Recognition API Implements the face_recognition library built on top of dlib\u0026rsquo;s state-of-the-art face recognition model:\n128-dimensional face encoding for each person Euclidean distance-based matching High accuracy with minimal false positives 3. KNN Classification Uses K-Nearest Neighbors (KNN) algorithm for final classification:\nFast prediction time Works well with small to medium datasets Easy to update with new faces No complex training required 4. Web Interface Built with Flask framework providing:\nFace registration portal for new users Live attendance monitoring Attendance history and logs Simple, intuitive UI for administrators Technical Architecture Detection Pipeline Frame Capture: OpenCV captures video frames from webcam Preprocessing: Converts to grayscale and applies histogram equalization Face Detection: Haar Cascade detects faces in frame Feature Extraction: Face Recognition API generates 128-D encodings Classification: KNN model predicts identity Logging: Attendance recorded with timestamp Technology Stack Python 3: Core programming language OpenCV: Real-time computer vision operations face_recognition: Face encoding and recognition NumPy: Numerical computations and array operations Flask: Web framework for user interface scikit-learn: KNN classifier implementation How It Works Registration Phase User enters their name in the web interface System captures multiple face images from different angles Face encodings are generated and stored KNN model is retrained with new data Attendance Phase System continuously captures frames from webcam Detected faces are encoded in real-time KNN classifier predicts the person\u0026rsquo;s identity First detection of the day logs attendance with timestamp Results displayed on web interface Installation \u0026amp; Setup Requirements Python 3.6+ Webcam or camera access Modern web browser Quick Start # Clone the repository git clone https://github.com/rishav-dahal/Face-Recognition-Based-Attendance-System.git cd Face-Recognition-Based-Attendance-System # Create virtual environment python -m venv venv source ./venv/bin/activate # On Windows: .\\venv\\Scripts\\activate # Install dependencies pip install -r requirements.txt # Train initial model python train.py # Start the server python app.py # Access the application # Open browser and go to localhost:8000 Use Cases Educational Institutions Automated attendance in classrooms Reduces manual attendance time Eliminates proxy attendance Generates attendance reports automatically Corporate Offices Employee check-in/check-out tracking Access control integration Time and attendance management Visitor registration Events \u0026amp; Conferences Participant tracking Session attendance monitoring Registration desk automation Challenges \u0026amp; Solutions Challenge 1: Varying Lighting Conditions Problem: Face recognition accuracy drops in poor or inconsistent lighting.\nSolution:\nApplied histogram equalization for consistent brightness Captured multiple training images under different lighting Used adaptive threshold techniques Challenge 2: Multiple Faces in Frame Problem: Detecting and recognizing multiple people simultaneously.\nSolution:\nImplemented batch processing for multiple face encodings Used spatial filtering to prevent duplicate logging Optimized detection region to reduce false positives Challenge 3: Real-Time Performance Problem: Balancing accuracy with processing speed.\nSolution:\nUsed Haar Cascade for fast initial detection Processed every 3rd frame for recognition (optimization) Implemented multithreading for parallel processing Future Enhancements Deep Learning Models: Integrate CNN-based face recognition for improved accuracy Mobile App: Develop Android/iOS apps for mobile attendance Cloud Storage: Store attendance data in cloud databases Anti-Spoofing: Add liveness detection to prevent photo-based fraud Analytics Dashboard: Visualize attendance patterns and statistics Multi-Camera Support: Handle multiple camera feeds simultaneously Technical Learnings This project provided hands-on experience with:\nComputer vision fundamentals and OpenCV Machine learning classification with KNN Real-time video processing optimization Flask web application development Model serialization and deployment Face recognition algorithms and their limitations Conclusion The Face Recognition Attendance System demonstrates how AI and computer vision can automate manual processes effectively. By combining Haar Cascade detection, Face Recognition API, and KNN classification, the system achieves a balance between accuracy, speed, and ease of use.\nThis project serves as a foundation for more advanced attendance systems and can be extended with additional features like liveness detection, cloud integration, and mobile support.\nGitHub Repository: Face-Recognition-Based-Attendance-System\nLive Demo: attendance-system-blue.vercel.app\n","permalink":"http://www.rishavdahal.com.np/projects/face-recognition-attendance-system/","summary":"Real-time attendance tracking using face recognition with KNN classification","title":"Face Recognition Attendance System"},{"content":"From Fridge to Feast How I used Gemini, RAG, and structured outputs to solve my \u0026ldquo;What\u0026rsquo;s for dinner?\u0026rdquo; problem.\nThe Problem: Kitchen Chaos We’ve all been there: staring into a fridge full of random ingredients—half a bell pepper, leftover chicken, wilting spinach—and wondering, “What can I even make with this?” Recipe websites rarely help because they assume you have pantry staples or time for grocery runs.\nMy Goal: Build an AI-powered tool that: Identifies ingredients from text or fridge photos. Generates creative recipes using only those ingredients. Suggests similar recipes for inspiration. Enter Generative AI—specifically, Google’s Gemini. How Generative AI Solves This I combined three key Gen AI capabilities:\nImage Understanding: “What’s in my fridge?”\nUsing Gemini’s vision model, the app analyzes uploaded photos to detect ingredients. For example:\ndef analyze_image(image_path): model = genai.GenerativeModel(\u0026#39;gemini-pro-vision\u0026#39;) response = model.generate_content([\u0026#34;List ingredients in this image:\u0026#34;, Image.open(image_path)]) return response.text # Detects: \u0026#34;chicken, rice, broccoli, soy sauce\u0026#34; This lets users snap a fridge photo instead of typing ingredients—perfect for rushed weeknights.\nStructured Outputs: Recipes in JSON\nRecipes need consistency. Using few-shot prompting, I guided Gemini to output recipes in a JSON format:\nprompt = f\u0026#34;\u0026#34;\u0026#34; Generate a recipe using ONLY: {ingredients}. Use this JSON structure: {examples} # Few-shot examples here \u0026#34;\u0026#34;\u0026#34; # Example Output: { \u0026#34;name\u0026#34;: \u0026#34;Garlic Butter Chicken \u0026amp; Rice\u0026#34;, \u0026#34;ingredients\u0026#34;: [\u0026#34;chicken\u0026#34;, \u0026#34;rice\u0026#34;, \u0026#34;garlic\u0026#34;], \u0026#34;steps\u0026#34;: [\u0026#34;Sauté garlic\u0026#34;, \u0026#34;Cook chicken\u0026#34;, \u0026#34;Mix with rice\u0026#34;] } Structured outputs make recipes machine-readable for apps or meal planners.\nRetrieval-Augmented Generation (RAG): “Inspire Me!”\nTo avoid repetitive recipes, I stored 500+ recipes in a ChromaDB vector database. When a user asks for \u0026ldquo;quick dinners,\u0026rdquo; RAG retrieves similar recipes to inspire Gemini:\ndef retrieve_similar_recipes(query): results = db.query(query_texts=[query], n_results=2) return results[\u0026#34;documents\u0026#34;] # Returns: [\u0026#34;Teriyaki Chicken Bowl\u0026#34;, \u0026#34;Vegetable Fried Rice\u0026#34;] This ensures variety while keeping ingredients relevant.\nChallenges \u0026amp; Limitations Vision Model Accuracy: Gemini sometimes misidentifies uncommon ingredients (e.g., “kale” vs. “spinach”). Unrealistic Combinations: The AI occasionally suggests odd pairings (like “broccoli smoothies”). Scalability: ChromaDB works for small datasets, but larger apps need managed vector databases. Future Ideas Dietary Filters: “Make this gluten-free!” Smart Fridge Integration: Auto-detect expiring ingredients. Taste Profiles: “Generate a spicy version.” Try It Yourself Explore the full code in my Kaggle Notebook. Next time you’re stuck with random ingredients, let Gen AI handle the meal planning!\nConclusion Generative AI isn’t just for chatbots—it can solve everyday problems like kitchen chaos. By combining vision models, structured outputs, and RAG, we can build tools that are both creative and practical. What will you cook up next?\n","permalink":"http://www.rishavdahal.com.np/blogs/building-a-recipe-generator-with-generative-ai/","summary":"How I built an AI-powered tool to generate recipes from fridge photos using Gemini, RAG, and structured outputs.","title":"Building a Recipe Generator with Generative AI"},{"content":"Optical Character Recognition (OCR) is revolutionizing the way we digitize and process documents. Whether it’s converting a scanned document into editable text or extracting data from receipts, OCR technology is increasingly relied upon across industries. However, one of the main challenges faced by OCR systems is their accuracy, especially when dealing with noisy or poorly scanned images. In this blog, I’ll walk you through the techniques I used to improve OCR accuracy on document images by leveraging pre-processing methods.\nThe Problem: Noisy Images and OCR Inaccuracy OCR systems are not perfect and can misinterpret characters in documents that are noisy or of low quality. Factors like poor resolution, background noise, skewed text, or faded characters can all hinder the OCR’s performance. A common scenario is a document image where the text is barely legible, or noise distorts the text, making it difficult for the OCR engine to read the characters correctly.\nImagine scanning an old document with faded text or even taking a photo of a document with uneven lighting – both of these can degrade the quality of OCR results. In my experience, this is where pre-processing steps become critical.\nWhy Pre-Processing Matters Pre-processing involves manipulating the image to improve its quality before feeding it into the OCR system. These techniques clean up the image, reduce noise, and enhance text readability, making it easier for OCR engines to recognize characters. The result is more accurate text extraction, fewer errors, and better overall performance.\nLet’s take a closer look at the steps involved in pre-processing.\nPre-Processing Techniques for OCR 1. Denoising One of the first challenges in OCR is noise. Background noise can come in the form of specks, smudges, or unwanted pixels. To handle this, I applied denoising methods like Gaussian blur and median filtering. These techniques help to smooth out noise while preserving the structure of the text.\nExample:\nBefore: The text is distorted by smudges and noise. After: The text becomes much clearer, making it easier for OCR to recognize the characters. 2. Thresholding and Binarization Thresholding is the process of converting an image to black and white. It helps in increasing the contrast between text and background, making the text stand out more clearly. In cases where the document is faded, binarization helps distinguish between foreground text and the background.\n3. Deskewing OCR performance can drop significantly if the text in the image is not aligned properly. When documents are scanned at an angle, the skewed text becomes difficult for OCR systems to interpret. To solve this, deskewing algorithms detect the angle of the text and straighten the document, improving accuracy.\n4. Morphological Operations These operations (such as dilation and erosion) can further enhance the visibility of characters. Dilation helps to expand the white regions of the text, making characters more readable, while erosion shrinks the noisy background, leaving only the important text visible.\nResults of Using Pre-Processing The results were promising. By applying these techniques, I was able to achieve better OCR accuracy on a variety of document types. Images that once produced errors or failed to be recognized by OCR systems were now processed with a higher degree of precision.\nBelow, you can see an example of how these pre-processing methods work in practice.\nComparison: Noisy vs. Cleaned-Up Image Here is a visual comparison showing a document with noisy text on the left side and a cleaned-up version of the document on the right side. You can see how the pre-processed image is much clearer and better suited for OCR extraction.\nThe cleaned-up version on the right has reduced background noise, sharper characters, and is aligned properly. This makes it much easier for an OCR engine to read and convert the text accurately.\nConclusion: The Impact of Pre-Processing Pre-processing is a vital step in enhancing OCR accuracy. By cleaning the image and preparing it for text extraction, you can reduce errors and improve results. Whether you\u0026rsquo;re working with old documents, receipts, or photographs, applying these pre-processing techniques can significantly boost OCR performance.\nAs OCR technology evolves, I believe that combining advanced pre-processing techniques with machine learning models will continue to improve the accuracy and reliability of document digitization processes, making them even more useful in real-world applications.\n","permalink":"http://www.rishavdahal.com.np/blogs/improving-ocr-accuracy-on-document-images/","summary":"Practical computer vision pre-processing techniques including denoising, thresholding, binarization, and deskewing to dramatically enhance OCR recognition accuracy on real-world document images.","title":"Improving OCR Accuracy on Document Images"},{"content":"Bridging Document Digitization and Code Execution In the world of software development, innovation often lies at the intersection of disparate technologies. OCRcompiler 2.0, hosted on GitHub, is a prime example of this. Combining Optical Character Recognition (OCR) with multi-language code compilation, this project takes document digitization and code execution to a whole new level.\nOverview of OCRcompiler 2.0 OCRcompiler 2.0 is designed to:\nExtract text from scanned or image-based documents using OCR. Parse and compile code written in multiple programming languages such as Python, C, C++, Java, and JavaScript. Provide a seamless interface for users to upload images, process code, and view execution results. This project not only automates tedious tasks like manual text extraction but also allows developers to execute and validate code directly from scanned documents.\nKey Features 1. Advanced OCR Capabilities OCRcompiler 2.0 employs cutting-edge OCR techniques to accurately extract text from images. By integrating tools like Tesseract and OpenCV, the system ensures:\nHigh accuracy in text recognition. Robust preprocessing for noise removal, skew correction, and binarization. Support for various document formats. 2. Multi-Language Code Compilation The project supports five major programming languages:\nPython C C++ Java JavaScript By leveraging appropriate compilers and interpreters, the system ensures efficient parsing, execution, and result generation.\n3. User-Friendly Interface The interface, built with React.js, provides a seamless user experience for uploading documents, reviewing extracted text, and executing code.\n4. Backend Reliability Powered by Django, the backend ensures secure and efficient processing. Features like session management and JWT-based authentication enhance user security.\n5. Deployment-Ready Architecture OCRcompiler 2.0 is built with scalability in mind, making it ready for deployment on platforms like AWS or Heroku.\nTechnical Breakdown OCR Pipeline Image Preprocessing: Techniques like Gaussian blur and thresholding are applied to improve text readability. Text Recognition: Tesseract OCR processes the preprocessed image to extract text. Post-Processing: The raw text is cleaned to remove artifacts and formatted for further use. Code Compilation Process Input Parsing: The extracted text is parsed to identify code blocks. Language Detection: Heuristics determine the programming language. Execution: Code is executed using respective compilers/interpreters, with outputs returned to the user. Applications OCRcompiler 2.0 has a wide range of use cases:\nEducational Tools: Automate the grading of programming assignments submitted as handwritten or scanned documents. Document Digitization: Extract and execute legacy code from physical documents. Research and Development: Process and analyze handwritten algorithm notes. Challenges and Solutions 1. OCR Accuracy Challenge: Ensuring accurate text recognition from noisy or low-quality images. Solution: Implement preprocessing techniques and leverage Tesseract’s adaptive recognition capabilities.\n2. Error Handling in Code Compilation Challenge: Identifying and resolving syntax errors in extracted code. Solution: Developing a robust parsing and error-reporting mechanism.\n3. Browser Caching Issues Challenge: Managing cached JavaScript and CSS files in browsers like Brave. Solution: Adding cache-busting mechanisms to ensure updated files are loaded.\nFuture Scope OCRcompiler 2.0 is a stepping stone toward more advanced systems. Potential enhancements include:\nSupport for Additional Languages: Expanding the compiler to include languages like Ruby or Go. AI-Powered OCR: Integrating machine learning models for improved text recognition accuracy. Cloud Integration: Enabling real-time processing and storage in the cloud. Conclusion OCRcompiler 2.0 is more than just a tool; it’s a bridge between the analog and digital worlds, transforming how we interact with text and code. Whether you’re an educator, a developer, or a researcher, this project offers a glimpse into the future of document processing and automation.\nExplore the project in detail on GitHub. Contributions and feedback are always welcome!\n","permalink":"http://www.rishavdahal.com.np/projects/ocr-code-compiler/","summary":"An intelligent system combining Optical Character Recognition with multi-language code compilation (Python, C, C++, Java, JS) and execution.","title":"OCR Code Compiler"}]