Skip to content

Commit 879a09e

Browse files
committed
chore: update copyright dates and improve async.md
- Update copyright year to 2025 for newly created files - Update async.md to reflect implementation choices: - Document namespace-based approach using aio module - Show that aio namespace accepts both sync and async functions - List completed work and remaining tasks - Update examples to show correct usage
1 parent 2058737 commit 879a09e

File tree

3 files changed

+42
-37
lines changed

3 files changed

+42
-37
lines changed

async.md

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ async def hello_async(request): # Starlette.Request
2323
2. **Backward compatibility** - All existing sync functions must continue to work
2424
3. **Unified API** - Users shouldn't need different decorators for sync vs async
2525
4. **Type safety** - Proper typing for both sync and async cases
26-
5. **Automatic detection** - The system should automatically detect and handle async functions
26+
5. **Flexibility** - The aio namespace accepts both sync and async functions
2727
6. **Universal support** - Async should work for ALL function types, not just HTTP
2828

2929
## Function Types to Support
@@ -106,39 +106,21 @@ Firebase Functions Python supports multiple trigger types that all need async su
106106

107107
### Phase 2: Decorator Updates
108108

109-
#### 2.1 Universal Decorator Pattern
110-
Each decorator should follow this pattern:
109+
#### 2.1 Namespace-based Approach
110+
Instead of modifying existing decorators, we created a new `aio` namespace:
111+
- `firebase_functions.aio.https_fn` for async HTTP functions
112+
- The aio decorators accept both sync and async functions
113+
- ASGI runtime handles sync functions by running them in a thread pool
111114

112-
```python
113-
def on_some_event(**kwargs):
114-
def decorator(func):
115-
is_async = inspect.iscoroutinefunction(func)
116-
117-
if is_async:
118-
# Set up async wrapper
119-
@functools.wraps(func)
120-
async def async_wrapper(*args, **kwargs):
121-
# Any necessary async setup
122-
return await func(*args, **kwargs)
123-
124-
wrapped = async_wrapper
125-
runtime_mode = "async"
126-
else:
127-
# Use existing sync wrapper
128-
wrapped = existing_sync_wrapper(func)
129-
runtime_mode = "sync"
130-
131-
# Set metadata
132-
endpoint = create_endpoint(
133-
# ... existing endpoint config ...
134-
runtime_mode=runtime_mode
135-
)
136-
_util.set_func_endpoint_attr(wrapped, endpoint)
137-
138-
return wrapped
139-
140-
return decorator
141-
```
115+
#### 2.2 Shared Implementation
116+
To avoid code duplication, we extracted shared business logic:
117+
- `_validate_on_call_request_headers()` - Validates headers and method
118+
- `_process_on_call_request_body()` - Processes request body after reading
119+
- `_format_on_call_response()` - Formats successful responses
120+
- `_format_on_call_error()` - Formats error responses
121+
- `_add_cors_headers_to_response()` - Adds CORS headers to any response
122+
123+
The decorators use a shared implementation with an `asgi` parameter to differentiate between sync and async modes.
142124

143125
#### 2.2 HTTP Functions Special Handling
144126
HTTP functions need special care because the request type changes:
@@ -176,16 +158,25 @@ We'll need to handle this in the type system and potentially in request processi
176158

177159
### HTTP Functions
178160
```python
161+
from firebase_functions import https_fn
162+
from firebase_functions.aio import https_fn as async_https_fn
163+
179164
# Sync (existing)
180165
@https_fn.on_request()
181166
def sync_http(request: Request) -> Response:
182167
return Response("Hello sync")
183168

184169
# Async (new)
185-
@https_fn.on_request()
170+
@async_https_fn.on_request()
186171
async def async_http(request) -> Response: # Will be Starlette Request
187172
result = await some_async_api_call()
188173
return Response(f"Hello async: {result}")
174+
175+
# Sync function in aio namespace (also supported)
176+
@async_https_fn.on_request()
177+
def sync_in_async_http(request) -> Response:
178+
# This sync function will run in ASGI's thread pool
179+
return Response("Hello from sync in async")
189180
```
190181

191182
### Firestore Functions
@@ -232,12 +223,26 @@ async def async_process_message(event: CloudEvent[MessagePublishedData]) -> None
232223
3. Update documentation and examples
233224
4. Release as minor version update (backward compatible)
234225

226+
## Implementation Status
227+
228+
### Completed (Phase 1)
229+
- ✅ HTTP functions (on_request and on_call) with async support
230+
- ✅ Shared business logic to avoid code duplication
231+
- ✅ CORS handling for async functions
232+
- ✅ Type safety with overloads
233+
- ✅ Support for both sync and async functions in aio namespace
234+
- ✅ Comprehensive tests
235+
236+
### Remaining Work
237+
- Event-triggered functions (Firestore, Database, Storage, etc.)
238+
- Documentation and examples
239+
- Integration with Firebase CLI for deployment
240+
235241
## Open Questions
236242

237243
1. Should we support both Flask and Starlette response types for async HTTP functions?
238244
2. How should we handle async context managers and cleanup?
239245
3. Should we provide async versions of Firebase Admin SDK operations?
240-
4. What's the best way to handle errors in async functions?
241246

242247
## Next Steps
243248

src/firebase_functions/aio/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2022 Google Inc.
1+
# Copyright 2025 Google Inc.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.

src/firebase_functions/aio/https_fn.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2022 Google Inc.
1+
# Copyright 2025 Google Inc.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)