code: def activities(self, name=None, pk=None, scope=None, **kwargs):
          # type: (Optional[str], Optional[str], Optional[str], **Any) -> List[Activity]
          
          request_params = {
              'id': pk,
              'name': name,
              'scope': scope
          }
  
          # update the fields query params
          # for 'kechain.core.wim >= 2.0.0' add additional API params
          if self.match_app_version(label='wim', version='>=2.0.0', default=False):
              request_params.update(API_EXTRA_PARAMS['activity'])
  
          if kwargs:
              request_params.update(**kwargs)
  
          response = self._request('GET', self._build_url('activities'), params=request_params)
  
          if response.status_code != requests.codes.ok:  # pragma: no cover
              raise NotFoundError("Could not retrieve activities. Server responded with {}".format(str(response)))
  
          data = response.json()
  
          # for 'kechain.core.wim >= 2.0.0' we return Activity2, otherwise Activity1
          if self.match_app_version(label='wim', version='<2.0.0', default=True):
              # WIM1
              return [Activity(a, client=self) for a in data['results']]
          else:
              # WIM2
              return [Activity2(a, client=self) for a in data['results']]
docs: Search for activities with optional name, pk and scope filter.
  
          If additional `keyword=value` arguments are provided, these are added to the request parameters. Please
          refer to the documentation of the KE-chain API for additional query parameters.
  
          :param pk: id (primary key) of the activity to retrieve
          :type pk: basestring or None
          :param name: filter the activities by name
          :type name: basestring or None
          :param scope: filter by scope id
          :type scope: basestring or None
          :return: list of :class:`models.Activity`
          :raises NotFoundError: If no `Activities` are found