Skip to main content

Modern async/await Python IVR framework for Yemot HaMashiach - Simple as Node.js yemot-router2

Project description

yemot-flow 🚀

גרסה 0.2.18 Python 3.11+ רישיון MIT

ספריית Python מודרנית עם async/await ליצירת מערכות IVR חכמות לימות המשיח

🎯 פשוט כמו Node.js yemot-router2 - כותבים קוד ליניארי עם await, והמנוע מטפל בכל השאר!

חדש בגרסה 0.2.18: תמיכה מלאה ב-async/await עם המשכיות אוטומטית + תיעוד מושלם!


🌟 למה yemot-flow?

@flow.get("")
async def welcome(call: Call):
    # כותבים קוד פשוט ורציף!
    name = await call.read([('text', 'מה השם שלך?')], mode="stt", val_name="name")
    age = await call.read([('text', f'שלום {name}, כמה אתה בן?')], val_name="age", max_digits=2)
    
    call.play_message([('text', f'נעים להכיר {name} בן {age}!')])
    call.hangup()

🚀 תכונות מרכזיות

תכונה פירוט
async/await קוד ליניארי וטבעי כמו ב-Node.js - ללא ניהול מצב ידני
המשכיות אוטומטית המנוע זוכר איפה עצרת וממשיך אחרי כל קלט מהמשתמש
תמיכה מלאה Flask, FastAPI, זיהוי דיבור (STT), הקלטות, כל סוגי הקלטים
פשוט להתקין pip install yemot-flow או uv add yemot-flow - מוכן לשימוש!
מהיר עם uv פיתוח מהיר פי 10 עם uv package manager
דוגמאות רבות מערכת הזמנות, תפריטים מתקדמים, בוט AI ועוד

📦 התקנה מהירה

🐍 עם pip (רגיל)

# התקנה בסיסית
pip install yemot-flow

# עם Flask (מומלץ למתחילים)
pip install yemot-flow flask

# עם FastAPI (לביצועים גבוהים)  
pip install yemot-flow fastapi uvicorn

⚡ עם uv (מומלץ - מהיר יותר!)

# התקן uv אם אין לך
curl -LsSf https://astral.sh/uv/install.sh | sh

# התקנה בסיסית
uv add yemot-flow

# עם Flask
uv add yemot-flow flask

# עם FastAPI
uv add yemot-flow fastapi uvicorn

# יצירת פרויקט חדש עם uv
uv init my-ivr-project
cd my-ivr-project
uv add yemot-flow flask

דרישות: Python 3.11+ (נבדק על 3.11, 3.12, 3.13)

🚀 למה uv?

יתרון פירוט
מהיר פי 10-100 התקנת packages מהירה בצורה דרמטית
ניהול Python מנהל גרסאות Python אוטומטית
Lock files גרסאות קבועות לכל הצוות
Virtual envs ניהול אוטומטי של סביבות וירטואליות
פשוט כל מה שצריך ב-tool אחד

🎬 התחלה מהירה עם uv

# 1. התקן uv (אם אין לך)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. צור פרויקט חדש
uv init my-ivr-system
cd my-ivr-system

# 3. הוסף yemot-flow
uv add yemot-flow flask

# 4. צור קובץ app.py
cat > app.py << 'EOF'
from flask import Flask, request, Response
from yemot_flow import Flow, Call

app = Flask(__name__)
flow = Flow(print_log=True)

@flow.get("")
async def hello(call: Call):
    name = await call.read([('text', 'מה שמך?')], mode="stt", val_name="name")
    call.play_message([('text', f'שלום {name}!')])
    call.hangup()

@app.route("/yemot", methods=["GET", "POST"])
def yemot():
    return Response(flow.handle_request(request.values.to_dict()), 
                   mimetype="text/plain; charset=utf-8")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)
EOF

# 5. הרץ!
uv run python app.py

🎉 זהו! המערכת רצה על http://localhost:5000/yemot


⚡ דוגמה מהירה (5 דקות!)

🔥 הדרך החדשה - async/await

from flask import Flask, request, Response
from yemot_flow import Flow, Call

app = Flask(__name__)
flow = Flow(print_log=True)

@flow.get("")
async def welcome(call: Call):
    """שיחה פשוטה עם 3 קלטים"""
    
    # קלט 1
    input1 = await call.read([('text', 'אנא הקש 1')], 
                            val_name="input1", max_digits=1, digits_allowed="1")
    
    # קלט 2 
    input2 = await call.read([('text', 'עכשיו הקש 2')], 
                            val_name="input2", max_digits=1, digits_allowed="2")
    
    # קלט 3
    input3 = await call.read([('text', 'ולסיום הקש 3')], 
                            val_name="input3", max_digits=1, digits_allowed="3")
    
    # סיכום
    call.play_message([('text', f'קלטת: {input1}, {input2}, {input3}. תודה!')])
    call.hangup()

