smarta2a 0.1.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ py_a2a - A Python package for implementing an A2A server
4
4
 
5
5
  __version__ = "0.1.0"
6
6
 
7
- from .server import FastA2A
7
+ from .server import SmartA2A
8
+ from . import types as models
8
9
 
9
- __all__ = ["FastA2A", "models"]
10
+ __all__ = ["SmartA2A", "models"]
@@ -48,9 +48,14 @@ from .types import (
48
48
  A2AStatus,
49
49
  A2AStreamResponse,
50
50
  TaskSendParams,
51
+ SetTaskPushNotificationRequest,
52
+ GetTaskPushNotificationRequest,
53
+ SetTaskPushNotificationResponse,
54
+ GetTaskPushNotificationResponse,
55
+ TaskPushNotificationConfig,
51
56
  )
52
57
 
53
- class FastA2A:
58
+ class SmartA2A:
54
59
  def __init__(self, name: str, **fastapi_kwargs):
55
60
  self.name = name
56
61
  self.handlers: Dict[str, Callable] = {}
@@ -96,7 +101,7 @@ class FastA2A:
96
101
  if method in self._registered_decorators:
97
102
  raise RuntimeError(
98
103
  f"@{handler_name} decorator for method '{method}' "
99
- f"can only be used once per FastA2A instance"
104
+ f"can only be used once per SmartA2A instance"
100
105
  )
101
106
 
102
107
  if handler_type == "handler":
@@ -129,6 +134,18 @@ class FastA2A:
129
134
  self._register_handler("tasks/cancel", func, "task_cancel", "handler")
130
135
  return func
131
136
  return decorator
137
+
138
+ def set_notification(self):
139
+ def decorator(func: Callable[[SetTaskPushNotificationRequest], None]) -> Callable:
140
+ self._register_handler("tasks/pushNotification/set", func, "set_notification", "handler")
141
+ return func
142
+ return decorator
143
+
144
+ def get_notification(self):
145
+ def decorator(func: Callable[[GetTaskPushNotificationRequest], Union[TaskPushNotificationConfig, GetTaskPushNotificationResponse]]):
146
+ self._register_handler("tasks/pushNotification/get", func, "get_notification", "handler")
147
+ return func
148
+ return decorator
132
149
 
133
150
  async def process_request(self, request_data: dict) -> JSONRPCResponse:
134
151
  try:
@@ -141,6 +158,10 @@ class FastA2A:
141
158
  return self._handle_get_task(request_data)
142
159
  elif method == "tasks/cancel":
143
160
  return self._handle_cancel_task(request_data)
161
+ elif method == "tasks/pushNotification/set":
162
+ return self._handle_set_notification(request_data)
163
+ elif method == "tasks/pushNotification/get":
164
+ return self._handle_get_notification(request_data)
144
165
  else:
145
166
  return self._error_response(
146
167
  request_data.get("id"),
@@ -422,6 +443,102 @@ class FastA2A:
422
443
  error=InternalError(data=str(e))
423
444
  )
424
445
 
446
+ def _handle_set_notification(self, request_data: dict) -> SetTaskPushNotificationResponse:
447
+ try:
448
+ request = SetTaskPushNotificationRequest.model_validate(request_data)
449
+ handler = self.handlers.get("tasks/pushNotification/set")
450
+
451
+ if not handler:
452
+ return SetTaskPushNotificationResponse(
453
+ id=request.id,
454
+ error=MethodNotFoundError()
455
+ )
456
+
457
+ try:
458
+ # Execute handler (may or may not return something)
459
+ raw_result = handler(request)
460
+
461
+ # If handler returns nothing - build success response from request params
462
+ if raw_result is None:
463
+ return SetTaskPushNotificationResponse(
464
+ id=request.id,
465
+ result=request.params
466
+ )
467
+
468
+ # If handler returns a full response object
469
+ if isinstance(raw_result, SetTaskPushNotificationResponse):
470
+ return raw_result
471
+
472
+
473
+ except Exception as e:
474
+ if isinstance(e, JSONRPCError):
475
+ return SetTaskPushNotificationResponse(
476
+ id=request.id,
477
+ error=e
478
+ )
479
+ return SetTaskPushNotificationResponse(
480
+ id=request.id,
481
+ error=InternalError(data=str(e))
482
+ )
483
+
484
+ except ValidationError as e:
485
+ return SetTaskPushNotificationResponse(
486
+ id=request_data.get("id"),
487
+ error=InvalidRequestError(data=e.errors())
488
+ )
489
+
490
+
491
+ def _handle_get_notification(self, request_data: dict) -> GetTaskPushNotificationResponse:
492
+ try:
493
+ request = GetTaskPushNotificationRequest.model_validate(request_data)
494
+ handler = self.handlers.get("tasks/pushNotification/get")
495
+
496
+ if not handler:
497
+ return GetTaskPushNotificationResponse(
498
+ id=request.id,
499
+ error=MethodNotFoundError()
500
+ )
501
+
502
+ try:
503
+ raw_result = handler(request)
504
+
505
+ if isinstance(raw_result, GetTaskPushNotificationResponse):
506
+ return raw_result
507
+ else:
508
+ # Validate raw_result as TaskPushNotificationConfig
509
+ config = TaskPushNotificationConfig.model_validate(raw_result)
510
+ return GetTaskPushNotificationResponse(
511
+ id=request.id,
512
+ result=config
513
+ )
514
+ except ValidationError as e:
515
+ return GetTaskPushNotificationResponse(
516
+ id=request.id,
517
+ error=InvalidParamsError(data=e.errors())
518
+ )
519
+ except Exception as e:
520
+ if isinstance(e, JSONRPCError):
521
+ return GetTaskPushNotificationResponse(
522
+ id=request.id,
523
+ error=e
524
+ )
525
+ return GetTaskPushNotificationResponse(
526
+ id=request.id,
527
+ error=InternalError(data=str(e))
528
+ )
529
+
530
+ except ValidationError as e:
531
+ return GetTaskPushNotificationResponse(
532
+ id=request_data.get("id"),
533
+ error=InvalidRequestError(data=e.errors())
534
+ )
535
+ except json.JSONDecodeError as e:
536
+ return GetTaskPushNotificationResponse(
537
+ id=request_data.get("id"),
538
+ error=JSONParseError(data=str(e))
539
+ )
540
+
541
+
425
542
  def _normalize_artifacts(self, content: Any) -> List[Artifact]:
426
543
  """Handle both A2AResponse content and regular returns"""
427
544
  if isinstance(content, Artifact):
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smarta2a
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: A Python package for creating servers and clients following Google's Agent2Agent protocol
5
- Project-URL: Homepage, https://github.com/siddharthsma/fasta2a
6
- Project-URL: Bug Tracker, https://github.com/siddharthsma/fasta2a/issues
5
+ Project-URL: Homepage, https://github.com/siddharthsma/smarta2a
6
+ Project-URL: Bug Tracker, https://github.com/siddharthsma/smarta2a/issues
7
7
  Author-email: Siddharth Ambegaonkar <siddharthsma@gmail.com>
8
8
  License-File: LICENSE
9
9
  Classifier: License :: OSI Approved :: MIT License
@@ -16,7 +16,7 @@ Requires-Dist: sse-starlette
16
16
  Requires-Dist: uvicorn
17
17
  Description-Content-Type: text/markdown
18
18
 
19
- # FastA2A
19
+ # SmartA2A
20
20
 
21
21
  A Python package for creating a server following Google's Agent2Agent protocol
22
22
 
@@ -39,15 +39,15 @@ A Python package for creating a server following Google's Agent2Agent protocol
39
39
  ## Installation
40
40
 
41
41
  ```bash
42
- pip install fasta2a
42
+ pip install smarta2a
43
43
  ```
44
44
 
45
45
  ## Simple Echo Server Implementation
46
46
 
47
47
  ```python
48
- from fasta2a import FastA2A
48
+ from smarta2a import SmartA2A
49
49
 
50
- app = FastA2A("EchoServer")
50
+ app = SmartA2A("EchoServer")
51
51
 
52
52
  @app.on_send_task()
53
53
  def handle_task(request):
@@ -81,8 +81,8 @@ To set up the development environment:
81
81
 
82
82
  ```bash
83
83
  # Clone the repository
84
- git clone https://github.com/siddharthsma/fasta2a.git
85
- cd fasta2a
84
+ git clone https://github.com/siddharthsma/smarta2a.git
85
+ cd smarta2a
86
86
 
87
87
  # Create and activate virtual environment
88
88
  python -m venv venv
@@ -0,0 +1,7 @@
1
+ smarta2a/__init__.py,sha256=f_RqeaAHiBXO0O8n2kR8EBLGM3ezNwmR-CV-xHeOHLM,182
2
+ smarta2a/server.py,sha256=lFUlAz4TEeEXCs2bgJmMTN7JpZTwYEKXyt4KWEQwS6U,30915
3
+ smarta2a/types.py,sha256=_UuFtOsnHIIqfQ2m_FiIBBp141iYmhpPGgxE0jmHSHg,10807
4
+ smarta2a-0.2.1.dist-info/METADATA,sha256=H4os9rBnBzByJI1FWr7vYW2w8Or8PInU7XtmwsHCIcY,2478
5
+ smarta2a-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ smarta2a-0.2.1.dist-info/licenses/LICENSE,sha256=ECMEVHuFkvpEmH-_A9HSxs_UnnsUqpCkiAYNHPCf2z0,1078
7
+ smarta2a-0.2.1.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- fasta2a/__init__.py,sha256=lW8fJ0XHZJVZC4Oy18UxJjxtxuSco878tV6wAKiCzw0,150
2
- fasta2a/server.py,sha256=Ge0eh6Go8P9LUmQwmFysTx2YSvRoWk3UIkVh7o-mAHU,26115
3
- fasta2a/types.py,sha256=_UuFtOsnHIIqfQ2m_FiIBBp141iYmhpPGgxE0jmHSHg,10807
4
- smarta2a-0.1.0.dist-info/METADATA,sha256=a8EA5KXN0YIwnkpoLSOJMh2gi8Vpn0XLes6lWvlYa0Y,2469
5
- smarta2a-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
- smarta2a-0.1.0.dist-info/licenses/LICENSE,sha256=ECMEVHuFkvpEmH-_A9HSxs_UnnsUqpCkiAYNHPCf2z0,1078
7
- smarta2a-0.1.0.dist-info/RECORD,,
File without changes