<p>I am trying to create a new service for one of my deployments named <code>node-js-deployment</code> in GCE hostes Kubernetes Cluster</p>

<p>I followed the Documentation to <a href="https://github.com/kubernetes-incubator/client-python/blob/master/kubernetes/docs/CoreV1Api.md#create_namespaced_service" rel="nofollow noreferrer">create_namespaced_service</a></p>

<p>This is the service data: </p>

<pre><code>{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "node-js-service"
    },
    "spec": {
        "selector": {
            "app": "node-js"
        },
        "ports": [
            {
                "protocol": "TCP",
                "port": 80,
                "targetPort": 8000
            }
        ]
    }
}
</code></pre>

<p>This is the Python function to create the service </p>

<pre><code>api_instance = kubernetes.client.CoreV1Api()
namespace = 'default'  

body = kubernetes.client.V1Service()  # V1Serice

# Creating Meta Data
metadata = kubernetes.client.V1ObjectMeta()
metadata.name = "node-js-service"

# Creating spec 
spec = kubernetes.client.V1ServiceSpec()

# Creating Port object
ports = kubernetes.client.V1ServicePort()
ports.protocol = 'TCP'
ports.target_port = 8000
ports.port = 80

spec.ports = ports
spec.selector = {"app": "node-js"}

body.spec = spec


try:
    api_response = api_instance.create_namespaced_service(namespace, body, pretty=pretty)
    pprint(api_response)
except ApiException as e:
    print("Exception when calling CoreV1Api-&gt;create_namespaced_service: %s\n" % e)
</code></pre>

<p>Error: </p>

<pre><code>Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Tue, 21 Feb 2017 03:54:55 GMT', 'Content-Length': '227'})
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Service in version \"v1\" cannot be handled as a Service: only encoded map or array can be decoded into a struct","reason":"BadRequest","code":400}
</code></pre>

<p>But the service is being created if I am passing JSON. Not sure what I am doing wrong. </p>

<p>Any help is greatly appreciated, thank you.</p>

<p>From reading your code, it seems that you miss assigning the metadata to <code>body.metadata</code>. And you missed that the <code>ports</code> field of the <code>V1ServiceSpec</code> is supposed to be a list, but you used a single <code>V1ServicePort</code> so without testing I assume this should works:</p>

<pre><code>api_instance = kubernetes.client.CoreV1Api()
namespace = 'default'

body = kubernetes.client.V1Service()  # V1Serice

# Creating Meta Data
metadata = kubernetes.client.V1ObjectMeta()
metadata.name = "node-js-service"

body.metadata = metadata

# Creating spec
spec = kubernetes.client.V1ServiceSpec()

# Creating Port object
port = kubernetes.client.V1ServicePort()
port.protocol = 'TCP'
port.target_port = 8000
port.port = 80

spec.ports = [ port ]
spec.selector = {"app": "node-js"}

body.spec = spec
</code></pre>

<p>The definition could also be loaded from json / yaml directly as shown in two of the examples within the offical repo - see <a href="https://github.com/kubernetes-incubator/client-python/blob/master/examples/exec.py" rel="nofollow noreferrer">exec.py</a> <a href="https://github.com/kubernetes-incubator/client-python/blob/master/examples/create_deployment.py" rel="nofollow noreferrer">create_deployment.py</a>.</p>

<p>Your solution could then look like:</p>

<pre><code>api_instance = kubernetes.client.CoreV1Api()
namespace = 'default'

manifest = {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "node-js-service"
    },
    "spec": {
        "selector": {
            "app": "node-js"
        },
        "ports": [
            {
                "protocol": "TCP",
                "port": 80,
                "targetPort": 8000
            }
        ]
    }
}

try:
    api_response = api_instance.create_namespaced_service(namespace, manifest, pretty='true')
    pprint(api_response)
except ApiException as e:
    print("Exception when calling CoreV1Api-&gt;create_namespaced_endpoints: %s\n" % e)
</code></pre>
