es
Feedback
Pythonic Dev

Pythonic Dev

Ir al canal en Telegram

Happy Coding 💫 ADMIN: @cmatrix1

Mostrar más
El país no está especificadoTecnologías y Aplicaciones38 243
999
Suscriptores
Sin datos24 horas
-107 días
-5330 días
Archivo de publicaciones
قطعا خیلی از دوستانی که توی حوزه بک اند کار میکنند گاهی اوقات برای داشتن نمونه کار مورد چالش قرار میگیرن یه مقاله روی ویرگول منتشر کردم که یک راه خیلی ساده و خوب برای ساخت نمونه کار حرفه ای رو توش توضیح دادم https://vrgl.ir/tM8oi اگر خوشتون اومد و استقبال کردید، می‌تونم یک ویدیو هم ضبط کنم که با همین روش، یک وبسایت خفن رو از صفر تا صد بالا بیاریم! 🚀 ممنون می‌شم نظرات و پیشنهاداتتون رو با من به اشتراک بذارید.

سلام خدمت دوستان اخیرا داخل یکی از پروژه ها لازمه که با چندین پنل مرزبان ارتباط برقرار کنیم و برای همین من دنبال یک کلاینت پا
سلام خدمت دوستان اخیرا داخل یکی از پروژه ها لازمه که با چندین پنل مرزبان ارتباط برقرار کنیم و برای همین من دنبال یک کلاینت پایتونی خوب برای ارتباط با این پنل بودم که فقط یک پروژه روی گیت هاب پیدا کردم که از نظرم interface جالبی نداشت برای همین یه کلاینت کوچیک نوشتم واسه استفاده از API های پنل مرزبان داخل پایتون آدرس پروژه: https://github.com/Cmatrix1/MarzbanAPIClient/ پنل مرزبان چیه؟ مرزبان یک نرم افزار (وب اپلیکیشن) مدیریت پروکسیه که امکان مدیریت چند صد حساب پروکسی رو به شما میده. مرزبان از Xray-core قدرت گرفته و درواقع با پایتون هم توسعه داده شده بنظرم حتما یه سری به گیت هاب مرزبان هم بزنید پروژه فوقالعاده ای هست @Pythonic_Dev

📘 Chapter 2: *Asyncio Basics* 🚀 Chapter 2 delves into the foundational aspects of asyncio in Python, focusing on how it enables single-threaded concurrency using coroutines, tasks, and event loops. Here’s a breakdown: 🌀 2.1 Introducing Coroutines - Coroutines are special Python functions that can pause and resume execution when encountering a potentially long-running task. - When a coroutine pauses to wait for an operation, other tasks can run concurrently, providing concurrency. 💡 - `async` and `await` are the two essential keywords: - async defines a function as a coroutine. - await pauses the coroutine until a result is available from an asynchronous operation. ⚙️ Example of Creating a Coroutine
async def my_coroutine() -> None:
    print("Hello world!")
This is similar to a normal Python function but can pause its execution. ⏳ 2.2 Introducing Long-Running Coroutines with `sleep` - Asyncio’s sleep function allows us to pause execution, simulating real-world, long-running operations like web requests or database queries 🌐. - When await asyncio.sleep() is called, other tasks can be executed during the pause. ⚙️ Example of Using asyncio.sleep
async def hello_world_message() -> str:
    await asyncio.sleep(1)
    return "Hello World!"
This coroutine pauses for 1 second before returning "Hello World!". During that second, other coroutines can run concurrently. 🔄 2.3 Running Concurrently with Tasks - A task is a wrapper around a coroutine that schedules it to run on the event loop 🕑. - Tasks allow coroutines to be run concurrently, as they don’t block the event loop, unlike await, which pauses until a result is returned. ⚙️ Example of Creating a Task
import asyncio
from util import delay

async def main():
    task = asyncio.create_task(delay(3))
    await task
Here, the task delay(3) runs concurrently, while other code can execute. ⛔ 2.4 Canceling Tasks and Setting Timeouts - Tasks can be canceled using task.cancel(), raising a CancelledError within the task. If a task is taking too long, we can also set timeouts using asyncio.wait_for 🕒. ⚙️ Example of Cancelling a Task
async def cancel_task(task):
    task.cancel()
    try:
        await task
    except asyncio.CancelledError:
        print("Task was cancelled")
💼 2.5 Tasks, Coroutines, Futures, and Awaitables - Futures represent a value that will be available in the future but might not exist yet. They are used internally in asyncio and can be awaited 🎯. - Coroutines and tasks can both be used in await expressions. ⚙️ Example of Working with Futures
from asyncio import Future

my_future = Future()
my_future.set_result(42)
print(my_future.result())  # Outputs: 42
⏱️ 2.6 Measuring Coroutine Execution Time with Decorators - By using decorators, we can measure the execution time of coroutines for performance analysis. ⌛ ⚠️ 2.7 Pitfalls of Coroutines and Tasks - Be cautious with CPU-bound code inside coroutines, as it will block the event loop. - Avoid using blocking I/O APIs; use asyncio-compatible libraries to ensure the event loop runs smoothly 🛠️. 🔧 2.8 Accessing and Manually Managing the Event Loop - You can access the event loop directly using asyncio.get_event_loop(), though asyncio.run() is recommended for running main coroutines. 🛠️ 2.9 Using Debug Mode - Debug mode helps in identifying long-running coroutines or tasks that block the event loop 🧐. You can enable it with:
python3 -X dev program.py
Or by setting the PYTHONASYNCIODEBUG environment variable. ⚙️ Example of Running in Debug Mode
asyncio.run(main(), debug=True)
#PythonConcurrencyWithAsyncio #Chapter_02 #Notes #Book

