Patch asyncio to allow nested event loops
npx @tessl/cli install tessl/pypi-nest-asyncio@1.5.00
# nest-asyncio
1
2
A utility library that patches asyncio to allow nested event loops. This solves the common RuntimeError "This event loop is already running" that occurs when trying to run tasks in environments where an event loop is already active, such as web servers, GUI applications, and Jupyter notebooks.
3
4
## Package Information
5
6
- **Package Name**: nest-asyncio
7
- **Package Type**: pypi
8
- **Language**: Python
9
- **Installation**: `pip install nest-asyncio`
10
- **Python Version**: Requires Python 3.5+
11
12
## Core Imports
13
14
```python
15
import nest_asyncio
16
```
17
18
## Basic Usage
19
20
```python
21
import asyncio
22
import nest_asyncio
23
24
# Apply the patch to allow nested event loops
25
nest_asyncio.apply()
26
27
# Now you can use asyncio.run() and loop.run_until_complete()
28
# even when an event loop is already running
29
async def my_async_function():
30
await asyncio.sleep(0.1)
31
return "Hello, World!"
32
33
# This works even in environments with existing event loops
34
result = asyncio.run(my_async_function())
35
print(result)
36
```
37
38
## Capabilities
39
40
### Event Loop Patching
41
42
Patches asyncio to make event loops reentrant, allowing nested execution of `asyncio.run()` and `loop.run_until_complete()` calls.
43
44
```python { .api }
45
def apply(loop=None):
46
"""
47
Patch asyncio to make its event loop reentrant.
48
49
Parameters:
50
- loop (optional): Specific event loop to patch. If None, patches the current event loop.
51
52
Returns:
53
None
54
55
Raises:
56
ValueError: If attempting to patch a non-asyncio.BaseEventLoop
57
"""
58
```
59
60
### Usage Examples
61
62
#### Basic Patching
63
64
```python
65
import nest_asyncio
66
67
# Patch the current event loop
68
nest_asyncio.apply()
69
```
70
71
#### Patching a Specific Loop
72
73
```python
74
import asyncio
75
import nest_asyncio
76
77
# Create and patch a specific loop
78
loop = asyncio.new_event_loop()
79
nest_asyncio.apply(loop)
80
asyncio.set_event_loop(loop)
81
```
82
83
#### In Jupyter Notebooks
84
85
```python
86
import nest_asyncio
87
import asyncio
88
89
# Apply patch to allow asyncio.run() in Jupyter cells
90
nest_asyncio.apply()
91
92
async def fetch_data():
93
await asyncio.sleep(1)
94
return "Data fetched"
95
96
# This works in Jupyter notebooks after applying the patch
97
result = asyncio.run(fetch_data())
98
```
99
100
#### With Web Frameworks
101
102
```python
103
import nest_asyncio
104
import asyncio
105
106
# Apply patch for web server environments
107
nest_asyncio.apply()
108
109
async def background_task():
110
await asyncio.sleep(2)
111
return "Background task completed"
112
113
# Can now run tasks within web request handlers
114
# where an event loop is already running
115
def request_handler():
116
result = asyncio.run(background_task())
117
return result
118
```
119
120
#### Nested Event Loop Usage
121
122
```python
123
import asyncio
124
import nest_asyncio
125
126
nest_asyncio.apply()
127
128
async def outer_task():
129
print("Outer task started")
130
131
# This nested call works with the patch
132
result = asyncio.run(inner_task())
133
print(f"Inner task result: {result}")
134
135
return "Outer task completed"
136
137
async def inner_task():
138
await asyncio.sleep(0.1)
139
return "Inner task result"
140
141
# Run the nested structure
142
result = asyncio.run(outer_task())
143
print(result)
144
```
145
146
## Limitations and Compatibility
147
148
### Supported Event Loops
149
150
- **Works with**: Standard asyncio event loops (asyncio.BaseEventLoop)
151
- **Does not work with**: Third-party event loops (uvloop, quamash, etc.)
152
153
### Platform Support
154
155
- **Cross-platform**: Works on Windows, Linux, and macOS
156
- **Windows-specific**: Includes special handling for ProactorEventLoop
157
158
### Version Compatibility
159
160
- **Python 3.5+**: Core functionality supported
161
- **Python 3.6+**: Uses pure Python tasks and futures
162
- **Python 3.7+**: Enhanced compatibility with asyncio internals
163
- **Python 3.9+**: Updated event loop handling
164
165
## Error Handling
166
167
### Common Exceptions
168
169
The package validates input and may raise:
170
171
```python { .api }
172
ValueError: "Can't patch loop of type <type>"
173
```
174
175
This occurs when attempting to patch non-asyncio event loops.
176
177
## Integration Notes
178
179
### Tornado Compatibility
180
181
If Tornado is imported before nest-asyncio, the package automatically makes Tornado aware of the pure-Python asyncio Future to ensure compatibility.
182
183
### Context Variables (Python 3.7+)
184
185
The patch preserves context variable behavior in nested executions, ensuring that context is properly maintained across nested async calls.
186
187
### Thread Safety
188
189
The patch is thread-aware and handles event loop thread identification correctly, preventing conflicts in multi-threaded applications.