Skip to content

MRThugh/ParsiKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🌟 ParsiKit Library 🌟

Python Version License Author Version Persian English

A production-grade, highly performant, and pure Python software infrastructure for Persian text processing, validation, financial calculations, calendar conversions, graphical text reshaping, developer diagnostics, and sensitive data security.


📖 Overview

ParsiKit (imported as parsikit) is a robust, zero-dependency Python library designed as a full-scale infrastructure for Persian language applications.

With the release of v3.3.0, ParsiKit evolves into a highly advanced developer utility, text-cleansing, and security-centric suite. Alongside its unified procedural API and rich Object-Oriented Domain Model, ParsiKit now introduces bومی (Persian-aware) formatting, visual alignment helpers, text diagnostics, smart classifiers, and sensitive data masking tools designed to make Persian software development reliable, clean, and secure.


🚀 Key Architectural Pillars in v3.3.0

1. Unified Configuration & Thread-Safe Caching (parsikit.config, parsikit.cache)

  • Thread-Safe Caching: Highly repetitive and CPU-bound operations (such as converting large digits to words or parsing database dates) are optimized with an internal thread-safe LRU-like cache.
  • Global Configurations: Easily control default parameters like value-added tax rates, default currency units, or toggle caching on/off dynamically at runtime.

2. Custom Structured Exceptions (parsikit.exceptions)

Never worry about managing generic ValueError or TypeError crashes. ParsiKit ships with a structured exception tree tailored to Iranian standards, making it perfect for Clean Architecture or DDD pipelines.

3. Object-Oriented Domain Models (parsikit.models)

Wrap raw strings in rich domain models like PersianText, NationalCode, MobileNumber, FixedLine, BankCard, Sheba, or VehiclePlate. These models validate inputs upon instantiation, extract rich metadata (like province/city of issue, operators, or bank details), and serialize cleanly.

4. Developer Diagnostics & bومی Formatting (parsikit.dev - New in v3.3.0!)

  • Persian-Aware Visual Padding (pformat & persian_fstring): Standard formatters misalign texts containing Zero-Width Non-Joiners (ZWNJs) or Arabic diacritics. ParsiKit calculates true visual string widths to output cleanly aligned tables and logs, supporting automatic Persian digit conversions.
  • Interactive Text Debugging: Inspect texts for missing ZWNJs, layout issues, or redundant spacings and get immediate corrective actions.

5. Advanced SEO, Sanitization, & Security Suite (New in v3.3.0!)

  • SEO Romanization (slugify): Transliterates mixed or Persian strings into SEO-friendly Finglish slugs, utilizing a built-in common word mapping dictionary.
  • Master Cleansing & Normalization (clean_text / normalize_whitespace): Sanitize multi-line texts by eliminating hidden unicode characters, collapsing redundant whitespace, correcting ZWNJ boundaries, and resolving newline excesses.
  • Smart Data Detection (detect): A unified classifier that parses strings to automatically identify if they represent an Iranian mobile number, national code, card number, Sheba code, email, URL, or IP address.
  • Sensitive Data Masking (mask_*): Instantly scrub logs, API outputs, or admin panel displays by masking middle digits of mobiles, cards, emails, and national codes.

⚙️ Installation

pip install parsikit

Requires Python 3.10+


🛠️ Configuration & Exception Management

1. Global Configurations

import parsikit

# Adjust VAT/Tax rate globally (Default: 0.10)
parsikit.config.default_tax_rate = 0.09

# Adjust global default currency (Default: "toman")
parsikit.config.default_currency = "rial"

# Toggle high-performance computation caching
parsikit.config.enable_cache = True

2. Exception Hierarchy

All specific exceptions inherit from parsikit.exceptions.ValidationError which inherits from ParsiKitError and Python's native ValueError:

import parsikit

try:
    card = parsikit.BankCard("invalid-card-number")
except parsikit.InvalidCardNumberError as e:
    print(f"Card processing failed: {e}")
except parsikit.ValidationError as e:
    print(f"Generic ParsiKit validation error: {e}")

🦄 Native Pydantic v2 & FastAPI Integration

You can declare ParsiKit models directly inside Pydantic schemas or FastAPI route handlers. ParsiKit natively handles data parsing, raises clean structured validation errors on failure, and serializes values cleanly to string:

from fastapi import FastAPI
from pydantic import BaseModel
import parsikit

app = FastAPI()

class UserRegisterSchema(BaseModel):
    fullname: parsikit.PersianText
    national_id: parsikit.NationalCode
    phone: parsikit.MobileNumber
    card: parsikit.BankCard

@app.post("/register")
def register_user(user: UserRegisterSchema):
    # Inputs are already parsed, validated, and normalized!
    print(user.fullname.standardize()) # Normalized chain
    print(user.national_id.location)   # {"province": "تهران", "city": "تهران مرکزی"}
    print(user.phone.to_international()) # "+989123456789"
    
    # Easily serialize everything to dictionary
    return {
        "status": "success",
        "data": {
            "national_id": user.national_id.to_dict(),
            "card_bank": user.card.bank
        }
    }