### 📘 Notes from Chapter 2: *Asyncio Basics* 🚀 Chapter 2 delves into the foundational aspects of asyncio in Python, focusing on how it enables single-threaded concurrency using coroutines, tasks, and event loops. Here’s a breakdown: 🌀 2.1 Introducing Coroutines - Coroutines are special Python functions that can pause and resume execution when encountering a potentially long-running task. - When a coroutine pauses to wait for an operation, other tasks can run concurrently, providing concurrency. 💡 - `async` and `await` are the two essential keywords: - async defines a function as a coroutine. - await pauses the coroutine until a result is available from an asynchronous operation. ⚙️ Example of Creating a Coroutine
async def my_coroutine() -> None:
    print("Hello world!")
This is similar to a normal Python function but can pause its execution. ⏳ 2.2 Introducing Long-Running Coroutines with `sleep` - Asyncio’s sleep function allows us to pause execution, simulating real-world, long-running operations like web requests or database queries 🌐. - When await asyncio.sleep() is called, other tasks can be executed during the pause. ⚙️ Example of Using asyncio.sleep
async def hello_world_message() -> str:
    await asyncio.sleep(1)
    return "Hello World!"
This coroutine pauses for 1 second before returning "Hello World!". During that second, other coroutines can run concurrently. 🔄 2.3 Running Concurrently with Tasks - A task is a wrapper around a coroutine that schedules it to run on the event loop 🕑. - Tasks allow coroutines to be run concurrently, as they don’t block the event loop, unlike await, which pauses until a result is returned. ⚙️ Example of Creating a Task
import asyncio
from util import delay

async def main():
    task = asyncio.create_task(delay(3))
    await task
Here, the task delay(3) runs concurrently, while other code can execute. ⛔ 2.4 Canceling Tasks and Setting Timeouts - Tasks can be canceled using task.cancel(), raising a CancelledError within the task. If a task is taking too long, we can also set timeouts using asyncio.wait_for 🕒. ⚙️ Example of Cancelling a Task
async def cancel_task(task):
    task.cancel()
    try:
        await task
    except asyncio.CancelledError:
        print("Task was cancelled")
💼 2.5 Tasks, Coroutines, Futures, and Awaitables - Futures represent a value that will be available in the future but might not exist yet. They are used internally in asyncio and can be awaited 🎯. - Coroutines and tasks can both be used in await expressions. ⚙️ Example of Working with Futures
from asyncio import Future

my_future = Future()
my_future.set_result(42)
print(my_future.result())  # Outputs: 42
⏱️ 2.6 Measuring Coroutine Execution Time with Decorators - By using decorators, we can measure the execution time of coroutines for performance analysis. ⌛ ⚠️ 2.7 Pitfalls of Coroutines and Tasks - Be cautious with CPU-bound code inside coroutines, as it will block the event loop. - Avoid using blocking I/O APIs; use asyncio-compatible libraries to ensure the event loop runs smoothly 🛠️. 🔧 2.8 Accessing and Manually Managing the Event Loop - You can access the event loop directly using asyncio.get_event_loop(), though asyncio.run() is recommended for running main coroutines. 🛠️ 2.9 Using Debug Mode - Debug mode helps in identifying long-running coroutines or tasks that block the event loop 🧐. You can enable it with:
python3 -X dev program.py
Or by setting the PYTHONASYNCIODEBUG environment variable. ⚙️ Example of Running in Debug Mode
asyncio.run(main(), debug=True)
#PythonConcurrencyWithAsyncio #Chapter_02 #Notes #Book

📘 Chapter 2: *Asyncio Basics* 🚀 Chapter 2 delves into the foundational aspects of asyncio in Python, focusing on how it enables single-threaded concurrency using coroutines, tasks, and event loops. Here’s a breakdown: 🌀 2.1 Introducing Coroutines - Coroutines are special Python functions that can pause and resume execution when encountering a potentially long-running task. - When a coroutine pauses to wait for an operation, other tasks can run concurrently, providing concurrency. 💡 - `async` and `await` are the two essential keywords: - async defines a function as a coroutine. - await pauses the coroutine until a result is available from an asynchronous operation. ⚙️ Example of Creating a Coroutine
async def my_coroutine() -> None:
    print("Hello world!")
This is similar to a normal Python function but can pause its execution. ⏳ 2.2 Introducing Long-Running Coroutines with `sleep` - Asyncio’s sleep function allows us to pause execution, simulating real-world, long-running operations like web requests or database queries 🌐. - When await asyncio.sleep() is called, other tasks can be executed during the pause. ⚙️ Example of Using asyncio.sleep
async def hello_world_message() -> str:
    await asyncio.sleep(1)
    return "Hello World!"