@app.route("/yemot", methods=["GET", "POST"])
def yemot_entry():
    return Response(
        flow.handle_request(request.values.to_dict()),
        mimetype="text/plain; charset=utf-8"
    )

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)

🚀 הפעלה

# עם Python רגיל
python app.py

# עם uv (מומלץ)
uv run app.py

# המערכת רצה על: http://localhost:5000/yemot

🔗 הגדרה בימות: כתובת API ← http://your-server-ip:5000/yemot

📱 הדרך הישנה (sync) - עדיין נתמכת

@flow.get("")
def old_style(call):
    call.play_message([("text", "שלום וברכה! הקש 1")])
    call.read([("text", "הקש 1 להמשך")], max_digits=1, digits_allowed="1")
    if call.params.get("Digits") == "1":
        call.goto("thanks")

@flow.get("thanks") 
def thanks(call):
    call.play_message([("text", "תודה ולהתראות")])
    call.hangup()

🎯 דוגמאות מתקדמות

🗣️ זיהוי דיבור (STT)

@flow.get("stt")
async def speech_demo(call: Call):
    name = await call.read([('text', 'אמור את שמך')], 
                          mode="stt", val_name="name", lang="he-IL")
    
    call.play_message([('text', f'שלום {name}, נעים להכיר!')])
    call.hangup()

🎙️ הקלטה

@flow.get("record")
async def recording_demo(call: Call):
    recording = await call.read([('text', 'תתחיל הקלטה אחרי הצפצוף')], 
                               mode="record", val_name="recording", 
                               max_length=30, path="/recordings")
    
    call.play_message([('text', 'תודה על ההקלטה')])
    call.hangup()

🍕 מערכת הזמנות מסעדה

@flow.get("")
async def restaurant(call: Call):
    # בחירת פיצה
    pizza = await call.read([
        ('text', 'ברוכים הבאים לפיצה שמח!'),
        ('text', 'הקש 1 למרגריטה, 2 לפפרוני, 3 לירקות')
    ], val_name="pizza", max_digits=1, digits_allowed="123")
    
    pizza_names = {"1": "מרגריטה", "2": "פפרוני", "3": "ירקות"}
    
    # בחירת גודל
    size = await call.read([
        ('text', f'בחרת פיצה {pizza_names[pizza]}'),
        ('text', 'הקש 1 לקטנה, 2 לבינונית, 3 לגדולה')
    ], val_name="size", max_digits=1, digits_allowed="123")
    
    sizes = {"1": "קטנה", "2": "בינונית", "3": "גדולה"}
    
    # פרטי משלוח
    phone = await call.read([('text', 'אמור מספר טלפון למשלוח')], 
                           mode="stt", val_name="phone", lang="he-IL")
    
    address = await call.read([('text', 'אמור כתובת למשלוח')], 
                             mode="stt", val_name="address", lang="he-IL")
    
    # אישור הזמנה
    call.play_message([
        ('text', f'אישור הזמנה: פיצה {pizza_names[pizza]} {sizes[size]}'),
        ('text', f'טלפון: {phone}'),
        ('text', f'כתובת: {address}'),
        ('text', 'ההזמנה תגיע תוך 30 דקות. תודה!')
    ])
    call.hangup()

📚 API מלא

Flow - המנוע הראשי

flow = Flow(timeout=30000, print_log=True)

# רישום handlers
@flow.get("")          # שלוחה ראשית
@flow.get("sales")     # שלוחת מכירות  
@flow.get("support")   # שלוחת תמיכה

# ניהול בקשות
response = flow.handle_request(params_dict)

Call - אובייקט השיחה

🎵 play_message - השמעת הודעות

call.play_message([
    ("text", "שלום וברכה"),           # טקסט
    ("file", "welcome"),              # קובץ שמע
    ("digits", "12345"),             # ספרות
    ("number", "150"),               # מספר (מאה וחמישים)
    ("alpha", "abc"),                # אותיות
])

🎹 read - קבלת קלטים

# הקשות מקלדת
result = await call.read([('text', 'הקש מספר')], 
                        val_name="user_input",
                        max_digits=3,
                        min_digits=1,
                        digits_allowed="123456789",
                        sec_wait=10)

# זיהוי דיבור
speech = await call.read([('text', 'דבר עכשיו')], 
                        mode="stt",
                        val_name="speech",
                        lang="he-IL")

# הקלטה
recording = await call.read([('text', 'תתחיל הקלטה')], 
                           mode="record",
                           val_name="recording",
                           max_length=60,
                           path="/recordings/")

🔄 ניווט

call.goto("sales")      # מעבר לשלוחה
call.goto("")           # חזרה לראשית  
call.hangup()           # ניתוק השיחה

🌐 FastAPI Support

from fastapi import FastAPI, Request, Response
from yemot_flow import Flow, Call

app = FastAPI()
flow = Flow()

