# asyncio stream

**Creating Subprocesses**

Asyncio provides high-level APIs to work with subprocesses. Here's how to create and manage subprocesses asynchronously:

**Creating a Shell Subprocess:**

To run a command in a shell, use `asyncio.create_subprocess_shell`:

```python
import asyncio

async def run_shell_command(cmd):
    proc = await asyncio.create_subprocess_shell(
        cmd,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)

    # Get the stdout and stderr output
    stdout, stderr = await proc.communicate()

    # Print the output and return code
    print(f'[{cmd!r} exited with {proc.returncode}]')
    if stdout:
        print(f'[stdout]\n{stdout.decode()}')
    if stderr:
        print(f'[stderr]\n{stderr.decode()}')

asyncio.run(run_shell_command('ls /zzz'))
```

This will output:

```
['ls /zzz' exited with 1]
[stderr]
ls: /zzz: No such file or directory
```

**Creating a Subprocess Using Pipes:**

To communicate with a subprocess using pipes:

```python
import asyncio

async def run_subprocess(cmd, args):
    # Create the subprocess using pipes
    proc = await asyncio.create_subprocess_exec(
        cmd, args,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)

    # Get the stdout and stderr output
    stdout, stderr = await proc.communicate()

    # Print the output and return code
    print(f'[{cmd} {args!r} exited with {proc.returncode}]')
    if stdout:
        print(f'[stdout]\n{stdout.decode()}')
    if stderr:
        print(f'[stderr]\n{stderr.decode()}')

asyncio.run(run_subprocess('ls', ['-l']))
```

This will output:

```
[ls -l exited with 0]
[stdout]
... (directory listing)
```

**Running Multiple Subprocesses Concurrently:**

With asyncio, you can easily run multiple subprocesses concurrently:

```python
import asyncio

async def main():
    # Create a list of commands to run
    commands = ['ls /zzz', 'sleep 1; echo "hello"']

    # Create a list of tasks to run the commands
    tasks = [run_shell_command(command) for command in commands]

    # Gather the results of the tasks
    await asyncio.gather(*tasks)

asyncio.run(main())
```

This will output:

```
['ls /zzz' exited with 1]
[stderr]
ls: /zzz: No such file or directory
['sleep 1; echo "hello"' exited with 0]
[stdout]
hello
```

**Real-World Applications:**

Asynchronous subprocesses have many applications, such as:

* Running distributed tasks in parallel
* Monitoring system processes
* Querying external services
* Pipelining data between multiple processes

***

**asyncio.create\_subprocess\_exec()**

**Simplified Explanation:**

This function allows you to create a new process and run a command, similar to the `subprocess.call()` function. It uses the asyncio library to handle the process in a non-blocking way.

**Parameters:**

* **program:** The command to run.
* **args:** Arguments to pass to the command.
* **stdin:** The standard input stream for the process.
* **stdout:** The standard output stream for the process.
* **stderr:** The standard error stream for the process.
* **limit:** The buffer limit for the asyncio streams.

**Return Value:**

A `Process` instance representing the subprocess.

**Example:**

```python
import asyncio

async def my_function():
    process = await asyncio.create_subprocess_exec(
        "ls", "-l", stdout=asyncio.subprocess.PIPE
    )
    stdout, _ = await process.communicate()
    print(stdout.decode())

loop = asyncio.get_event_loop()
loop.run_until_complete(my_function())
```

**Real-World Applications:**

* Running system commands in an asynchronous way.
* Managing subprocesses in a non-blocking fashion.
* Automating tasks that require the execution of external commands.

**Alternative Syntax:**

asyncio.create\_subprocess\_exec() can also be used as a decorator. This is useful for creating asynchronous processes that can be called directly:

```python
@asyncio.create_subprocess_exec("ls", "-l")
async def my_ls():
    stdout, _ = await process.communicate()
    return stdout.decode()
```

**Note:**

* The `limit` parameter is added to control the buffer size of the asyncio streams.
* The `loop` parameter was removed. Use `asyncio.get_event_loop()` instead.