This coroutine pauses for 1 second before returning "Hello World!". During that second, other coroutines can run concurrently. 🔄 2.3 Running Concurrently with Tasks - A task is a wrapper around a coroutine that schedules it to run on the event loop 🕑. - Tasks allow coroutines to be run concurrently, as they don’t block the event loop, unlike await, which pauses until a result is returned. ⚙️ Example of Creating a Task
import asyncio
from util import delay

async def main():
    task = asyncio.create_task(delay(3))
    await task
Here, the task delay(3) runs concurrently, while other code can execute. ⛔ 2.4 Canceling Tasks and Setting Timeouts - Tasks can be canceled using task.cancel(), raising a CancelledError within the task. If a task is taking too long, we can also set timeouts using asyncio.wait_for 🕒. ⚙️ Example of Cancelling a Task
async def cancel_task(task):
    task.cancel()
    try:
        await task
    except asyncio.CancelledError:
        print("Task was cancelled")
💼 2.5 Tasks, Coroutines, Futures, and Awaitables - Futures represent a value that will be available in the future but might not exist yet. They are used internally in asyncio and can be awaited 🎯. - Coroutines and tasks can both be used in await expressions. ⚙️ Example of Working with Futures
from asyncio import Future

my_future = Future()
my_future.set_result(42)
print(my_future.result())  # Outputs: 42
⏱️ 2.6 Measuring Coroutine Execution Time with Decorators - By using decorators, we can measure the execution time of coroutines for performance analysis. ⌛ ⚠️ 2.7 Pitfalls of Coroutines and Tasks - Be cautious with CPU-bound code inside coroutines, as it will block the event loop. - Avoid using blocking I/O APIs; use asyncio-compatible libraries to ensure the event loop runs smoothly 🛠️. 🔧 2.8 Accessing and Manually Managing the Event Loop - You can access the event loop directly using asyncio.get_event_loop(), though asyncio.run() is recommended for running main coroutines. 🛠️ 2.9 Using Debug Mode - Debug mode helps in identifying long-running coroutines or tasks that block the event loop 🧐. You can enable it with:
python3 -X dev program.py
Or by setting the PYTHONASYNCIODEBUG environment variable. ⚙️ Example of Running in Debug Mode
asyncio.run(main(), debug=True)

📘 Chapter 1: Getting to Know Asyncio 🔄 What is asyncio? asyncio is a Python library introduced in version 3.4 that allows you to run I/O-bound tasks concurrently. Rather than making your code wait for slow operations, asyncio allows multiple tasks to run "in parallel" by pausing tasks when they’re waiting for I/O. This allows Python to work on other tasks in the meantime. 🖥️ I/O-bound vs. CPU-bound Tasks - I/O-bound: Tasks that wait for input/output, such as web requests or database queries. These tasks benefit greatly from asyncio as it allows them to pause and let other tasks run while waiting. - CPU-bound: Tasks that use lots of computational power (like math calculations). asyncio isn't designed for CPU-heavy tasks. ⚙️ Concurrency, Parallelism, and Multitasking - Concurrency: When multiple tasks appear to be running at the same time by taking turns. For example, while one task is waiting for a file to download, another task can start. - Parallelism: When tasks are literally running at the same time on multiple CPU cores. - Multitasking: Managing several tasks at once. This can be preemptive (the OS decides when to switch between tasks) or cooperative (tasks decide when to yield control). asyncio uses cooperative multitasking, meaning tasks "cooperate" by pausing when they reach I/O. 🔄 Processes vs. Threads - Processes: Independent units that do not share memory. They are good for CPU-bound tasks but use more resources. - Threads: Lighter-weight than processes and share memory within the same program. However, Python’s Global Interpreter Lock (GIL) prevents threads from running Python code at the same time (no parallel execution). Still, threads are useful for I/O-bound tasks. 🔐 Global Interpreter Lock (GIL) - GIL is a mechanism in Python that allows only one thread to execute Python bytecode at a time, even on multi-core systems. - This makes multithreading less useful for CPU-bound operations but still beneficial for I/O-bound tasks because I/O releases the GIL. ⚡ Single-threaded Concurrency asyncio achieves concurrency without needing multiple threads by using non-blocking I/O and an event loop. 📬 What is a Socket? A socket is a low-level connection to send and receive data over a network. By default, sockets are blocking, meaning they make the program wait while they communicate. Non-blocking sockets allow the program to continue executing other tasks while waiting for a response. This is key to how asyncio achieves concurrency with just one thread. 🔄 Event Loop - An event loop is a core part of how asyncio works. It’s a loop that runs tasks, pausing and resuming them as necessary. The event loop checks if tasks are waiting on I/O and either runs them or pauses them until they’re ready. - Tasks that involve I/O can pause and free up the loop to run other tasks, making programs more efficient. 🕹️ How It Works: 1. Tasks are submitted to the event loop. 2. The loop starts running tasks. If a task hits an I/O operation (like a web request), the task pauses. 3. The operating system watches the socket and informs the event loop when the I/O is complete. 4. The event loop resumes the paused task and continues processing. 🤔 Why Use asyncio? - Improves performance for programs that do a lot of waiting (web servers, file reading). - Lightweight and doesn’t need multiple threads or processes to handle concurrency. - Efficient resource utilization: While waiting for slow I/O operations, the CPU can continue working on other tasks, leading to faster overall execution. 🚀 Key Takeaways: - asyncio is ideal for I/O-bound tasks and allows you to write concurrent programs using a single thread. - It does not remove Python's GIL but makes it less of an issue by focusing on I/O tasks. - Non-blocking I/O and the event loop allow tasks to pause and resume, making concurrency efficient even with just one thread. #PythonConcurrencyWithAsyncio #Chapter_01 #Notes #Book

