[Feature Request] Suggest Providing activities extraction utilities to get them from a class and a module
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Stack tecnológico
- python
- Área
- developer-experience
Línea de trabajo
Empieza leyendo la implementación de activity.defn y el módulo activity.py, especialmente cómo se almacenan las definiciones de actividad. Revisa los casos solicitados de extracción de clases, instancias y módulos, y las pruebas proporcionadas; el trabajo estará terminado cuando exista una API de utilidades documentada con cobertura para esos casos.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Is your feature request related to a problem? Please describe.
Creating activities and decorating them is easy using activy.def in python
Making sure that they are all included in worker launch is more difficult.
Describe the solution you'd like
It would be helpful if a utility was provided that allowed
- extracting activities from a class
- extracting activities from a class instance
- extracting activities from a module
Below is a sample implementation for extraction from class and class instances, assuming async method implementations that uses ast and inspection.
It looks like one could find which methods are decorate by checking if fn.__temporal_activity_definition but that is a private variable name and is not exposed in the temporalio activity.py module. Code that uses __temporal_activity_definition would be simpler and not invoking ast.parse(inspect.getsource(cls)) is preferrable.
import ast
import inspect
import typing
class _MyNodeVisitor(ast.NodeVisitor):
def __init__(self):
self.fn_name_to_decorators: dict[str, set[str]] = {}
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef):
self.fn_name_to_decorators[node.name] = set()
for decorator in node.decorator_list:
print(decorator)
if isinstance(decorator, ast.Call):
# noinspection PyUnresolvedReferences
name = (
decorator.func.attr
if isinstance(decorator.func, ast.Attribute)
else decorator.func.id
)
else:
# noinspection PyUnresolvedReferences
name = (
decorator.value.id + "." + decorator.attr
if isinstance(decorator, ast.Attribute)
else decorator.id
)
self.fn_name_to_decorators[node.name].add(name)
def get_fn_name_to_decorators(self) -> dict[str, set[str]]:
return self.fn_name_to_decorators
class ActivitiesListProvider:
@classmethod
def __get_activities(
cls,
instance: typing.Union[
type["ActivitiesListProvider"], "ActivitiesListProvider"
],
) -> list[typing.Callable]:
visitor = _MyNodeVisitor()
visitor.visit(ast.parse(inspect.getsource(cls)))
fn_name_to_decorators: dict[str, set[str]] = visitor.get_fn_name_to_decorators()
activities = []
for fn_name, decorators in fn_name_to_decorators.items():
if "activity.defn" in decorators:
method = getattr(instance, fn_name)
activities.append(method)
return activities
def get_activities_from_instance(self) -> list[typing.Callable]:
return self.__get_activities(self)
@classmethod
def get_activities_from_cls(cls) -> list[typing.Callable]:
return cls.__get_activities(cls)
And some Tests:
from workflow_metrics.temporal_tools import activities_class
from temporalio import activity
class SomeActivities(activities_class.ActivitiesListProvider):
@activity.defn
async def instance_method_activity(self):
pass
@activity.defn
async def class_method_activity(self):
pass
@staticmethod
@activity.defn
async def static_method_activity():
pass
def test_get_activities_from_cls():
assert SomeActivities.get_activities_from_cls() == [
SomeActivities.instance_method_activity,
SomeActivities.class_method_activity,
SomeActivities.static_method_activity,
]
class ActivitiesClassThatNeedsInstance(activities_class.ActivitiesListProvider):
@activity.defn
async def instance_method_activity(self):
pass
@activity.defn
async def class_method_activity(self):
pass
@staticmethod
@activity.defn
async def static_method_activity():
pass
def test_get_activities_from_instance():
inst = ActivitiesClassThatNeedsInstance()
assert inst.get_activities_from_instance() == [
inst.instance_method_activity,
inst.class_method_activity,
inst.static_method_activity,
]
Additional context
In code that I am working on activities are mainly defined in one module when they are fns and in class methods.
- Lenguaje dominante
- Python
- Estrellas
- 1.2k
- Forks
- 245
- Merge medio
- 4 d 13 h
- PR fusionados (30 d)
- 50
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de temporalio/sdk-python
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
temporalio/sdk-python#1897 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
temporalio/sdk-python#496 ·
Los mantenedores suelen responder en 1 día
-
[Bug] Heartbeat Task Slot information is not pulled when MetricBuffer is configuredPosiblemente ocupada @Sushisource la tomó hace 24 días. Abiertobug
temporalio/sdk-python#1817 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Cloud CI Skips Nexus TestsQuizá libre de nuevo @tconley1428 la tomó hace 52 días y no hay ningún pull request abierto. Abierto
temporalio/sdk-python#1704 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Windows ARM64 wheel supportAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
temporalio/sdk-python#1592 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
Todos los issues de temporalio/sdk-python
Issues similares
-
comp/tools duplicate P2 sweeper:risk-compatibility tool/mcp type/bug
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
NousResearch/hermes-agent#132042 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
deepset-ai/haystack#13092 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
EverMind-AI/Raven#845 ·
Los mantenedores suelen responder en 1 día
-
[Feature] 移除「切换到旧版知识库」入口Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
AstrBotDevs/AstrBot#10340 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
BasedHardware/omi#20401 · 1 comentario ·
Los mantenedores suelen responder en 1 día