"""
ViewSet for replicating repositories and distributions from an upstream Pulp
"""
from django.conf import settings
from drf_spectacular.utils import extend_schema
from rest_framework import mixins
from rest_framework.decorators import action

from pulpcore.app.models import TaskGroup, UpstreamPulp
from pulpcore.app.serializers import AsyncOperationResponseSerializer, UpstreamPulpSerializer
from pulpcore.app.viewsets import NamedModelViewSet
from pulpcore.app.response import TaskGroupOperationResponse
from pulpcore.app.tasks import replicate_distributions
from pulpcore.tasking.tasks import dispatch


class UpstreamPulpViewSet(
    NamedModelViewSet,
    mixins.CreateModelMixin,
    mixins.RetrieveModelMixin,
    mixins.ListModelMixin,
    mixins.DestroyModelMixin,
    mixins.UpdateModelMixin,
):
    """API for configuring an upstream Pulp to replicate. This API is provided as a tech preview."""

    queryset = UpstreamPulp.objects.all()
    endpoint_name = "upstream-pulps"
    serializer_class = UpstreamPulpSerializer
    ordering = "-pulp_created"

    @extend_schema(
        summary="Replicate",
        description="Trigger an asynchronous repository replication task group. This API is "
        "provided as a tech preview.",
        responses={202: AsyncOperationResponseSerializer},
    )
    @action(detail=True, methods=["post"])
    def replicate(self, request, pk):
        """
        Triggers an asynchronous repository replication operation.
        """
        server = UpstreamPulp.objects.get(pk=pk)
        task_group = TaskGroup.objects.create(description=f"Replication of {server.name}")

        uri = "/api/v3/servers/"
        if settings.DOMAIN_ENABLED:
            uri = f"/{request.domain.name}{uri}"

        dispatch(
            replicate_distributions,
            exclusive_resources=[uri],
            kwargs={"server_pk": pk},
            task_group=task_group,
        )

        return TaskGroupOperationResponse(task_group, request)

pulpcore/app/viewsets/replica.py
"""
ViewSet for replicating repositories and distributions from an upstream Pulp
"""
from django.conf import settings
from drf_spectacular.utils import extend_schema
from rest_framework import mixins
from rest_framework.decorators import action

from pulpcore.app.models import TaskGroup, UpstreamPulp
from pulpcore.app.serializers import AsyncOperationResponseSerializer, UpstreamPulpSerializer
from pulpcore.app.viewsets import NamedModelViewSet
from pulpcore.app.response import TaskGroupOperationResponse
from pulpcore.app.tasks import replicate_distributions
from pulpcore.tasking.tasks import dispatch


class UpstreamPulpViewSet(
    NamedModelViewSet,
    mixins.CreateModelMixin,
    mixins.RetrieveModelMixin,
    mixins.ListModelMixin,
    mixins.DestroyModelMixin,
    mixins.UpdateModelMixin,
):
    """API for configuring an upstream Pulp to replicate. This API is provided as a tech preview."""

    queryset = UpstreamPulp.objects.all()
    endpoint_name = "upstream-pulps"
    serializer_class = UpstreamPulpSerializer
    ordering = "-pulp_created"

    @extend_schema(
        summary="Replicate",
        description="Trigger an asynchronous repository replication task group. This API is "
        "provided as a tech preview.",
        request=None,
        responses={202: AsyncOperationResponseSerializer},
    )
    @action(detail=True, methods=["post"])
    def replicate(self, request, pk):
        """
        Triggers an asynchronous repository replication operation.
        """
        server = UpstreamPulp.objects.get(pk=pk)
        task_group = TaskGroup.objects.create(description=f"Replication of {server.name}")

        uri = "/api/v3/servers/"
        if settings.DOMAIN_ENABLED:
            uri = f"/{request.domain.name}{uri}"

        dispatch(
            replicate_distributions,
            exclusive_resources=[uri],
            kwargs={"server_pk": pk},
            task_group=task_group,
        )

        return TaskGroupOperationResponse(task_group, request)

pulpcore/app/viewsets/replica.py
diff --git a/CHANGES/3995.bugfix b/CHANGES/3995.bugfix
new file mode 100644
index 0000000000..acfdd5ad32
--- /dev/null
+++ b/CHANGES/3995.bugfix
@@ -0,0 +1 @@
+Fix api schema of the `upstream_pulp_replicate` operation requiring no body.
diff --git a/pulpcore/app/viewsets/replica.py b/pulpcore/app/viewsets/replica.py
index 5d9d8aa8b7..666f671b38 100644
--- a/pulpcore/app/viewsets/replica.py
+++ b/pulpcore/app/viewsets/replica.py
@@ -33,6 +33,7 @@ class UpstreamPulpViewSet(
         summary="Replicate",
         description="Trigger an asynchronous repository replication task group. This API is "
         "provided as a tech preview.",
+        request=None,
         responses={202: AsyncOperationResponseSerializer},
     )
     @action(detail=True, methods=["post"])

RESTAPI document fix for Upstream Pulp Replication API
**Version**
Pulp installed through the Python modules.
"core:3.28.0"
"certguard:3.28.0"
"file:3.28.0"
"python:3.28.0"
"rpm:3.28.0"

**Describe the bug**
Why the attributes of **upstream_pulps_create**/**update**  is mentioned again in the **upstream_pulps_replicate" document? Are those attributes (base_url, api_root, domain,...) used at time making an API request "https://PULP-SERVER/pulp/api/v3/upstream_pulps/{object_id}/replicate/"?

**To Reproduce**
None.

**Expected behavior**
A fix is required in the REST API document.

**Additional context**
Create Upstream Pulp API document: https://docs.pulpproject.org/pulpcore/restapi.html#tag/Upstream-Pulps/operation/upstream_pulps_create
Upstream Replication API document: https://docs.pulpproject.org/pulpcore/restapi.html#tag/Upstream-Pulps/operation/upstream_pulps_replicate