📘 Chapter 1: Getting to Know Asyncio 🔄 What is asyncio? asyncio is a Python library introduced in version 3.4 that allows you to run I/O-bound tasks concurrently. Rather than making your code wait for slow operations (like web requests), asyncio allows multiple tasks to run "in parallel" by pausing tasks when they’re waiting for I/O. This allows Python to work on other tasks in the meantime. 🖥️ I/O-bound vs. CPU-bound Tasks I/O-bound: Tasks that wait for input/output, such as web requests or database queries. These tasks benefit greatly from asyncio as it allows them to pause and let other tasks run while waiting. CPU-bound: Tasks that use lots of computational power (like math calculations). asyncio isn't designed for CPU-heavy tasks. ⚙️ Concurrency, Parallelism, and Multitasking Concurrency: When multiple tasks appear to be running at the same time by taking turns. For example, while one task is waiting for a file to download, another task can start. Parallelism: When tasks are literally running at the same time on multiple CPU cores. Multitasking: Managing several tasks at once. This can be preemptive (the OS decides when to switch between tasks) or cooperative (tasks decide when to yield control). asyncio uses cooperative multitasking, meaning tasks "cooperate" by pausing when they reach I/O. 🔄 Processes vs. Threads Processes: Independent units that do not share memory. They are good for CPU-bound tasks but use more resources. Threads: Lighter-weight than processes and share memory within the same program. However, Python’s Global Interpreter Lock (GIL) prevents threads from running Python code at the same time (no parallel execution). Still, threads are useful for I/O-bound tasks. 🔐 The Global Interpreter Lock (GIL) The GIL is a mechanism in Python that allows only one thread to execute Python bytecode at a time, even on multi-core systems. This makes multithreading less useful for CPU-bound operations but still beneficial for I/O-bound tasks because I/O releases the GIL. ⚡ Single-threaded Concurrency asyncio achieves concurrency without needing multiple threads by using non-blocking I/O and an event loop. 📬 What is a Socket? A socket is a low-level connection to send and receive data over a network. By default, sockets are blocking, meaning they make the program wait while they communicate. Non-blocking sockets allow the program to continue executing other tasks while waiting for a response. This is key to how asyncio achieves concurrency with just one thread. 🔄 Event Loop An event loop is a core part of how asyncio works. It’s a loop that runs tasks, pausing and resuming them as necessary. The event loop checks if tasks are waiting on I/O and either runs them or pauses them until they’re ready. Tasks that involve I/O can pause and free up the loop to run other tasks, making programs more efficient. 🕹️ How It Works: 1. Tasks are submitted to the event loop. 2. The loop starts running tasks. If a task hits an I/O operation (like a web request), the task pauses. 3. The operating system watches the socket and informs the event loop when the I/O is complete. 4. The event loop resumes the paused task and continues processing. 🤔 Why Use asyncio? Improves performance for programs that do a lot of waiting (e.g., web servers, file reading). Lightweight and doesn’t need multiple threads or processes to handle concurrency. Efficient resource utilization: While waiting for slow I/O operations, the CPU can continue working on other tasks, leading to faster overall execution. 🚀 Key Takeaways: asyncio is ideal for I/O-bound tasks and allows you to write concurrent programs using a single thread. It does not remove Python's GIL but makes it less of an issue by focusing on I/O tasks. Non-blocking I/O and the event loop allow tasks to pause and resume, making concurrency efficient even with just one thread.

just one thread. #PythonConcurrencyWithAsyncio #Chapter_1 #Notes

