## Bug description

strtobool is used in several places where it will cause deprecation warning in Pythin 3.10 and error in Python 3.12 since distutils will be removed in Python 3.12 .

Reference : https://www.python.org/dev/peps/pep-0632/

```
rg distutils                     
posthog/api/annotation.py
1:from distutils.util import strtobool

posthog/api/dashboard.py
2:from distutils.util import strtobool

posthog/api/insight.py
1:from distutils.util import strtobool

posthog/models/filters/mixins/common.py
4:from distutils.util import strtobool

posthog/settings.py
17:from distutils.util import strtobool
```

## Expected behavior

It's a good idea to vendor in the function as it's a short one.

## Environment

- [ ] PostHog Cloud
- [ ] self-hosted PostHog, version/commit: _please provide_


#### *Thank you* for your bug report – we love squashing them!

posthog/api/insight.py
team = self.team
        refresh = request.GET.get("refresh", None)
        filter = Filter(request=request, data={"insight": INSIGHT_FUNNELS})
        cache_key = generate_cache_key("{}_{}".format(filter.toJSON(), team.pk))
        result = {"loading": True}
        if refresh:
            cache.delete(cache_key)
        else:
            cached_result = get_safe_cache(cache_key)
            if cached_result:
                task_id = cached_result.get("task_id", None)
                if not task_id:
                    return cached_result["result"]
                else:
                    return {"result": result}
        payload = {"filter": filter.toJSON(), "team_id": team.pk}
        task = update_cache_item_task.delay(cache_key, CacheType.FUNNEL, payload)
        if not task.ready():
            task_id = task.id
            cache.set(cache_key, {"task_id": task_id}, 180)  
        self._refresh_dashboard(request=request)
        return {"result": result}
    
    
    
    
    
    
    @action(methods=["GET"], detail=False)
    def retention(self, request: request.Request, *args: Any, **kwargs: Any) -> Response: