8000 Add Python type annotation for base Compute API by Kami · Pull Request #1306 · apache/libcloud · GitHub
[go: up one dir, main page]

Skip to content

Add Python type annotation for base Compute API #1306

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Nov 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,4 @@ lib/
pip-selfcheck.json
report.html
.pytest_cache


.mypy_cache/
10 changes: 9 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@ Common
Compute
-------

- Introduce type annotations for the base compute API methods. This means you
can now leverage mypy to type check (with some limitations) your code which
utilizes Libcloud compute API standard API methods.

Keep in mind that at this point, type annotations are only available for
standard compute API methods.
(GITHUB-1306)
[Tomaz Muraus]
- [Azure ARM] Fix ``attach_volume`` method and allow maximum of 64 disks to be
added when LUN is not specified. Previously there was a bug and only a
maximum of 63 disks could be added.
(GITHUB-1372
(GITHUB-1372)
[Palash Gandhi - @palashgandhi]

Storage
Expand Down
19 changes: 16 additions & 3 deletions example_compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,26 @@
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

EC2 = get_driver(Provider.EC2)
Rackspace = get_driver(Provider.RACKSPACE)
from libcloud.compute.drivers.ec2 import EC2NodeDriver
from libcloud.compute.drivers.rackspace import RackspaceNodeDriver

from typing import Type, cast

ec2_cls = get_driver(Provider.EC2)
rackspace_cls = get_driver(Provider.RACKSPACE)

# NOTE: If you are using driver methods which are not part of the standard API,
# you need to explicitly cast the driver class reference to the correct class
# for type checking to work correctly
EC2 = cast(Type[EC2NodeDriver], ec2_cls)
Rackspace = cast(Type[RackspaceNodeDriver], rackspace_cls)

drivers = [EC2('access key id', 'secret key', region='us-east-1'),
Rackspace('username', 'api key', region='iad')]

nodes = [driver.list_nodes() for driver in drivers]
nodes = []
for driver in drivers:
nodes.extend(driver.list_nodes())

print(nodes)
# [ <Node: provider=Amazon, status=RUNNING, name=bob, ip=1.2.3.4.5>,
Expand Down
7 changes: 5 additions & 2 deletions libcloud/common/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Dict
from typing import Type

import base64
from datetime import datetime
import hashlib
Expand All @@ -23,7 +26,7 @@
try:
import simplejson as json
except ImportError:
import json
import json # type: ignore

from libcloud.utils.py3 import ET
from libcloud.utils.py3 import _real_unicode
Expand Down Expand Up @@ -96,7 +99,7 @@ class AWSGenericResponse(AWSBaseResponse):
# exception class that is raised immediately.
# If a custom exception class is not defined, errors are accumulated and
# returned from the parse_error method.
exceptions = {}
exceptions = {} # type: Dict[str, Type[Exception]]

def success(self):
return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED]
Expand Down
3 changes: 2 additions & 1 deletion libcloud/common/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from libcloud.common.base import ConnectionUserAndKey, RawResponse
from libcloud.common.base import CertificateConnection
from libcloud.common.base import XmlResponse
from libcloud.common.base import BaseDriver

# The time format for headers in Azure requests
AZURE_TIME_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
Expand Down Expand Up @@ -241,7 +242,7 @@ def _format_special_header_values(self, headers, method):
return special_header_values


class AzureBaseDriver(object):
class AzureBaseDriver(BaseDriver):
name = "Microsoft Azure Service Management API"


Expand Down
5 changes: 3 additions & 2 deletions libcloud/common/azure_arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@
try:
import simplejson as json
except ImportError:
import json
import json # type: ignore

import time
from libcloud.utils.py3 import urlparse

from libcloud.common.base import (ConnectionUserAndKey,
JsonResponse,
RawResponse)
from libcloud.common.base import BaseDriver
from libcloud.http import LibcloudConnection
from libcloud.utils.py3 import basestring, urlencode


class AzureBaseDriver(object):
class AzureBaseDriver(BaseDriver):
name = "Microsoft Azure Resource Management API"


Expand Down
28 changes: 19 additions & 9 deletions libcloud/common/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Union
from typing import Type
from typing import Optional

import json
import os
import ssl
Expand Down Expand Up @@ -115,10 +119,16 @@ class Response(object):
A base Response class to derive from.
"""

status = httplib.OK # Response status code
headers = {} # Response headers
body = None # Raw response body
object = None # Parsed response body
# Response status code
status = httplib.OK # type: int
# Response headers
headers = {} # type: dict

# Raw response body
body = None

# Parsed response body
object = None

error = None # Reason returned by the server.
connection = None # Parent connection class
Expand Down Expand Up @@ -298,11 +308,11 @@ class Connection(object):
responseCls = Response
rawResponseCls = RawResponse
connection = None
host = '127.0.0.1'
host = '127.0.0.1' # type: str
port = 443
timeout = None
timeout = None # type: Optional[Union[int, float]]
secure = 1
driver = None
driver = None # type: Type[BaseDriver]
action = None
cache_busting = False
backoff = None
Expand Down Expand Up @@ -898,7 +908,7 @@ class ConnectionUserAndKey(ConnectionKey):
Base connection class which accepts a ``user_id`` and ``key`` argument.
"""

user_id = None
user_id = None # type: int