📘 Chapter 1: Getting to Know Asyncio (Python Concurrency with asyncio) 🔄 What is asyncio? asyncio is a Python library introduced in version 3.4 that allows you to run I/O-bound tasks concurrently. Rather than making your code wait for slow operations (like web requests), asyncio allows multiple tasks to run "in parallel" by pausing tasks when they’re waiting for I/O. This allows Python to work on other tasks in the meantime. 🖥️ I/O-bound vs. CPU-bound Tasks - I/O-bound: Tasks that wait for input/output, such as web requests or database queries. These tasks benefit greatly from asyncio as it allows them to pause and let other tasks run while waiting. - CPU-bound: Tasks that use lots of computational power (like math calculations). asyncio isn't designed for CPU-heavy tasks. ⚙️ Concurrency, Parallelism, and Multitasking - Concurrency: When multiple tasks appear to be running at the same time by taking turns. For example, while one task is waiting for a file to download, another task can start. - Parallelism: When tasks are literally running at the same time on multiple CPU cores. - Multitasking: Managing several tasks at once. This can be preemptive (the OS decides when to switch between tasks) or cooperative (tasks decide when to yield control). asyncio uses cooperative multitasking, meaning tasks "cooperate" by pausing when they reach I/O. 🔄 Processes vs. Threads - Processes: Independent units that do not share memory. They are good for CPU-bound tasks but use more resources. - Threads: Lighter-weight than processes and share memory within the same program. However, Python’s Global Interpreter Lock (GIL) prevents threads from running Python code at the same time (no parallel execution). Still, threads are useful for I/O-bound tasks. 🔐 The Global Interpreter Lock (GIL) - The GIL is a mechanism in Python that allows only one thread to execute Python bytecode at a time, even on multi-core systems. - This makes multithreading less useful for CPU-bound operations but still beneficial for I/O-bound tasks because I/O releases the GIL. ⚡ Single-threaded Concurrency asyncio achieves concurrency without needing multiple threads by using non-blocking I/O and an event loop. 📬 What is a Socket? A socket is a low-level connection to send and receive data over a network. By default, sockets are blocking, meaning they make the program wait while they communicate. Non-blocking sockets allow the program to continue executing other tasks while waiting for a response. This is key to how asyncio achieves concurrency with just one thread. 🔄 Event Loop - An event loop is a core part of how asyncio works. It’s a loop that runs tasks, pausing and resuming them as necessary. The event loop checks if tasks are waiting on I/O and either runs them or pauses them until they’re ready. - Tasks that involve I/O can pause and free up the loop to run other tasks, making programs more efficient. 🕹️ How It Works: 1. Tasks are submitted to the event loop. 2. The loop starts running tasks. If a task hits an I/O operation (like a web request), the task pauses. 3. The operating system watches the socket and informs the event loop when the I/O is complete. 4. The event loop resumes the paused task and continues processing. 🤔 Why Use asyncio? - Improves performance for programs that do a lot of waiting (e.g., web servers, file reading). - Lightweight and doesn’t need multiple threads or processes to handle concurrency. - Efficient resource utilization: While waiting for slow I/O operations, the CPU can continue working on other tasks, leading to faster overall execution. 🚀 Key Takeaways: - asyncio is ideal for I/O-bound tasks and allows you to write concurrent programs using a single thread. - It does not remove Python's GIL but makes it less of an issue by focusing on I/O tasks. - Non-blocking I/O and the event loop allow tasks to pause and resume, making concurrency efficient even with

Pages Instead of downloading web pages one by one (which can take a long time if you wait for each page), asyncio allows you to download multiple pages "at the same time." This reduces the waiting time dramatically and improves performance! ### 🚀 Key Takeaways: - asyncio is ideal for I/O-bound tasks and allows you to write concurrent programs using a single thread. - It does not remove Python's GIL but makes it less of an issue by focusing on I/O tasks. - Non-blocking I/O and the event loop allow tasks to pause and resume, making concurrency efficient even with just one thread. #PythonConcurrencyWithAsyncio #Chapter_1 #Notes

📘 Chapter 1: Getting to Know Asyncio (Python Concurrency with asyncio) In this chapter, we explore how asyncio works and why it’s a powerful tool for handling tasks in Python, especially when dealing with I/O-bound operations. Here's everything you need to know from this chapter 👇 --- ### 🔄 What is asyncio? asyncio is a Python library introduced in version 3.4 that allows you to run I/O-bound tasks concurrently. Rather than making your code wait for slow operations (like web requests), asyncio allows multiple tasks to run "in parallel" by pausing tasks when they’re waiting for I/O. This allows Python to work on other tasks in the meantime. --- ### 🖥️ I/O-bound vs. CPU-bound Tasks - I/O-bound: Tasks that wait for input/output, such as web requests or database queries. These tasks benefit greatly from asyncio as it allows them to pause and let other tasks run while waiting. - CPU-bound: Tasks that use lots of computational power (like math calculations). asyncio isn't designed for CPU-heavy tasks. --- ### ⚙️ Concurrency, Parallelism, and Multitasking - Concurrency: When multiple tasks appear to be running at the same time by taking turns. For example, while one task is waiting for a file to download, another task can start. - Parallelism: When tasks are literally running at the same time on multiple CPU cores. - Multitasking: Managing several tasks at once. This can be preemptive (the OS decides when to switch between tasks) or cooperative (tasks decide when to yield control). asyncio uses cooperative multitasking, meaning tasks "cooperate" by pausing when they reach I/O. --- ### 🔄 Processes vs. Threads - Processes: Independent units that do not share memory. They are good for CPU-bound tasks but use more resources. - Threads: Lighter-weight than processes and share memory within the same program. However, Python’s Global Interpreter Lock (GIL) prevents threads from running Python code at the same time (no parallel execution). Still, threads are useful for I/O-bound tasks. --- ### 🔐 The Global Interpreter Lock (GIL) - The GIL is a mechanism in Python that allows only one thread to execute Python bytecode at a time, even on multi-core systems. - This makes multithreading less useful for CPU-bound operations but still beneficial for I/O-bound tasks because I/O releases the GIL. --- ### ⚡ Single-threaded Concurrency asyncio achieves concurrency without needing multiple threads by using non-blocking I/O and an event loop. --- ### 📬 What is a Socket? A socket is a low-level connection to send and receive data over a network. By default, sockets are blocking, meaning they make the program wait while they communicate. Non-blocking sockets allow the program to continue executing other tasks while waiting for a response. This is key to how asyncio achieves concurrency with just one thread. --- ### 🔄 Event Loop - An event loop is a core part of how asyncio works. It’s a loop that runs tasks, pausing and resuming them as necessary. The event loop checks if tasks are waiting on I/O and either runs them or pauses them until they’re ready. - Tasks that involve I/O can pause and free up the loop to run other tasks, making programs more efficient. --- ### 🕹️ How It Works: 1. Tasks are submitted to the event loop. 2. The loop starts running tasks. If a task hits an I/O operation (like a web request), the task pauses. 3. The operating system watches the socket and informs the event loop when the I/O is complete. 4. The event loop resumes the paused task and continues processing. --- ### 🤔 Why Use asyncio? - Improves performance for programs that do a lot of waiting (e.g., web servers, file reading). - Lightweight and doesn’t need multiple threads or processes to handle concurrency. - Efficient resource utilization: While waiting for slow I/O operations, the CPU can continue working on other tasks, leading to faster overall execution. --- ### 📊 Example: Downloading Web

