Skip to content

Merges release 1.15 into main #788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 38 commits into from
Closed
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
96b3ccf
Bump fossas/fossa-action from 1.3.3 to 1.4.0 (#732)
dependabot[bot] Sep 11, 2024
face17e
Fixes missing docker-compose in examples (#736)
elena-kolevska Oct 21, 2024
eb97597
Bidirectional streaming for pubsub (#735)
elena-kolevska Oct 25, 2024
4802cf0
Makes streaming Subscription iterable (#751)
elena-kolevska Nov 11, 2024
1ebe2e5
Makes data argument optional on transactional delete (#752)
elena-kolevska Nov 21, 2024
1947d49
Bump codecov/codecov-action from 4 to 5 (#753)
dependabot[bot] Nov 21, 2024
7881ba3
remove alpha for workflow stable release (#760)
hhunter-ms Dec 19, 2024
cd4bd58
Replace deprecated tox.ini option (#762)
emsearcy Dec 19, 2024
cbf8361
Add Actor Mocks (#750)
lor1113 Jan 2, 2025
beff217
Fixes try_add_state in actor state manger (#756)
elena-kolevska Jan 2, 2025
901af34
Integration test for http invocation (#758)
elena-kolevska Jan 2, 2025
6105bd3
fixes missing state store in test (#759)
elena-kolevska Jan 2, 2025
c4c1255
Mark workflows API functions as deprecated (#749)
famarting Jan 2, 2025
726067f
Removes support for 3.8 and adds 3.13 to test version matrix (#763)
elena-kolevska Jan 2, 2025
18a865e
Updates protos and fixes grpc-tools for protos generation (#766)
elena-kolevska Jan 9, 2025
5d01ddc
Add DaprInternalError.as_json_safe_dict for actors (#765)
Druid-of-Luhn Jan 9, 2025
5ca0c87
workflows: update durabletask dependency (#757)
famarting Jan 14, 2025
c91bc48
Temporarily enable the release workflow to be triggered manually
elena-kolevska Jan 21, 2025
54f87b2
Reverts temporary option
elena-kolevska Jan 21, 2025
11f1184
Temporarily enable the release workflow to be triggered manually
elena-kolevska Feb 25, 2025
7b96e6e
Updates versions for 1.15.0rc1 (#768)
elena-kolevska Jan 21, 2025
467c7ef
Adds tags for 1.15.0 RC1
elena-kolevska Jan 21, 2025
4dab633
Release 1.15.0 RC1
elena-kolevska Jan 21, 2025
6c0b25b
Temporarily enable the workflow to be dispatched manually
elena-kolevska Jan 21, 2025
2141261
Release 1.15.0 RC2
elena-kolevska Jan 21, 2025
5f26e6f
Catch error in sdk when workflow instance not found (#771)
elena-kolevska Jan 28, 2025
d9e3cb7
Fix get_worfklow_state docstring to match fetch_payloads default (#772)
ajstewart Jan 28, 2025
5414679
Remove test sleep (#778)
elena-kolevska Feb 12, 2025
b9827af
Restores sleeps in test, as it was decided not to invest making synch…
elena-kolevska Feb 14, 2025
ad1d1de
Updates workflows docs to use the new workflows client (#780)
elena-kolevska Feb 20, 2025
80b82e9
Workflow fixes and improvements (#784)
elena-kolevska Feb 20, 2025
b6979b3
Retry streaming subscription on status UNKNOWN as well (#783)
elena-kolevska Feb 20, 2025
a29309d
Adds examples and docs for cloud events messages (#785)
elena-kolevska Feb 21, 2025
df196a5
Conversation API support (#787)
elena-kolevska Feb 24, 2025
7d0c037
Bumps version to RC3 (#779)
elena-kolevska Feb 24, 2025
db33a43
1.15.0
elena-kolevska Feb 27, 2025
48cd494
Dev version
elena-kolevska Mar 6, 2025
1de7c95
Updates docs error codes link
elena-kolevska Mar 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build-push-to-main.yaml
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python_ver: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python_ver: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python_ver }}
@@ -58,7 +58,7 @@ jobs:
run: |
tox -e py`echo "${{ matrix.python_ver }}" | sed 's/\.//g'`
- name: Upload test coverage
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
publish:
needs: build
if: github.event_name != 'pull_request'
5 changes: 3 additions & 2 deletions .github/workflows/build-tag.yaml
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ on:
- grpc-v*
- flask-v*
- fastapi-v*
workflow_dispatch:

jobs:
lint:
@@ -43,7 +44,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python_ver: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python_ver: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python_ver }}
@@ -61,7 +62,7 @@ jobs:
run: |
tox -e py`echo "${{ matrix.python_ver }}" | sed 's/\.//g'`
- name: Upload test coverage
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
publish:
needs: build
if: github.event_name != 'pull_request'
4 changes: 2 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python_ver: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python_ver: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python_ver }}
@@ -64,4 +64,4 @@ jobs:
run: |
tox -e py`echo "${{ matrix.python_ver }}" | sed 's/\.//g'`
- name: Upload test coverage
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
4 changes: 2 additions & 2 deletions .github/workflows/fossa.yaml
Original file line number Diff line number Diff line change
@@ -43,12 +43,12 @@ jobs:
uses: actions/checkout@v4

- name: "Run FOSSA Scan"
uses: fossas/fossa-action@v1.3.3 # Use a specific version if locking is preferred
uses: fossas/fossa-action@v1.4.0 # Use a specific version if locking is preferred
with:
api-key: ${{ env.FOSSA_API_KEY }}

- name: "Run FOSSA Test"
uses: fossas/fossa-action@v1.3.3 # Use a specific version if locking is preferred
uses: fossas/fossa-action@v1.4.0 # Use a specific version if locking is preferred
with:
api-key: ${{ env.FOSSA_API_KEY }}
run-tests: true
2 changes: 1 addition & 1 deletion .github/workflows/validate_examples.yaml
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python_ver: [3.8, 3.9, "3.10", "3.11", "3.12"]
python_ver: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Parse repository_dispatch payload
if: github.event_name == 'repository_dispatch'
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,9 @@
[![GitHub issue custom search in repo](https://img.shields.io/github/issues-search/dapr/python-sdk?query=type%3Aissue%20is%3Aopen%20label%3A%22good%20first%20issue%22&label=Good%20first%20issues&style=flat&logo=github)](https://github.com/dapr/python-sdk/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
[![Discord](https://img.shields.io/discord/778680217417809931?label=Discord&style=flat&logo=discord)](http://bit.ly/dapr-discord)
[![YouTube Channel Views](https://img.shields.io/youtube/channel/views/UCtpSQ9BLB_3EXdWAUQYwnRA?style=flat&label=YouTube%20views&logo=youtube)](https://youtube.com/@daprdev)
<!-- IGNORE_LINKS -->
[![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/daprdev?logo=x&style=flat)](https://twitter.com/daprdev)
<!-- END_IGNORE -->

[Dapr](https://docs.dapr.io/concepts/overview/) is a portable, event-driven, serverless runtime for building distributed applications across cloud and edge.

@@ -30,7 +32,7 @@ This includes the following packages:
### Prerequisites

* [Install Dapr standalone mode](https://github.com/dapr/cli#install-dapr-on-your-local-machine-self-hosted)
* [Install Python 3.8+](https://www.python.org/downloads/)
* [Install Python 3.9+](https://www.python.org/downloads/)

### Install Dapr python sdk

@@ -137,8 +139,7 @@ The generated files will be found in `docs/_build`.
## Generate gRPC Protobuf client

```sh
pip3 install -r dev-requirements.txt

pip3 install -r tools/requirements.txt
./tools/regen_grpcclient.sh
```

122 changes: 122 additions & 0 deletions dapr/actor/runtime/mock_actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
"""
Copyright 2023 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from __future__ import annotations

from datetime import timedelta
from typing import Any, Optional, TypeVar

from dapr.actor.id import ActorId
from dapr.actor.runtime._reminder_data import ActorReminderData
from dapr.actor.runtime._timer_data import TIMER_CALLBACK, ActorTimerData
from dapr.actor.runtime.actor import Actor
from dapr.actor.runtime.mock_state_manager import MockStateManager


class MockActor(Actor):
"""A mock actor class to be used to override certain Actor methods for unit testing.
To be used only via the create_mock_actor function, which takes in a class and returns a
mock actor object for that class.

Examples:
class SomeActorInterface(ActorInterface):
@actor_method(name="method")
async def set_state(self, data: dict) -> None:

class SomeActor(Actor, SomeActorInterface):
async def set_state(self, data: dict) -> None:
await self._state_manager.set_state('state', data)
await self._state_manager.save_state()

mock_actor = create_mock_actor(SomeActor, "actor_1")
assert mock_actor._state_manager._mock_state == {}
await mock_actor.set_state({"test":10})
assert mock_actor._state_manager._mock_state == {"test":10}
"""

def __init__(self, actor_id: str, initstate: Optional[dict]):
self.id = ActorId(actor_id)
self._runtime_ctx = None # type: ignore
self._state_manager = MockStateManager(self, initstate)

async def register_timer(
self,
name: Optional[str],
callback: TIMER_CALLBACK,
state: Any,
due_time: timedelta,
period: timedelta,
ttl: Optional[timedelta] = None,
) -> None:
"""Adds actor timer to self._state_manager._mock_timers.
Args:
name (str): the name of the timer to register.
callback (Callable): An awaitable callable which will be called when the timer fires.
state (Any): An object which will pass to the callback method, or None.
due_time (datetime.timedelta): the amount of time to delay before the awaitable
callback is first invoked.
period (datetime.timedelta): the time interval between invocations
of the awaitable callback.
ttl (Optional[datetime.timedelta]): the time interval before the timer stops firing
"""
name = name or self.__get_new_timer_name()
timer = ActorTimerData(name, callback, state, due_time, period, ttl)
self._state_manager._mock_timers[name] = timer # type: ignore

async def unregister_timer(self, name: str) -> None:
"""Unregisters actor timer from self._state_manager._mock_timers.

Args:
name (str): the name of the timer to unregister.
"""
self._state_manager._mock_timers.pop(name, None) # type: ignore

async def register_reminder(
self,
name: str,
state: bytes,
due_time: timedelta,
period: timedelta,
ttl: Optional[timedelta] = None,
) -> None:
"""Adds actor reminder to self._state_manager._mock_reminders.

Args:
name (str): the name of the reminder to register. the name must be unique per actor.
state (bytes): the user state passed to the reminder invocation.
due_time (datetime.timedelta): the amount of time to delay before invoking the reminder
for the first time.
period (datetime.timedelta): the time interval between reminder invocations after
the first invocation.
ttl (datetime.timedelta): the time interval before the reminder stops firing
"""
reminder = ActorReminderData(name, state, due_time, period, ttl)
self._state_manager._mock_reminders[name] = reminder # type: ignore

async def unregister_reminder(self, name: str) -> None:
"""Unregisters actor reminder from self._state_manager._mock_reminders..

Args:
name (str): the name of the reminder to unregister.
"""
self._state_manager._mock_reminders.pop(name, None) # type: ignore


T = TypeVar('T', bound=Actor)


def create_mock_actor(cls1: type[T], actor_id: str, initstate: Optional[dict] = None) -> T:
class MockSuperClass(MockActor, cls1): # type: ignore
pass

return MockSuperClass(actor_id, initstate) # type: ignore
Loading