or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compatibility.mdcurrent-thread-executor.mdindex.mdlocal-storage.mdserver-base.mdsync-async.mdtesting.mdtimeout.mdtype-definitions.mdwsgi-integration.md

sync-async.mddocs/

0

# Sync/Async Conversion

1

2

Core functionality for converting between synchronous and asynchronous functions, handling context propagation, thread management, and event loop integration automatically. These utilities enable seamless integration between sync and async codebases.

3

4

## Capabilities

5

6

### Function Decorators

7

8

Convert functions between sync and async execution contexts with automatic context variable propagation and proper thread/event loop management.

9

10

```python { .api }

11

def sync_to_async(func=None, *, thread_sensitive=True, executor=None):

12

"""

13

Convert a synchronous function to an asynchronous one.

14

15

Parameters:

16

- func: callable, the synchronous function to convert

17

- thread_sensitive: bool, whether to run in thread-sensitive mode (default True)

18

- executor: Executor, custom executor for running sync code (optional)

19

20

Returns:

21

SyncToAsync wrapper that can be called with await

22

"""

23

24

def async_to_sync(awaitable=None, *, force_new_loop=False):

25

"""

26

Convert an asynchronous function to a synchronous one.

27

28

Parameters:

29

- awaitable: callable, the async function/coroutine to convert

30

- force_new_loop: bool, whether to force creation of new event loop (default False)

31

32

Returns:

33

AsyncToSync wrapper that can be called synchronously

34

"""

35

```

36

37

### Conversion Classes

38

39

Direct access to the underlying conversion classes for advanced use cases and custom integration.

40

41

```python { .api }

42

class SyncToAsync:

43

"""Generic utility class to convert sync functions to async."""

44

45

def __init__(self, func, thread_sensitive=True, executor=None):

46

"""

47

Initialize sync-to-async converter.

48

49

Parameters:

50

- func: callable, synchronous function to wrap

51

- thread_sensitive: bool, run in thread-sensitive mode

52

- executor: Executor, custom executor instance

53

"""

54

55

def __call__(self, *args, **kwargs):

56

"""

57

Execute wrapped function asynchronously.

58

59

Returns:

60

Coroutine that will execute the sync function

61

"""

62

63

def __get__(self, parent, objtype):

64

"""Descriptor protocol support for method binding."""

65

66

class AsyncToSync:

67

"""Generic utility class to convert async functions to sync."""

68

69

def __init__(self, awaitable, force_new_loop=False):

70

"""

71

Initialize async-to-sync converter.

72

73

Parameters:

74

- awaitable: callable, async function to wrap

75

- force_new_loop: bool, force new event loop creation

76

"""

77

78

def __call__(self, *args, **kwargs):

79

"""

80

Execute wrapped function synchronously.

81

82

Returns:

83

Result of the async function executed synchronously

84

"""

85

86

def __get__(self, parent, objtype):

87

"""Descriptor protocol support for method binding."""

88

```

89

90

### Thread Context Management

91

92

Advanced context management for thread-sensitive operations and cross-context execution.

93

94

```python { .api }

95

class ThreadSensitiveContext:

96

"""Async context manager for thread-sensitive mode."""

97

98

async def __aenter__(self):

99

"""Enter thread-sensitive async context."""

100

101

async def __aexit__(self, exc, value, tb):

102

"""Exit thread-sensitive async context."""

103

```

104

105

### Coroutine Function Utilities

106

107

Utilities for detecting and marking coroutine functions, particularly useful for framework integration.

108

109

```python { .api }

110

def iscoroutinefunction(func):

111

"""

112

Check if something is a coroutine function.

113

114

Parameters:

115

- func: callable, function to check

116

117

Returns:

118

bool: True if func is a coroutine function

119

"""

120

121

def markcoroutinefunction(func):

122

"""

123

Decorator to mark functions as coroutine functions.

124

125

Parameters:

126

- func: callable, function to mark

127

128

Returns:

129

callable: The marked function

130

"""

131

```

132

133

## Usage Examples

134

135

### Basic Function Conversion

136

137

```python

138

from asgiref.sync import sync_to_async, async_to_sync

139

import time

140

import asyncio

141

142

# Convert sync function to async

143

@sync_to_async

144

def sync_operation():

145

time.sleep(1) # Simulate blocking operation

146

return "sync result"

147

148

# Convert async function to sync

149

@async_to_sync

150

async def async_operation():

151

await asyncio.sleep(1) # Simulate async operation

152

return "async result"

153

154

# Usage in async context

155

async def async_main():

156

result = await sync_operation()

157

print(result) # "sync result"

158

159

# Usage in sync context

160

def sync_main():

161

result = async_operation()

162

print(result) # "async result"

163

```

164

165

### Thread-Sensitive vs Thread-Insensitive

166

167

```python

168

from asgiref.sync import sync_to_async

169

import threading

170

171

# Thread-sensitive (default) - runs in same thread

172

@sync_to_async(thread_sensitive=True)

173

def thread_sensitive_func():

174

return threading.current_thread().name

175

176

# Thread-insensitive - can run in any thread

177

@sync_to_async(thread_sensitive=False)

178

def thread_insensitive_func():

179

return "Can run anywhere"

180

181

async def demonstrate():

182

# Will run in specific thread context

183

result1 = await thread_sensitive_func()

184

185

# Can run in thread pool

186

result2 = await thread_insensitive_func()

187

```

188

189

### Custom Executor

190

191

```python

192

from asgiref.sync import sync_to_async

193

from concurrent.futures import ThreadPoolExecutor

194

195

# Use custom executor

196

custom_executor = ThreadPoolExecutor(max_workers=2)

197

198

@sync_to_async(executor=custom_executor)

199

def cpu_intensive_task():

200

# CPU-bound work

201

return sum(i * i for i in range(1000000))

202

203

async def main():

204

result = await cpu_intensive_task()

205

print(f"Result: {result}")

206

```

207

208

### Method Conversion

209

210

```python

211

from asgiref.sync import sync_to_async, async_to_sync

212

213

class DatabaseManager:

214

@sync_to_async

215

def get_user(self, user_id):

216

# Simulate database query

217

return {"id": user_id, "name": f"User {user_id}"}

218

219

@async_to_sync

220

async def async_get_user(self, user_id):

221

# Simulate async database query

222

await asyncio.sleep(0.1)

223

return {"id": user_id, "name": f"Async User {user_id}"}

224

225

# Usage

226

db = DatabaseManager()

227

228

async def async_usage():

229

user = await db.get_user(123)

230

print(user)

231

232

def sync_usage():

233

user = db.async_get_user(456)

234

print(user)

235

```