def __init__(self, user_id, key, secure=True, host=None, port=None,
url=None, timeout=None, proxy_url=None,
Expand All @@ -917,7 +927,7 @@ class BaseDriver(object):
Base driver class from which other classes can inherit from.
"""

connectionCls = ConnectionKey
connectionCls = ConnectionKey # type: Type[Connection]

def __init__(self, key, secret=None, secure=True, host=None, port=None,
api_version=None, region=None, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion libcloud/common/brightbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
try:
import simplejson as json
except ImportError:
import json
import json # type: ignore


class BrightboxResponse(JsonResponse):
Expand Down
7 changes: 5 additions & 2 deletions libcloud/common/buddyns.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List
from typing import Dict

from libcloud.common.base import ConnectionKey, JsonResponse


Expand All @@ -28,8 +31,8 @@


class BuddyNSResponse(JsonResponse):
errors = []
objects = []
errors = [] # type: List[Dict]
objects = [] # type: List[Dict]

def __init__(self, response, connection):
super(BuddyNSResponse, self).__init__(response=response,
Expand Down
3 changes: 2 additions & 1 deletion libcloud/common/dimensiondata.py
10000
Original file line number Diff line number Diff line change
Expand Up @@ -600,8 +600,9 @@ def wait_for_state(self, state, func, poll_interval=2, timeout=60, *args,
else:
object_state = result.status

if object_state is state or object_state in state:
if object_state is state or str(object_state) in state:
return result

sleep(poll_interval)
cnt += 1

Expand Down
7 changes: 5 additions & 2 deletions libcloud/common/dnspod.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List
from typing import Dict

from libcloud.common.base import ConnectionKey, JsonResponse


Expand All @@ -28,8 +31,8 @@


class DNSPodResponse(JsonResponse):
errors = []
objects = []
errors = [] # type: List[Dict]
objects = [] # type: List[Dict]

def __init__(self, response, connection):
super(DNSPodResponse, self).__init__(response=response,
Expand Down
7 changes: 5 additions & 2 deletions libcloud/common/durabledns.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List
from typing import Dict

import re
from xml.etree import ElementTree as ET # noqa

Expand Down Expand Up @@ -126,8 +129,8 @@ def __repr__(self):

class DurableResponse(XmlResponse):

errors = []
objects = []
errors = [] # type: List[Dict]
objects = [] # type: List[Dict]

def __init__(self, response, connection):
super(DurableResponse, self).__init__(response=response,
Expand Down
6 changes: 4 additions & 2 deletions libcloud/common/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
try:
import simplejson as json
except ImportError:
import json
import json # type: ignore

import logging
import base64
Expand All @@ -85,6 +85,7 @@
from libcloud.utils.py3 import b, httplib, urlencode, urlparse, PY3
from libcloud.common.base import (ConnectionUserAndKey, JsonResponse,
PollingConnection)
from libcloud.common.base import BaseDriver
from libcloud.common.types import (ProviderError,
LibcloudError)

Expand Down Expand Up @@ -293,7 +294,7 @@ def parse_body(self):
raise GoogleBaseError(message, self.status, code)


class GoogleBaseDriver(object):
class GoogleBaseDriver(BaseDriver):
name = "Google API"


Expand Down Expand Up @@ -730,6 +731,7 @@ def _write_token_to_file(self):

class GoogleBaseConnection(ConnectionUserAndKey, PollingConnection):
"""Base connection class for interacting with Google APIs."""

driver = GoogleBaseDriver
responseCls = GoogleResponse
host = 'www.googleapis.com'
Expand Down
2 changes: 1 addition & 1 deletion libcloud/common/gridscale.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
try:
import simplejson as json
except Exception:
import json
import json # type: ignore

from libcloud.common.base import BaseDriver, PollingConnection
from libcloud.common.base import ConnectionUserAndKey
Expand Down
2 changes: 1 addition & 1 deletion libcloud/common/hostvirtual.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
try:
import simplejson as json
except ImportError:
import json
import json # type: ignore

from libcloud.utils.py3 import httplib
from libcloud.common.base import ConnectionKey, JsonResponse
Expand Down
1 change: 0 additions & 1 deletion libcloud/common/liquidweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ def __repr__(self):
class LiquidWebResponse(JsonResponse):
objects = None
errors = None
error_dict = {}

def __init__(self, response, connection):
self.errors = []
Expand Down
8 changes: 5 additions & 3 deletions libcloud/common/luadns.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import base64
from typing import List
from typing import Dict

import base64

from libcloud.common.base import ConnectionUserAndKey, JsonResponse
from libcloud.utils.py3 import b
Expand All @@ -31,8 +33,8 @@


class LuadnsResponse(JsonResponse):
errors = []
objects = []
errors = [] # type: List[Dict]
objects = [] # type: List[Dict]

def __init__(self, response, connection):
super(LuadnsResponse, self).__init__(response=response,
Expand Down
7 changes: 5 additions & 2 deletions libcloud/common/nsone.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List
from typing import Dict

from libcloud.common.base import ConnectionKey, JsonResponse


Expand All @@ -28,8 +31,8 @@


class NsOneResponse(JsonResponse):
errors = []
objects = []
errors = [] # type: List[Dict]
objects = [] # type: List[Dict]

def __init__(self, response, connection):
super(NsOneResponse, self).__init__(response=response,
Expand Down
5 changes: 4 additions & 1 deletion libcloud/common/nttcis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"""
NTTCIS Common Components
"""

from typing import Dict

import xml.etree.ElementTree as etree
import re
from functools import wraps
Expand Down Expand Up @@ -1956,7 +1959,7 @@ class ClassFactory(object):
pass


attrs = {}
attrs = {} # type: Dict[str, str]


def processor(mapping, name=None):
Expand Down
Loading
0