<p>I've defined this method, it should create a Kubernetes job for me.</p>

<pre><code>def make_job():
    job = client.V1Job()
    job.metadata = client.V1ObjectMeta()
    job.metadata.name = "process"
    job.spec = client.V1JobSpec()
    job.spec.template = client.V1PodTemplate()
    job.spec.template.spec = client.V1PodTemplateSpec()
    job.spec.template.spec.restart_policy = "Never"
    job.spec.template.spec.containers = [
        make_container()
    ]
    return job
</code></pre>

<p>However, it returns an error on this line.</p>

<pre><code>job.spec = client.V1JobSpec()
</code></pre>

<p>Saying</p>

<pre><code>ValueError: Invalid value for `template`, must not be `None`
</code></pre>

<p>I wonder if I am doing something wrong here, and if so, what am I doing wrong here?</p>

<p>EDIT:</p>

<p>I've solved the error with this change</p>

<pre><code>job.spec = client.V1JobSpec(template=client.V1PodTemplate)
</code></pre>

<p>As you have already figured out, it is not possible to construct a <code>Job.Spec</code> without injecting its <code>template</code>, something that is set on stone in the Job <a href="https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/" rel="nofollow noreferrer">documentation</a>.</p>

<blockquote>
  <p>The .spec.template is the only required field of the .spec. </p>
  
  <p>The .spec.template is a pod template. It has exactly the same schema as a
  pod, except it is nested and does not have an apiVersion or kind.</p>
</blockquote>

<p>Taking a look onto the Python's Kubernetes Client implementation of the <code>V1JobSpec</code>, it's possible to verify that the <code>spec</code> property is marked as <a href="https://github.com/kubernetes-client/python/blob/e057f273069de445a2d5a250ac5fe37d79671f3b/kubernetes/docs/V1JobSpec.md" rel="nofollow noreferrer">non-optional</a>, contrary to the other properties.</p>

<p>So by constructing the <code>template</code> beforehand and injecting it while constructing the <code>JobSpec</code> does solve the issue:</p>

<pre><code>job.spec.template = client.V1PodTemplate()
job.spec.template.spec = client.V1PodTemplateSpec()
job.spec.template.spec.restart_policy = "Never"
job.spec.template.spec.containers = [
    make_container()
]

job.spec = client.V1JobSpec()
</code></pre>

<p>Following this reasoning, it does seem weird that the same does not apply in a higher-scope to the <code>Spec</code> property of the <code>Job</code>, since it's a mandatory section of the definition of a Job object.</p>

<p>But taking a look once again to the <a href="https://github.com/kubernetes-client/python/blob/e057f273069de445a2d5a250ac5fe37d79671f3b/kubernetes/docs/V1Job.md" rel="nofollow noreferrer">documentation</a> of the client, it is possible to observe that the <code>Spec</code> property is marked as optional, which explains why we are able to create a <code>Job</code> instance, without having to inject the <code>Spec</code>. </p>