🚀 Feature Guides & Code Examples

1. Developer Diagnostics Ecosystem (parsikit.dev)

ParsiKit v3.3.0 ships with a highly optimized developer diagnostic suite for printing, inspecting, and managing logs containing Persian data.

Interactive Text Diagnostics

Identify encoding errors, missing semi-spaces, or digit script issues instantly:

import parsikit

# Get detailed dictionary diagnostics
analysis = parsikit.inspect_text("ي كافيه ك کتاب ها ميباشد ۱۲۳")
print(analysis["has_arabic_chars"]) # True
print(analysis["has_zwnj_issues"])  # True
print(analysis["suggestions"])
# Output: [
#   "Replace Arabic letters (ي, ك, ة) with standard Persian equivalents (ی, ک, ه).",
#   "Add proper zero-width non-joiners (ZWNJs) around prefixes/suffixes.",
#   ...
# ]

# Print a beautiful terminal-colored diagnostic report to stdout
parsikit.debug_text("ي كافيه ك کتاب ها ميباشد")

Smart Pretty Printing & Native Container Repr

Standard Python structures escape Persian characters inside containers. ParsiKit fixes this with native-repr representations and colored outputs:

import parsikit

data = {"کاربر": ["امیر", "رضا"], "وضعیت": True}

# Standard python repr: "{'\\u06a9\\u0627\\u0631\\u0628\\u0631': ['\\u0627\\u0645\\u06cc\\u0631', ...]}"
# ParsiKit clean representation:
print(parsikit.persian_repr(data))
# Output: {'کاربر': ['امیر', 'رضا'], 'وضعیت': True}

# Pretty print structured dicts/lists or ParsiKit models with ANSI colors
parsikit.pretty_print(data, title="User Information")

Batch Validation Reports

Validate batches of raw inputs against any ParsiKit domain model and print/return a summary breakdown:

import parsikit

items = ["7730123452", "1111111111", "0010123451", "bad-code"]
report = parsikit.validate_batch(items, parsikit.NationalCode, silent=False)
# Prints a structured validation summary detailing valid/invalid elements and indexes

Raw Persian Logging Setup

Configures Python's stream logger with clean formatting that prints unescaped Persian text:

import parsikit

logger = parsikit.setup_logging("DEBUG")
logger.info("ثبت نام کاربر با موفقیت انجام شد.")

2. Persian-Aware Text Formatting (pformat & persian_fstring)

Standard string formatters align strings based on character length. However, zero-width characters (like ZWNJs) or diacritics occupy character indices while taking up zero visual width, resulting in crooked alignments. ParsiKit resolves this visually.

Clean Padding with Zero-Width Characters

import parsikit

# "کتاب‌‌ها" contains a ZWNJ (character length is 8, but visually occupies 7 slots)
# Standard format '{:<10}' outputs a string with 2 trailing spaces (visual width of 9)
# pformat compensates for the ZWNJ, adding 3 trailing spaces to achieve a visual width of exactly 10 slots:
aligned = parsikit.pformat("{:<10} | تراز شد", "کتاب‌‌ها")
print(aligned) # "کتاب‌‌ها   | تراز شد"

Suffix-Based Digit Conversion

Append :fa or :p to placeholders inside templates to automatically format numbers in Persian script:

import parsikit

# Auto convert numbers to Persian digits and apply standard spacing/grouping
print(parsikit.pformat("هزینه: {:>10,fa} ریال", 1500000))
# Output: "هزینه:  ۱،۵۰۰،۰۰۰ ریال"

Contextual f-string Evaluator

Evaluates standard formatting templates while automatically extracting local/global variables from the caller's frame context:

import parsikit

name = "علی"
price = 12500

# Automatically parses 'name' and 'price' from the surrounding variables scope
formatted = parsikit.persian_fstring("کاربر: {name:<5} | قیمت: {price:fa} تومان")
print(formatted)
# Output: "کاربر: علی   | قیمت: ۱۲۵۰۰ تومان"

3. SEO, Whitespace, & Cleansing Suite

Easily convert mixed Persian scripts into clean components, URLs, and database-safe records.

Finglish SEO Slug Generator

Transliterates mixed or Persian strings into SEO-friendly, clean Finglish slugs:

import parsikit

# Auto maps popular Persian words (like "سلام" -> "salam", "دنیا" -> "donya", "آموزش" -> "amoozesh")
# and transliterates other characters alphabetically
print(parsikit.slugify("آموزش وردپرس به زبان ساده"))
# Output: "amoozesh-wordpress-beh-zaban-sadeh"

print(parsikit.slugify("سلام دنیا 💕"))
# Output: "salam-donya"

