Repository: ansible/awx
File: awx/api/views/__init__.py (Python)

Code before:
                self.permission_denied(request)
            else:
                can_access, messages = request.user.can_access_with_errors(self.model, 'add', request.data)
                if not can_access:
                    self.permission_denied(request, message=messages)

        super(JobTemplateList, self).check_permissions(request)


class JobTemplateDetail(RelatedJobsPreventDeleteMixin, RetrieveUpdateDestroyAPIView):
    model = models.JobTemplate
    serializer_class = serializers.JobTemplateSerializer
    always_allow_superuser = False
    resource_purpose = 'job template detail'


class JobTemplateLaunch(RetrieveAPIView):
    model = models.JobTemplate
    obj_permission_type = 'start'
    serializer_class = serializers.JobLaunchSerializer
    always_allow_superuser = False
    resource_purpose = 'launch a job from a job template'

    @extend_schema_if_available(
        extensions={'x-ai-description': 'Retrieve details for a job template launch'},
    )
    def update_raw_data(self, data):
        """
        Use the ID of a job template to retrieve its launch details.
        """
        try:
            obj = self.get_object()
        except PermissionDenied:
            return data
        extra_vars = data.pop('extra_vars', None) or {}
        if obj:
            needed_passwords = obj.passwords_needed_to_start
            if needed_passwords:
                data['credential_passwords'] = {}
                for p in needed_passwords:
                    data['credential_passwords'][p] = u''
            else:
                data.pop('credential_passwords')
            for v in obj.variables_needed_to_start:
                extra_vars.setdefault(v, u'')
            if extra_vars:
                data['extra_vars'] = extra_vars
            modified_ask_mapping = models.JobTemplate.get_ask_mapping()
            modified_ask_mapping.pop('extra_vars')
            for field, ask_field_name in modified_ask_mapping.items():
                if not getattr(obj, ask_field_name):

Review comment (bug):
I could be wrong, but `update_raw_data` isn't externally mapped to any particular endpoint, and I expect this will not put this text into the generated schema, which is your intent.

A GET to /api/v2/job_templates/N/launch/, which I think this is for, also isn't particularly useful or clear. It gives general information about the job template, and other fields related to what you need for launching it, and would word it somehow to that effect.

Code after:
            if request.user.is_anonymous:
                self.permission_denied(request)
            else:
                can_access, messages = request.user.can_access_with_errors(self.model, 'add', request.data)
                if not can_access:
                    self.permission_denied(request, message=messages)

        super(JobTemplateList, self).check_permissions(request)


class JobTemplateDetail(RelatedJobsPreventDeleteMixin, RetrieveUpdateDestroyAPIView):
    model = models.JobTemplate
    serializer_class = serializers.JobTemplateSerializer
    always_allow_superuser = False
    resource_purpose = 'job template detail'


@extend_schema_view(
    retrieve=extend_schema(
        extensions={'x-ai-description': 'List job template launch criteria'},
    )
)
class JobTemplateLaunch(RetrieveAPIView):
    model = models.JobTemplate
    obj_permission_type = 'start'
    serializer_class = serializers.JobLaunchSerializer
    always_allow_superuser = False
    resource_purpose = 'launch a job from a job template'

    def update_raw_data(self, data):
        """
        Use the ID of a job template to retrieve its launch details.
        """
        try:
            obj = self.get_object()
        except PermissionDenied:
            return data
        extra_vars = data.pop('extra_vars', None) or {}
        if obj:
            needed_passwords = obj.passwords_needed_to_start
            if needed_passwords:
                data['credential_passwords'] = {}
                for p in needed_passwords:
                    data['credential_passwords'][p] = u''
            else:
                data.pop('credential_passwords')
            for v in obj.variables_needed_to_start:
                extra_vars.setdefault(v, u'')
            if extra_vars:
                data['extra_vars'] = extra_vars
            modified_ask_mapping = models.JobTemplate.get_ask_mapping()