***

### `create_subprocess_shell` Function

The `create_subprocess_shell` function in `asyncio` allows you to run a command in the shell of your operating system. It returns a `Process` object that represents the running subprocess.

#### Parameters

* `cmd`: The command you want to run as a string. For example, `'ls -l'`.
* `stdin`: An optional file-like object that will be used as the standard input for the subprocess.
* `stdout`: An optional file-like object that will be used as the standard output for the subprocess.
* `stderr`: An optional file-like object that will be used as the standard error for the subprocess.
* `limit`: An optional integer that sets the buffer limit for `StreamReader` wrappers for `Process.stdout` and `Process.stderr`.
* `**kwds`: Additional keyword arguments that are passed to the `Process` constructor.

#### Return Value

The `create_subprocess_shell` function returns a `Process` object.

#### Code Example

The following code example shows how to use the `create_subprocess_shell` function to run the `ls -l` command:

```python
import asyncio

async def main():
    process = await asyncio.create_subprocess_shell('ls -l')
    stdout, stderr = await process.communicate()
    print(f'Stdout:\n{stdout.decode()}')
    print(f'Stderr:\n{stderr.decode()}')

asyncio.run(main())
```

#### Real-World Applications

The `create_subprocess_shell` function can be used in a variety of real-world applications, including:

* Running system commands from within your Python program.
* Interacting with external programs and services.
* Automating tasks that would otherwise require manual intervention.

### Constants

The `asyncio.subprocess` module also defines the following constants:

* `PIPE`: Can be passed to the `stdin`, `stdout`, or `stderr` parameters of the `create_subprocess_shell` function to indicate that a pipe should be used to connect to the corresponding standard stream of thesubprocess.
* `STDOUT`: A constant that represents the standard output stream of a subprocess.
* `STDIN`: A constant that represents the standard input stream of a subprocess.
* `STDERR`: A constant that represents the standard error stream of a subprocess.

***

**Attributes**

`asyncio.subprocess` has two special attributes:

* `STDOUT`: Indicates that stderr should be redirected into stdout.
* `DEVNULL`: Indicates that the special file `/dev/null` will be used for the corresponding subprocess stream.

**Interacting with Subprocesses**

Both `create_subprocess_exec` and `create_subprocess_shell` functions return instances of the `Process` class. `Process` allows you to communicate with and monitor subprocesses.

**Simplified Explanation**

Imagine you have a command you want to run in a separate process. You can use `create_subprocess_exec` or `create_subprocess_shell` to create a new process and execute the command.

**Real-World Examples**

* **Running a command:**

```python
import asyncio

command = "ls -l"
process = asyncio.create_subprocess_shell(command)
await process.communicate()
```

This code runs the `ls -l` command in a separate process. The `communicate` method waits for the process to complete and returns its stdout and stderr output.

* **Using STDOUT and DEVNULL:**

```python
command = "command_that_writes_to_both_stdout_and_stderr"
process = asyncio.create_subprocess_exec(command, stdout=asyncio.subprocess.STDOUT, stderr=asyncio.subprocess.DEVNULL)
await process.communicate()
```

In this example, stdout and stderr are redirected to the same stream. The `/dev/null` file is used for stderr, so the error output is discarded.

**Potential Applications**

* Running commands from a GUI application
* Monitoring system processes
* Executing long-running tasks in the background

***

**What is asyncio.subprocess.Process?**

asyncio.subprocess.Process is an object that represents a running subprocess, which is a separate program that runs alongside your Python program. You can create subprocesses to perform tasks that you don't want to handle within your main Python program, such as running external commands or interacting with other programs.

**How to use asyncio.subprocess.Process**

To use asyncio.subprocess.Process, you first need to create a new process object using the `create_subprocess_exec` or `create_subprocess_shell` functions. The `create_subprocess_exec` function takes a list of command arguments, while the `create_subprocess_shell` function takes a single string containing the command to be executed.