Master Text Sanitizer

Removes invisible non-printing unicode characters, collapses extra spaces, fixes ZWNJ boundaries, and converts Arabic characters and English digits:

import parsikit

dirty_text = "ي كافيه ك   کتاب  ها  ميباشد  ۱۱۲۳\n\n\n\nجدید  "
print(parsikit.clean_text(dirty_text))
# Output:
# "ی کافیه ک کتاب‌ها میباشد ۱۱۲۳
# 
# جدید"

Whitespace Normalizer

Normalizes whitespace structures, with an option to preserve single paragraph line breaks or flatten them into a single line:

import parsikit

raw_paragraphs = "خط اول\n\n\n\nخط دوم   با   فاصله\n\nخط سوم"

# Preserves paragraph spacing
print(parsikit.normalize_whitespace(raw_paragraphs, keep_paragraphs=True))
# Output:
# "خط اول
# 
# خط دوم با فاصله
# 
# خط سوم"

# Flattens all line breaks
print(parsikit.normalize_whitespace(raw_paragraphs, keep_paragraphs=False))
# Output: "خط اول خط دوم با فاصله خط سوم"

Bidirectional Digit Script Converter

Convert all numbers in a given raw block of text to Persian or English digits:

import parsikit

text = "شماره تماس ما: 09123456789"
print(parsikit.convert_numbers(text, to="persian"))
# Output: "شماره تماس ما: ۰۹۱۲۳۴۵۶۷۸۹"

print(parsikit.convert_numbers("کد امنیتی: ۱۲۵۰۰", to="english"))
# Output: "کد امنیتی: 12500"

4. Smart Classifiers & Sensitive Data Masking

Implement smart validation pipelines and protect sensitive user logs or profiles from exposure.

Universal Input Identifier (detect)

Automatically parses any string input to categorize its semantic data type:

import parsikit

print(parsikit.detect("09123456789")) # "mobile_number"
print(parsikit.detect("7730123452"))  # "national_code"
print(parsikit.detect("ali@example.com")) # "email"
print(parsikit.detect("192.168.1.1")) # "ip"
print(parsikit.detect("https://google.com")) # "url"
print(parsikit.detect("some general phrase")) # None

Sensitive Data Masking Utilities

Perfect for admin panel fields, user profile previews, and secure database logging:

import parsikit

# Mask Mobile Numbers
print(parsikit.mask_mobile("09123456789"))
# Output: "0912***6789"

# Mask Bank Cards (preserves standard formatted chunks)
print(parsikit.mask_card("6037991122334455", mask_char="X"))
# Output: "6037-99XX-XXXX-4455"

# Mask National Codes (preserves formatted XXX-XXXXXX-X layout)
print(parsikit.mask_national_code("7730123452"))
# Output: "773-****45-2"

# Mask Email usernames proportionally
print(parsikit.mask_email("kamrani.exe@gmail.com"))
# Output: "ka******e@gmail.com"

5. Calendar conversions, Fintech, Reshapers & Old Modules

All standard tools from previous versions remain completely supported.

Astronomical Shamsi Calendar & Time Humanizer

import parsikit
import datetime

# Gregorian to Jalali (Cached for performance)
jy, jm, jd = parsikit.gregorian_to_jalali(2026, 7, 5)
print(parsikit.format_jalali(jy, jm, jd, "YYYY-MM-DD"))
# Output: "1405-04-14"

# Check leap year (Precise astronomical cycle)
print(parsikit.is_jalali_leap(1403)) # True

# Relative Time Humanizer
posted_at = datetime.datetime.now() - datetime.timedelta(hours=3)
print(parsikit.humanize_relative_time(posted_at))
# Output: "۳ ساعت پیش"

Graphical Reshaper (Diacritics-Aware)

import parsikit

# Reshapes connected text for canvas engines with poor RTL support (OpenCV, Pygame, Pillow)
shaped = parsikit.reshape_for_graphics("عَلِیّ", reverse=False)
print(shaped) # "ﻋَﻠِﻲّ"

Cross-Framework GUI Binding (Tkinter / PySide / PyQt)

import parsikit
from PySide6.QtWidgets import QLineEdit, QApplication

app = QApplication([])
card_input = QLineEdit()

# Auto-formats card digits reactive-style as "XXXX-XXXX-XXXX-XXXX" as the user types
parsikit.bind_persian_input(card_input, "card_number")

card_input.show()
app.exec()

🧪 Running Tests

A comprehensive, bug-free unit test suite is included in the project root to guarantee full structural compliance:

python -m unittest test.py
# or
python test.py

👨‍💻 Author

Ali Kamrani


📄 License

This project is licensed under the MIT License. Feel free to use, modify, and distribute it in your commercial or open-source projects.


ParsiKit — Making Persian software development cleaner and more professional. 🚀

About

Persian text standardization, localization & speed optimization.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages