Slide 1

Slide 1 text

Event-Driven asyncio: A Case Study of Trio's API Junya Fukuda PyCon US 2024

Slide 2

Slide 2 text

Who am I? 👤 •Junya Fukudaʢ@JunyaFffʣcalled “Jun” not “Junior” •Photos 📷 SNS post 👍 •Software Engineer at Groove X, inc. Here is today's code

Slide 3

Slide 3 text

Who am I? 👤 •book •Python Practical Recipes Here is today's code •Junya Fukudaʢ@JunyaFffʣcalled “Jun” not “Junior” •Photos 📷 SNS post 👍 •Software Engineer at Groove X, inc.

Slide 4

Slide 4 text

Who am I? 👤 •Expert Python Programming - Fourth Edition •Written by Tarek Ziadé, Michał Jaworski Here is today's code •Junya Fukudaʢ@JunyaFffʣcalled “Jun” not “Junior” •Photos 📷 SNS post 👍 •Software Engineer at Groove X, inc. •book •Python Practical Recipes

Slide 5

Slide 5 text

Who am I? 👤 •Expert Python Programming - Fourth Edition •Written by Tarek Ziadé, Michał Jaworski •Junya Fukudaʢ@JunyaFffʣcalled “Jun” not “Junior” •Photos 📷 SNS post 👍 •Software Engineer at Groove X, inc. •book •Python Practical Recipes Here is today's code

Slide 6

Slide 6 text

Thank you 🙏 I love Python async 🌷

Slide 7

Slide 7 text

Event-Driven async A Case Study of Trio's API

Slide 8

Slide 8 text

Python async, are you using it? ✋

Slide 9

Slide 9 text

Python async, are you using it? ✋ Thank You!

Slide 10

Slide 10 text

Python async, are you using it? ✋ Web? ✋

Slide 11

Slide 11 text

Python async, are you using it? ✋ Web? ✋ Database? ✋

Slide 12

Slide 12 text

Python async, are you using it? ✋ Web? ✋ Database? ✋ API calls? ✋

Slide 13

Slide 13 text

Python async, are you using it? ✋ Web? ✋ Database? ✋ API calls? ✋ Tasks? ✋

Slide 14

Slide 14 text

Trio? ✋ ✋ ✋

Slide 15

Slide 15 text

🤝🤝🤝🤝🤝

Slide 16

Slide 16 text

We use it in robotics.

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

Event-Driven async A Case Study of Trio's API

Slide 19

Slide 19 text

Event-Driven async A Case Study of Trio's API in production

Slide 20

Slide 20 text

Event-Driven async A Case Study of Trio's API in production

Slide 21

Slide 21 text

Today's Goal •Python async and robot use case

Slide 22

Slide 22 text

Today's Goal •Python async and robot use case •Event-Driven Example in Robot Development - Handling Multiple Inputs

Slide 23

Slide 23 text

Today's Goal •Python async and robot use case •Event-Driven Example in Robot Development - Handling Multiple Inputs •About Trio and Trio-util, asyncio

Slide 24

Slide 24 text

Today's Goal •Python async and robot use case •Event-Driven Example in Robot Development - Handling Multiple Inputs •About Trio and Trio-util, asyncio AsyncValue class

Slide 25

Slide 25 text

Today's Goal •Python async and robot use case •Event-Driven Example in Robot Development - Handling Multiple Inputs •About Trio and Trio-util, asyncio AsyncValue class •Handling Many Inputs in Async Apps - AsyncValue

Slide 26

Slide 26 text

Today's Goal •Python async and robot use case •Event-Driven Example in Robot Development - Handling Multiple Inputs •About Trio and Trio-util, asyncio AsyncValue class •Handling Many Inputs in Async Apps - AsyncValue 🌷

Slide 27

Slide 27 text

Today's Agenda •Python async and robot use case •Event-Driven Example in Robot Development - Handling Multiple Inputs

Slide 28

Slide 28 text

Today's Agenda •Python async and robot use case •Event-Driven Example in Robot Development - Handling Multiple Inputs •Why Python Async •Why Trio

Slide 29

Slide 29 text

Today's Agenda •Python async and robot use case •Event-Driven Example in Robot Development - Handling Multiple Inputs •Why Python Async •Why Trio

Slide 30

Slide 30 text

•Python async and robot use case

Slide 31

Slide 31 text

Why we chose Python Async for the robot decision-making engine

Slide 32

Slide 32 text

Why Python Async

Slide 33

Slide 33 text

Why Python Async •Their name is LOVOT

Slide 34

Slide 34 text

Why Python Async •Their name is LOVOTʢ "LOVE" ❤ and "ROBOT 🤖"ʣ

Slide 35

Slide 35 text

Why Python Async •Their name is LOVOT •Over 10,000 sold in Japan

Slide 36

Slide 36 text

Why Python Async •Their name is LOVOT •Over 10,000 sold in Japan •Equipped with many sensors

Slide 37

Slide 37 text

Why Python Async •൴Β͸֎ͷ৘ใΛͨ͘͞Μಘ͍ͯΔ

Slide 38

Slide 38 text

Why Python Async •൴Β͸֎ͷ৘ใΛͨ͘͞Μಘ͍ͯΔ &RVJQQFEXJUIPWFS$16DPSFT PWFS.$6T BOEPWFSTFOTPST

Slide 39

Slide 39 text

Why Python Async •Their name is LOVOT •Over 10,000 sold in Japan •Equipped with many sensors •Decision-Making and Environment

Slide 40

Slide 40 text

Why Python Async •Running many microservices

Slide 41

Slide 41 text

Why Python Async •Hardware-level information and cloud integration •Running many microservices

Slide 42

Slide 42 text

Why Python Async •Hardware-level information and cloud integration •Running many microservices •Limited HW resources

Slide 43

Slide 43 text

Why Python Async •Equipped with many sensors - many I/O •Limited HW resources

Slide 44

Slide 44 text

Why Python Async •Equipped with many sensors - many I/O •Limited HW resources

Slide 45

Slide 45 text

Why Python Async •Equipped with many sensors - many I/O •Limited HW resources • Python Async is perfect

Slide 46

Slide 46 text

Why Trio instead of asyncio?

Slide 47

Slide 47 text

Why Trio? •Structured Concurrency

Slide 48

Slide 48 text

Why Trio? •Robust cancellation •Structured Concurrency

Slide 49

Slide 49 text

Why Trio? •Robust cancellation •Structured Concurrency •User-friendly API

Slide 50

Slide 50 text

Why Trio? •Robust cancellation •Structured Concurrency •User-friendly API •However, this decision was made in the summer of 2017

Slide 51

Slide 51 text

Why Trio? •Robust cancellation •Structured Concurrency •User-friendly API No high-level APIs yet 😢 •However, this decision was made in the summer of 2017

Slide 52

Slide 52 text

Why do we need a user-friendly APIʁ 🤔

Slide 53

Slide 53 text

Why Trio? Python Engineers

Slide 54

Slide 54 text

Why Trio? Python Engineers

Slide 55

Slide 55 text

Why Trio? Python Engineers

Slide 56

Slide 56 text

Why Trio? Python Engineers Animators

Slide 57

Slide 57 text

Why Trio? Python Engineers Animators

Slide 58

Slide 58 text

Why Trio? Python Engineers Animators Kawaii Behavior

Slide 59

Slide 59 text

Why Trio? •Why do we need a user-friendly APIʁ •Animators also needed to write code.

Slide 60

Slide 60 text

Why Trio? •Why do we need a user-friendly APIʁ •Animators also needed to write code. 8F DIPTF 5SJP

Slide 61

Slide 61 text

•Event-Driven Example in Robot Development - Handling Multiple Inputs

Slide 62

Slide 62 text

•Event-Driven Example in Robot Development - Handling Multiple Inputs

Slide 63

Slide 63 text

Handling Multiple Inputs •Continuously watch for value changes

Slide 64

Slide 64 text

Handling Multiple Inputs •Continuously watch for value changes 👀

Slide 65

Slide 65 text

async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“) •Continuously watch for value changes 👀

Slide 66

Slide 66 text

•Continuously watch for value changes 👀 async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“)

Slide 67

Slide 67 text

async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“) •Continuously watch for value changes 👀

Slide 68

Slide 68 text

async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“) •Continuously watch for value changes 👀

Slide 69

Slide 69 text

•Continuously watch for value changes 👀

Slide 70

Slide 70 text

async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“) •Continuously watch for value changes 👀

Slide 71

Slide 71 text

•Continuously watch for value changes 👀 async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“)

Slide 72

Slide 72 text

Handling Multiple Inputs •AsyncValue Class 👀

Slide 73

Slide 73 text

Handling Multiple Inputs •AsyncValue Class 👀 •from trio-util

Slide 74

Slide 74 text

Handling Multiple Inputs •AsyncValue Class 👀 •from trio-util •wraps any value or awaitable

Slide 75

Slide 75 text

async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“) •Continuously watch for value changes 👀

Slide 76

Slide 76 text

async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“) •Continuously watch for value changes 👀

Slide 77

Slide 77 text

async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“) •Continuously watch for value changes 👀

Slide 78

Slide 78 text

async def main(): async with trio.open_nursery() as nursery: event1 = AsyncValue("idel 🤖😢") event2 = AsyncValue("idel 🤖😆") nursery.start_soon(fetch, event1, event2) with compose_values(event1=event1, event2=event2) as comp_event: async for v in comp_event.eventual_values(): print(f"doing something cute 🤖 {v=}“) •Continuously watch for value changes 👀

Slide 79

Slide 79 text

Handling Multiple Inputs •Inside AsyncValue •_async_value.py •class _ValueWrapper: •class _WaitQueue: •class _Result: •class _RefCountedDefaultDict

Slide 80

Slide 80 text

class _ValueWrapper: … def __hash__(self): try: return hash(self.value) except TypeError: return super().__hash__() def __eq__(self, other): return self.value.__eq__(other.value) def __call__(self, x, *args): return x == self.value •class _ValueWrapper:

Slide 81

Slide 81 text

class _RefCountedDefaultDict(defaultdict): """defaultdict offering deterministic collection of unreferenced keys""" … @contextmanager def open_ref(self, key): try: yield self[key] finally: self.refs_by_key[key] -= 1 if self.refs_by_key[key] == 0: del self[key] del self.refs_by_key[key] •class _RefCountedDefaultDict

Slide 82

Slide 82 text

Handling Multiple Inputs •Inside AsyncValue •Value Storage and Setting •Waiting for Value Changes: •Waiting for Transitions •Iterating Over Transitions •Waiting for Value Changes:

Slide 83

Slide 83 text

Handling Multiple Inputs •Event-Driven API Approach •Trio-util IUUQTHJUIVCDPN HSPPWFYUSJPVUJM

Slide 84

Slide 84 text

Handling Multiple Inputs •In the case of asyncio: •There is no API that performs the same function. •Synchronization Primitives •asyncio.Event, asyncio.Condition

Slide 85

Slide 85 text

Handling Multiple Inputs •Trio-util does not support anyio yet •There is no API that performs the same function. •asyncio-util IUUQTHJUIVCDPNKSGLBTZODJPVUJM Here is today's code

Slide 86

Slide 86 text

reference •Simplifying Python's Async with Trio •https://talkpython.fm/episodes/show/167/simplifying-pythons-async-with-trio •Higher level Python asyncio with AnyIO •https://talkpython.fm/episodes/show/385/higher-level-python-asyncio-with-anyio •groove-x / trio-util •https://github.com/groove-x/trio-util •Structured Concurrency - Martin Sústrik •https://250bpm.com/blog:71/

Slide 87

Slide 87 text

Would you like to see them?

Slide 88

Slide 88 text

Groove X will be a sponsor of PyCon JP 2024. See you in Tokyo. Sep27-28 2024

Slide 89

Slide 89 text

Groove X will be a sponsor of PyCon JP 2024. See you in Tokyo. Sep27-28 2024

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

Thank you for your attention 👋

Slide 92

Slide 92 text

Do you have a any Question? Feel free to ask questions on Twitter. (@junya ff f)