🔍 نگاهی عمیق‌تر به ولیدیشن (Validation) در توسعه نرم‌افزار ولیدیشن به زبان ساده به معنی اعتبارسنجی داده‌های ورودی سیستم قبل از اجرای عملیات داخل سیستم هست. 🔑 انواع Validation 1. Syntax Validation ساده‌ترین نوع ولیدیشن سینتکس ولیدیشن بررسی می‌کنه که آیا ساختار دیتای ورودی صحت داره یا نه. مثلاً:
{
  "order_id": 123,
  "sku": "ABC-123",
  "quantity": 5
}
اینجا سینتکس ولیدیشن بررسی می‌کنه که: - order_id باید عدد باشد. - sku باید رشته باشد. - quantity باید یک عدد غیرمنفی باشد. ✅ نکته مهم اینکه این نوع ولیدیشن باید در لایه‌های اولیه مثل کنترلرهای سیستم شما انجام بشه تا از ورود دیتای اشتباه به لاجیک جلوگیری بشه. 2. Semantic Validation ولیدیشن معنایی به مفهوم دیتای مرتبط هست. گاهی اوقات حتی اگر سینتکس دیتا درست باشه، ممکن است هنوز در زمینه تجاری منطقی نباشه. مثلاً اگر شما لاجیکی برای تخصیص موجودی داشته باشید:
allocate("SKU-001", quantity=10)
اینجا سیستم باید بررسی کنه که: - آیا SKU-001 وجود داره؟ - آیا به اندازه کافی موجودی برای تخصیص ۱۰ واحد وجود داره؟ ✅ اینجا حتی اگر سینتکس دیتا درست باشه باید در زمینه کسب و کار هم منطقی باشه. 3. Pragmatic Validation ولیدیشن کاربردی بررسی می‌کنه که آیا این اکشن ممکن هست یا مجاز هست با توجه به وضعیت فعلی سیستم. مثلاً: - اگر انبار تعطیل باشه نباید سفارشی پردازش بشه. - یا اگر یک کد تخفیف منقضی شده باید اعمال اون روی سفارش ناموفق باشه. یک مثال دیگر: شما ممکن است اکشنی مثل:
allocate("SKU-001", quantity=50)
داشته باشید. ولیدیشن سینتکس و معنایی درست هستند، اما اگر قانون بیزینس شما بگه "مشتری نمی‌تونه بیش از ۲۰ محصول در یک بار سفارش بده"، این اکشن در ولیدیشن کاربردی ناموفق میشه. 🧠 Common Validation Patterns 1. Declarative Validation فرض کنید یک لیست از قوانین دارید مانند: - order_id باید یک عدد صحیح باشد. - quantity باید غیرمنفی باشد. این قوانین را می‌توان به‌صورت Declarative از قبل تعریف کرد. در پایتون، می‌توانید از چیزی مثل pydantic برای تعریف ورودی‌های مورد انتظار استفاده کنید.
from pydantic import BaseModel, Field

class Order(BaseModel):
    order_id: int
    sku: str
    quantity: int = Field(ge=0) 
2. Postel’s Law (Tolerant Reader Pattern) این قانون میگه: Be conservative in what you send, but liberal in what you accept. یعنی "در آنچه ارسال می‌کنید محافظه‌کار باشید، اما در آنچه دریافت می‌کنید آزاد باشید." یا به عبارت ساده‌تر، سیستم شما باید در پذیرش فیلدهای اضافی یا ناشناخته انعطاف‌پذیر باشه. برای مثال، اگر سیستم شما فقط به order_id و quantity نیاز دارد، اما این را دریافت کند:
{
  "order_id": 123,
  "quantity": 5,
  "promo_code": "DISCOUNT20"
}
می‌تونید فیلد اضافی (promo_code) را نادیده بگیرید به جای اینکه کل درخواست را رد کنید. این کار سیستم شما را در برابر تغییرات انعطاف‌پذیر می‌کنه. 🏁 جمع‌بندی - ولیدیشن Syntax بررسی می‌کنه که آیا قالب داده‌ها صحیح هست یا نه. - ولیدیشن Semantic بررسی می‌کنه که داده‌ها در زمینه بیزینس شما معنی‌دار هستند. - ولیدیشن Pragmatic بررسی می‌کند که آیا عمل منطقی و با توجه به وضعیت فعلی سیستم امکان‌پذیر هست. - از ولیدیشن declarative برای اعمال قوانین استفاده کنید و از Tolerant Reader Pattern برای انعطاف‌پذیری بیشتر استفاده کنید