@flow.get("")
async def root(call: Call):
    name = await call.read([('text', 'מה שמך?')], mode="stt", val_name="name")
    call.play_message([('text', f'שלום {name} מ-FastAPI!')])
    call.hangup()

@app.api_route("/yemot", methods=["GET", "POST"])
async def yemot_entry(request: Request):
    if request.method == "POST":
        params = await request.form()
    else:
        params = request.query_params
    
    resp = flow.handle_request(dict(params))
    return Response(resp, media_type="text/plain; charset=utf-8")

# הפעלה עם uvicorn רגיל
# uvicorn main:app --host 0.0.0.0 --port 8000

# הפעלה עם uv (מומלץ)  
# uv run uvicorn main:app --host 0.0.0.0 --port 8000

🧪 דוגמאות נוספות

ראה תיקיית examples/ לדוגמאות מלאות:

  • minimal_example.py - דוגמה פשוטה ביותר
  • flask_basic_example.py - Flask מתקדם עם תפריטים
  • fastapi_basic_example.py - FastAPI עם async handlers
  • restaurant_ordering_system.py - מערכת הזמנות מסעדה מלאה
  • hebrew_no_encoding_example.py - עברית ללא בעיות קידוד

🛠️ פיתוח ותרומה

🐍 עם pip

# Clone + setup
git clone https://github.com/davidTheDeveloperY/yemot-flow
cd yemot-flow
pip install -e .

# הרצת בדיקות
pytest tests/

# בדיקת examples
python examples/minimal_example.py

⚡ עם uv (מומלץ למפתחים)

# Clone + setup
git clone https://github.com/davidTheDeveloperY/yemot-flow
cd yemot-flow
uv sync

# הרצת בדיקות
uv run pytest tests/

# בדיקת examples
uv run python examples/minimal_example.py

# פיתוח עם hot reload
uv run python examples/flask_basic_example.py

# בנייה ופרסום
uv build
uv publish

🐛 פתרון בעיות נפוצות

❌ שגיאת חיבור

  • וודא שהשרת רץ על IP חיצוני (host="0.0.0.0")
  • בדוק firewall/router settings
  • השתמש בטרמינל: curl "http://your-server:5000/yemot?ApiCallId=test"

❌ עברית לא עובדת

  • הוסף charset=utf-8 ל-Response
  • השתמש ב-url_encode=True ב-play_message אם יש בעיות

❌ השיחה נתקעת

  • בדוק שיש val_name ייחודי לכל read()
  • ודא ש-digits_allowed מכיל את הספרות הנכונות
  • הוסף print_log=True ל-Flow לראות מה קורה

📋 Changelog

v0.2.18 (נוכחי)

  • 📚 README מושלם ומפורט
  • 🎯 דוגמאות async/await מלאות
  • 🔧 תיקוני תיעוד וסדר

v0.2.17

  • ✨ תמיכה מלאה ב-async/await
  • 🔧 המשכיות אוטומטית של handlers
  • 🚀 ביצועים משופרים
  • 📚 דוגמאות מעודכנות

v0.2.16

  • 🐛 תיקוני באגים ביציבות
  • 📝 שיפורי תיעוד

🤝 תמיכה ועזרה

  • GitHub Issues: yemot-flow/issues
  • דוגמאות: ראה תיקיית examples/
  • פורום ימות: חפש "yemot-flow"

📄 רישיון

MIT License - חופשי לשימוש מסחרי ואישי


💝 נהנת מהספרייה? תן לנו ⭐ ב-GitHub!
Made with ❤️ by davidTheDeveloper

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yemot_flow-0.2.20.tar.gz (30.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

yemot_flow-0.2.20-py3-none-any.whl (15.3 kB view details)

Uploaded Python 3

File details

Details for the file yemot_flow-0.2.20.tar.gz.

File metadata

  • Download URL: yemot_flow-0.2.20.tar.gz
  • Upload date:
  • Size: 30.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.13

File hashes

Hashes for yemot_flow-0.2.20.tar.gz
Algorithm Hash digest
SHA256 b466faea493a922483e77d09ede403e07a1b74999014b97576164706f5acfa11
MD5 831bf404d50d46507b549341c763d7e5
BLAKE2b-256 6f495e7b5ca23f683ff1e9a127a6f739c184a1320615ee5ad3802be970d33cc0

See more details on using hashes here.

File details

Details for the file yemot_flow-0.2.20-py3-none-any.whl.

File metadata

File hashes

Hashes for yemot_flow-0.2.20-py3-none-any.whl
Algorithm Hash digest
SHA256 eb4675de0b6496f3c64075ec2107d2216594c51004d2999f75a01c3dd1832b61
MD5 71cfe17f083191985dc56430a94de21b
BLAKE2b-256 23e0ebb7d91b0fa96b495f6b781ee0ded2f543b393ba874f26df700692cb8eb6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page