Once you have a process object, you can use the following methods to interact with it:

* `communicate`: Send data to the subprocess's stdin and receive data from its stdout and stderr.
* `kill`: Terminate the subprocess.
* `wait`: Wait for the subprocess to finish running.

**Real-world examples**

* You can use a subprocess to run a system command and get its output. For example, the following code prints the output of the `ls` command:

```python
import asyncio

async def main():
    process = await asyncio.subprocess.create_subprocess_shell('ls')
    stdout, stderr = await process.communicate()
    print(stdout.decode())

asyncio.run(main())
```

* You can use a subprocess to interact with another program. For example, the following code opens a text editor and waits for the user to save the file:

```python
import asyncio

async def main():
    process = await asyncio.subprocess.create_subprocess_exec('notepad', 'myfile.txt')
    await process.wait()

asyncio.run(main())
```

**Potential applications**

Subprocesses have a wide range of potential applications in real-world scenarios, including:

* Running external commands
* Interacting with other programs
* Automating tasks
* Managing system resources
* Monitoring processes

***

**Process Class in Python's asyncio-stream Module**

The `Process` class in asyncio-stream allows you to run external programs asynchronously, similar to `subprocess.Popen`. However, there are some key differences:

**Notable Differences:**

* **No `poll` method:** Unlike `Popen`, you can't check the status of a child process using `poll`.
* **Asynchronous `wait` and `communicate` methods:** These methods don't have a timeout parameter. Instead, you can use the `asyncio.wait_for` function.
* **Asynchronous `wait` method:** The `wait` method of `Process` is asynchronous, unlike `Popen.wait`, which is a blocking busy loop.
* **No universal newlines support:** The `universal_newlines` parameter is not supported.

**Methods:**

* **`wait()`:** Waits for the child process to finish running and returns its exit code.
* **`communicate(input=None)`:** Interacts with the child process:

  * Sends input data to stdin (if `input` is not `None`).
  * Closes stdin.
  * Reads data from stdout and stderr.
  * Waits for the child process to finish running.

  Returns a tuple containing the stdout and stderr data.

**Potential Applications:**

The `Process` class can be used in various real-world applications, such as:

* Automating tasks by running external commands asynchronously.
* Launching background processes without blocking the main program.
* Interacting with external programs to retrieve data or perform operations.

**Example:**

```python
import asyncio

async def main():
    # Start a child process asynchronously
    process = asyncio.subprocess.Process("echo", "Hello, world!")
    await process.start()

    # Wait for the child process to finish running asynchronously
    exit_code = await process.wait()

    # Print the exit code of the child process
    print(f"Exit code: {exit_code}")

asyncio.run(main())
```

In this example, we asynchronously run the `echo` command with the argument "Hello, world!" and print its exit code once it finishes running.

***

### send\_signal() Method in asyncio-stream

The `send_signal()` method in `asyncio-stream` sends the signal *signal* to the child process.

**Syntax:**

```python
send_signal(signal)
```

**Parameters:**

* `signal`: The signal to send to the child process.

**Note:**

* On Windows, `SIGTERM` is an alias for `terminate`.
* `CTRL_C_EVENT` and `CTRL_BREAK_EVENT` can be sent to processes started with a *creationflags* parameter which includes `CREATE_NEW_PROCESS_GROUP`.

**Example:**

```python
import asyncio
import asyncio_stream

async def main():
    # Create a child process.
    process = await asyncio_stream.Process.create('python', ['-c', 'print("Hello world!")'])

    # Send a signal to the child process.
    process.send_signal(asyncio_stream.SIGTERM)

    # Wait for the child process to terminate.
    await process.wait()

asyncio.run(main())
```

**Output:**

```
Hello world!
```

**Real-World Applications:**

* Sending signals to child processes can be useful for controlling their behavior. For example, you could send a `SIGTERM` signal to a child process to terminate it.
* You could also use signals to pause or resume a child process.

***

**Method: `terminate()`**