--- 🔍 نگاهی عمیق‌تر به ولیدیشن (Validation) در توسعه نرم‌افزار ولیدیشن به زبان ساده به معنی اعتبارسنجی داده‌های ورودی سیستم قبل از اجرای عملیات داخل سیستم هست. --- ### 🔑 انواع Validation #### 1. Syntax Validation ساده‌ترین نوع ولیدیشن سینتکس ولیدیشن برسی میکنه که آیا ساختار دیتای ورودی صحت داره یا نه. مثلاً:
{"order_id": 123, "sku": "ABC-123", "quantity": 5}
اینجا سینتکس ولیدیشن بررسی می‌کنه که: - order_id باید عدد باشد. - sku باید رشته باشد. - quantity باید یک عدد غیرمنفی باشد. ✅ نکته مهم اینکه این نوع ولیدیشن باید در لایه‌های اولیه مثل کنترلرهای سیستم شما انجام بشه تا از ورود دیتای اشتباه به لاجیک جلوگیری بشه. --- #### 2. Semantic Validation ولیدیشن معنایی به مفهوم دیتای مرتبط هست. گاهی اوقات حتی اگر سینتکس دیتا درست باشه، ممکن است هنوز در زمینه تجاری منطقی نباشه. مثلاً اگر شما لاجیکی برای تخصیص موجودی داشته باشید:
allocate("SKU-001", quantity=10)
اینجا سیستم باید بررسی کنه که: - آیا SKU-001 وجود داره؟ - آیا به اندازه کافی موجودی برای تخصیص ۱۰ واحد وجود داره؟ ✅ اینجا حتی اگر سینتکس دیتا درست باشه باید در زمینه کسب و کار هم منطقی باشه. --- #### 3. Pragmatic Validation ولیدیشن کاربردی بررسی می‌کنه که آیا این اکشن ممکن هست یا مجاز هست با توجه به وضعیت فعلی سیستم. مثلاً: - اگر انبار تعطیل باشه نباید سفارشی پردازش بشه. - یا اگر یک کد تخفیف منقضی شده باید اعمال اون روی سفارش ناموفق باشه. یک مثال دیگر: شما ممکن است اکشنی مثل:
allocate("SKU-001", quantity=50)
داشته باشید. ولیدیشن سینتکس و معنایی درست هستند، اما اگر قانون بیزینس شما بگه "مشتری نمی‌تونه بیش از ۲۰ محصول در یک بار سفارش بده"، این اکشن در ولیدیشن کاربردی ناموفق میشه. --- ### 🛠️ ولیدیشن کجا باید انجام شود؟ بهترین حالت اینه که ولیدیشن در سریع‌ترین حالت ممکن انجام بشه، ولی خب هر کدوم از این انواع ولیدیشن که گفتم در یک جای خاصی باید انجام بشه: - سینتکس ولیدیشن باید در لایه کنترلر هندل بشه مثل routerهای API شما. - ولیدیشن‌های Semantic و Pragmatic باید در لایه سرویس و لاجیک پروژه هندل بشه چون این ولیدیشن‌ها بسته به state فعلی سیستم هستند. --- ### 🧠 Common Validation Patterns #### 1. Declarative Validation فرض کنید یک لیست از قوانین دارید مانند: - order_id باید یک عدد صحیح باشد. - quantity باید غیرمنفی باشد. این قوانین را می‌توان به‌صورت Declarative از قبل تعریف کرد. در پایتون، می‌توانید از چیزی مثل pydantic برای تعریف ورودی‌های مورد انتظار استفاده کنید.
from pydantic import BaseModel, Field

class Order(BaseModel):
    order_id: int
    sku: str
    quantity: int = Field(ge=0) 
--- #### 2. Postel’s Law (Tolerant Reader Pattern) این قانون میگه: Be conservative in what you send, but liberal in what you accept. یعنی "در آنچه ارسال می‌کنید محافظه‌کار باشید، اما در آنچه دریافت می‌کنید آزاد باشید." یا به عبارت ساده‌تر، سیستم شما باید در پذیرش فیلدهای اضافی یا ناشناخته انعطاف‌پذیر باشه. برای مثال، اگر سیستم شما فقط به order_id و quantity نیاز دارد، اما این را دریافت کند:
{
  "order_id": 123,
  "quantity": 5,
  "promo_code": "DISCOUNT20"
}
می‌تونید فیلد اضافی (`promo_code`) را نادیده بگیرید به جای اینکه کل درخواست را رد کنید. این کار سیستم شما را در برابر تغییرات انعطاف‌پذیر می‌کنه. --- --- ### 🏁 جمع‌بندی - ولیدیشن Syntax بررسی می‌کنه که آیا قالب داده‌ها صحیح هست یا نه. - ولیدیشن Semantic برسی میکنه که داده‌ها در زمینه بیزینس شما معنی‌دار هستند. - ولیدیشن Pragmatic بررسی می‌کند که آیا عمل منطقی و با توجه به وضعیت فعلی سیستم امکان‌پذیر هست. - از ولیدیشن declarative برای اعمال قوانین استفاده کنید و از Tolerant Reader Pattern برای انعطاف‌پذیری بیشتر بهره ببرید. ---

