Developer Information

Type Annotations

Python type annotations / hints for the base Libcloud compute API have beenadded in v2.8.0.

The goal behind type annotations is to make developer lives easier byintroducing optional static typing for Python programs.

This allows you to catch bugs and issues which are related to variable typesearlier and faster (aka when you run mypy locally either manually orintegrated in your editor / IDE and also as part of you CI/CD buildpipeline).

An example of how to use type annotations correctly is shown below.

  1. # Licensed to the Apache Software Foundation (ASF) under one or more
  2. # contributor license agreements. See the NOTICE file distributed with
  3. # this work for additional information regarding copyright ownership.
  4. # The ASF licenses this file to You under the Apache License, Version 2.0
  5. # (the "License"); you may not use this file except in compliance with
  6. # the License. You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15.  
  16. from libcloud.compute.types import Provider
  17. from libcloud.compute.providers import get_driver
  18.  
  19. from libcloud.compute.drivers.ec2 import EC2NodeDriver
  20. from libcloud.compute.drivers.rackspace import RackspaceNodeDriver
  21.  
  22. from typing import Type, cast
  23.  
  24. ec2_cls = get_driver(Provider.EC2)
  25. rackspace_cls = get_driver(Provider.RACKSPACE)
  26.  
  27. # NOTE: If you are using driver methods which are not part of the standard API,
  28. # you need to explicitly cast the driver class reference to the correct class
  29. # for type checking to work correctly
  30. EC2 = cast(Type[EC2NodeDriver], ec2_cls)
  31. Rackspace = cast(Type[RackspaceNodeDriver], rackspace_cls)
  32.  
  33. drivers = [EC2('access key id', 'secret key', region='us-east-1'),
  34. Rackspace('username', 'api key', region='iad')]
  35.  
  36. nodes = []
  37. for driver in drivers:
  38. nodes.extend(driver.list_nodes())
  39.  
  40. print(nodes)
  41. # [ <Node: provider=Amazon, status=RUNNING, name=bob, ip=1.2.3.4.5>,
  42. # <Node: provider=Rackspace, status=REBOOT, name=korine, ip=6.7.8.9.10>, ... ]
  43.  
  44. # grab the node named "test"
  45. node = [n for n in nodes if n.name == 'test'][0]
  46.  
  47. # reboot "test"
  48. node.reboot()

If you reference an invalid object attribute or a method, you wouldsee an error similar to the one beloe when running mypy:

  1. ...
  2. print(nodes[0].name)
  3. print(nodes[0].invalid)
  4. print(nodes[0].rebbot())
  5. print(nodes[0].reboot(foo='invalid'))
  6. ...
  1. $ mypy --no-incremental example_compute.py
  2. example_compute.py:41: error: "Node" has no attribute "invalid"
  3. example_compute.py:42: error: "Node" has no attribute "rebbot"; maybe "reboot"?
  4. example_compute.py:43: error: Unexpected keyword argument "foo" for "reboot" of "Node"

If you are using driver methods which are not part of the Libcloud standardAPI, you need to use cast() method as shown below to cast the driver classto the correct type. If you don’t do that, mypy will only be aware of themethods which are part of the Libcloud base compute API (akaBaseNodeDriver class).

This is needed because of how Libcloud utilizes meta programming for theget_driver() and related methods (there is no other way without writinga mypy plugin to achieve that).

Mailing Lists

All of the communication about Libcloud development happens on our mailinglists.

Archive of old incubator mailing lists:

IRC

  • libcloud on Freenode

Issue Tracker

For bug and issue tracking we use Github issues located athttps://github.com/apache/libcloud/issues.

Testing

For information how to run the tests and how to generate the test coveragereport, please see the Testing page.

Continuous Integration

For continuous integration we use Travis-CI. You can find build reports on thefollowing links:

Travis-CI builder is also integrated with Github which means that if you open apull request there, Travis-CI will automatically build it.

If you want to validate the build before raising the PR, Travis-CI can be enabled for personalaccounts and branches separately.

Test Coverage

Test coverage report is automatically generated after every push and can befound at https://codecov.io/github/apache/libcloud?branch=trunk.