python-scaleway icon indicating copy to clipboard operation
python-scaleway copied to clipboard

Create server raise Client Error 400?

Open DravenJohnson opened this issue 4 years ago • 2 comments

Using following:

compute_api = ComputeAPI(auth_token=secret_key, region='pl-waw-1')

compute_api.query().servers.post({'project': org_id, "name": 'test', "commercial_type": "DEV1-M"})

Got:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/draven/.local/lib/python2.7/site-packages/slumber/__init__.py", line 167, in post
    resp = self._request("POST", data=data, files=files, params=kwargs)
  File "scaleway/scaleway/apis/__init__.py", line 87, in _request
    return super(SlumberResource, self)._request(*args, **kwargs)
  File "/home/draven/.local/lib/python2.7/site-packages/slumber/__init__.py", line 101, in _request
    raise exception_class("Client Error %s: %s" % (resp.status_code, url), response=resp, content=resp.content)
slumber.exceptions.HttpClientError: Client Error 400: https://api-pl-waw.scaleway.com/instance/v1/zones/pl-waw-1/servers/

Since there is no documents about how to use POST / Create so based on other sample such as this I assume the above code is correct.

But Error 400 ?

DravenJohnson avatar Apr 08 '21 20:04 DravenJohnson

You can catch the exception to display the error and figure out what is going on.

import json

from scaleway.apis import ComputeAPI
from slumber.exceptions import HttpClientError

try:
    res = compute_api.query().servers.post({'project': org_id, "name": 'test', "commercial_type": "DEV1-M"})
except HttpClientError as exc:
    print(json.dumps(exc.response.json(), indent=2))
{
  "type": "invalid_request_error",
  "message": "Validation Error",
  "fields": {
    "image": [
      "required key not provided"
    ],
    "volumes": [
      "required key not provided"
    ]
  }
}

To create a server, you need to specify an image ("ubuntu" for example), or a list of volumes. Let's try to find the image to specify:

res = compute_api.query().images.get()
image = next(image for image in res['images'] if 'Ubuntu 20.04' in image['name'])
print(json.dumps(image, indent=2))

This retrieves the first image containing the name "Ubuntu 20.04". Feel free to print (res) to list all the images and get the one you prefer.

{
  "id": "7af873db-4999-4147-a176-59f6f22833fd",
  "name": "Ubuntu 20.04 Focal Fossa",
  "organization": "51b656e3-4865-41e8-adbc-0c45bdd780db",
  "project": "51b656e3-4865-41e8-adbc-0c45bdd780db",
  "root_volume": {
    "id": "671a345f-32a7-4d25-98db-6ceae7f68c33",
    "name": "ubuntu_20.04_focal_fossa:volume-0",
    "volume_type": "l_ssd",
    "size": 10000000000
  },
  "extra_volumes": {},
  "public": true,
  "arch": "x86_64",
  "creation_date": "2021-03-25T11:32:45.773914+00:00",
  "modification_date": "2021-03-25T11:32:45.773914+00:00",
  "default_bootscript": null,
  "from_server": null,
  "state": "available",
  "zone": "pl-waw-1"
}

You can now create the server with:

res = compute_api.query().servers.post({
    "project": org_id,
    "name": 'test',
    "commercial_type": "DEV1-M",
    "image": "7af873db-4999-4147-a176-59f6f22833fd"
})
server_id = res['server']['id']

On creation the server is not started automatically. To poweron the server, you need another API query:

compute_api.query().servers(server_id).action.post({
    'action': 'poweron'
})

brmzkw avatar Apr 09 '21 07:04 brmzkw

Great, thank you for helping.

DravenJohnson avatar Apr 09 '21 19:04 DravenJohnson