دپندنسی اینجکشن ( Dependency Injection ) یک دیزاین پترن عالی برای مدیریت وابستگی کمک میکنه یک پروژه انعطاف‌پذیرتر، قابل نگهداری‌تر و تست‌پذیرتر داشته باشیم تعریفش به صورت خلاصه هم میشه به جای این‌که کلاس‌ها و توابع وابستگی‌ها رو به‌صورت داخلی ایجاد کنیم با استفاده از این دیزاین پترن میتونیم اونارو از بیرون بهشون بدیم. (مثال هارو ببینید برای بهتر متوجه شدن) از مزایای این دیزان پترن میشه اشاره کرد به 1. تست پذیری بیشتر چون شما میتونید کلاس های ماک شده خودتون رو بدید برای تست کردن کلاس مورد نظر خودتون مثلا اینجا میتونید کلاس دیتابیس in memory ای که خودتون ماک کردید رو بدید و دیگه کانکشن اضافه نسازید 2. راحت تر شدن تغییرات از اونجایی که کلاس ها دپندنسی های خودشون رو کنترل نمی کنند راحت تر میشه اونارو تغییر داد درصورت ثابت موندن interface اشون مثلا داخل این مثال ما میتونیم روند کار متد connect رو تغییر بدیم و به جای اینکه به sql وصل بشیم به redis وصل بشیم بدون اینکه تغییری داخل UserService بدیم 3. و اخرین ویژگی که به ذهنم میرسه اینه که کد شما اصل SRP رو حفظ میکنه و هر بخش کاری که باید انجام بده رو انجام میده مثلا اینجا داخل مثالی که از DI استفاده میشه دیگه نیازی به instantiate کردن دیتابیس داخل UserService نیست این دیزاین پترن رو بهتره داخل پروژه هایی استفاده کنید که پیچدگی زیادی دارن و وابستگی زیادی بین بخش های مختلف وجود داره و البته برای زمان هایی که میخواید بین implement های مختلف جا به جا بشید هم کاربردیه مثل همین مثال دیتابیس SQL و Redis ای که گفتم

Dependency Injection
+1
Dependency Injection

دپندنسی اینجکشن ( Dependency Injection ) یک دیزاین پترن عالی برای مدیریت وابستگی کمک میکنه یک پروژه انعطاف‌پذیرتر، قابل نگهداری‌تر و تست‌پذیرتر داشته باشیم تعریفش به صورت خلاصه هم میشه به جای این‌که کلاس‌ها و توابع وابستگی‌ها رو به‌صورت داخلی ایجاد کنیم با استفاده از این دیزاین پترن میتونیم اونارو از بیرون بهشون بدیم. (مثال هارو ببینید برای بهتر متوجه شدن) از مزایای این دیزان پترن میشه اشاره کرد به 1. تست پذیری بیشتر چون شما میتونید کلاس های ماک شده خودتون رو بدید برای تست کردن کلاس مورد نظر خودتون مثلا اینجا میتونید کلاس دیتابیس in memory ای که خودتون ماک کردید رو بدید و دیگه کانکشن اضافه نسازید 2. راحت تر شدن تغییرات از اونجایی که کلاس ها دپندنسی های خودشون رو کنترل نمی کنند راحت تر میشه اونارو تغییر داد درصورت ثابت موندن interface اشون مثلا داخل این مثال ما میتونیم روند کار متد connect رو تغییر بدیم و به جای اینکه به sql وصل بشیم به redis وصل بشیم بدون اینکه تغییری داخل UserService بدیم 3. و اخرین ویژگی که به ذهنم میرسه اینه که کد شما اصل SRP رو حفظ میکنه و هر بخش کاری که باید انجام بده رو انجام میده مثلا اینجا داخل مثالی که از DI استفاده میشه دیگه نیازی به instantiate کردن دیتابیس داخل UserService نیست این دیزاین پترن رو بهتره داخل پروژه هایی استفاده کنید که پیچدگی زیادی دارن و وابستگی زیادی بین بخش های مختلف وجود داره و البته برای زمان هایی که میخواید بین implement های مختلف جا به جا بشید هم کاربردیه مثل همین مثال دیتابیس SQL و Redis ای که گفتم

test
+1
test

test

Applying Clean Code Principles: Refactoring for Better Structure I recently refactored the keyboard layouts in a Telegram bot
+2
Applying Clean Code Principles: Refactoring for Better Structure I recently refactored the keyboard layouts in a Telegram bot to improve clarity and maintainability. The original procedural approach worked but became difficult to manage as the project grew. By switching to an Enum-based, object-oriented structure, I made the code more readable, easier to maintain, and scalable for future features. This change not only cleaned up the code but also made it more resilient to updates. Check out the before and after below!

You know they say economists know the price of everything and the value of nothing? Well, programmers know the benefits of everything and the trade-offs of nothing. -- Rich Hickey