**Simplified Explanation:**

This method is used to stop a child process. When you call `terminate()`, it sends a signal to the child process to end its execution.

**Detailed Explanation:**

* **On POSIX systems (like Linux and macOS):** `terminate()` sends the `SIGTERM` signal to the child process. This signal is typically used to request the child process to terminate itself gracefully. If the child process does not handle the `SIGTERM` signal, it will be killed immediately.
* **On Windows:** `terminate()` uses the Windows API function `TerminateProcess` to stop the child process. This function immediately kills the child process without giving it a chance to clean up its resources.

**Code Snippet:**

```python
import asyncio

async def main():
    # Create a child process
    process = await asyncio.create_subprocess_exec('python', 'child_script.py')

    # Wait for the child process to finish
    await process.wait()

    # If the child process exited with an error, print it
    if process.returncode != 0:
        print(f'Child process exited with error: {process.returncode}')

    # Stop the child process
    process.terminate()

asyncio.run(main())
```

**Real-World Applications:**

* **Gracefully ending child processes:** You can use `terminate()` to end child processes that are no longer needed or that are misbehaving. This can help you clean up your application and free up resources.
* **Controlling child processes:** You can use `terminate()` to control child processes that are performing long-running tasks. For example, you could terminate a child process that is taking too long to respond or that is using too much memory.

***

**Process Class**

The Process class in asyncio allows you to create and manage child processes from within your Python program. Here's a simplified explanation of the main features:

* **Creating a Process:** You can create a child process using the `create_subprocess_exec()` function, specifying the command you want to run and the arguments to pass to it.
* **Streams:** The Process class provides access to the standard input, output, and error streams of the child process. You can write data to the input stream using `stdin.write()` and read data from the output and error streams using `stdout.read()` and `stderr.read()`.
* **Process Control:** You can control the child process in various ways. The `kill()` method sends a signal to terminate the process (SIGKILL on POSIX systems). The `terminate()` method sends a signal to stop the process gracefully (SIGINT on POSIX systems). The `wait()` method waits for the process to finish and returns its exit code.
* **Attributes:** The Process class has several attributes that provide useful information about the child process, such as `pid` (process ID), `returncode` (exit code), and `stdin`, `stdout`, and `stderr` (stream objects).

**Subprocess and Threads**

By default, asyncio supports running subprocesses from different threads concurrently. This is useful when you want to perform multiple tasks in parallel, without blocking the execution of your main program.

**Real-World Example**

Let's consider a simple example of using the Process class to get the current date and time from the command line:

```python
import asyncio
import sys

async def get_date():
    # Create the subprocess to execute the 'date' command
    proc = await asyncio.create_subprocess_exec(
        sys.executable, '-c', 'import datetime; print(datetime.datetime.now())',
        stdout=asyncio.subprocess.PIPE)

    # Read the output from the subprocess
    data = await proc.stdout.readline()
    date = data.decode('ascii').rstrip()

    # Wait for the subprocess to finish and get its exit code
    await proc.wait()
    return date

# Run the get_date() function in an asyncio event loop
date = asyncio.run(get_date())

# Print the current date and time
print(f"Current date: {date}")
```

In this example, we use the `create_subprocess_exec()` function to create a child process that runs the 'date' command. We then use the `stdout` attribute of the Process class to read the output of the subprocess and decode it into a string. Finally, we wait for the subprocess to finish using the `wait()` method.

**Potential Applications**

The Process class can be used in a variety of real-world applications, such as:

* **Automating tasks:** You can use the Process class to automate tasks that can be performed by command-line tools, such as running system commands, generating reports, or processing data.
* **Managing subprocesses:** The Process class provides a convenient way to create, control, and monitor subprocesses from within your Python program.
* **Parallel processing:** By using multiple Process objects, you can perform multiple tasks in parallel, speeding up the execution of your program.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://a7246c5516ab4c80cdfe21ca2be3e40c.gitbook.io/python-docs/asyncio-stream.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
