import json
from . import BaseClient
[docs]class Client(BaseClient):
"""
A low-level client representing Biling:
.. code-block:: python
import coto
session = coto.Session()
client = session.client('billing')
These are the available methods:
* Account:
* :py:meth:`account_status`
* :py:meth:`close_account`
* Alternate Contacts:
* :py:meth:`list_alternate_contacts`
* :py:meth:`set_alternate_contacts`
* Tax Registrations:
* :py:meth:`list_tax_registrations`
* :py:meth:`set_tax_registration`
* :py:meth:`delete_tax_registration`
"""
def __init__(self, session):
super().__init__(session)
self.__xsrf_token = None
def _xsrf_token(self):
if self.__xsrf_token is None:
self.__xsrf_token = self._get_xsrf_token()
return self.__xsrf_token
def _get_xsrf_token(self):
r = self.session()._get(
'https://console.aws.amazon.com/billing/home?region=eu-central-1&state=hashArgs%23'
)
if r.status_code != 200:
raise Exception("failed get billing xsrf token")
return r.headers['x-awsbc-xsrf-token']
def _get(self, api):
r = self.session()._get(
"https://console.aws.amazon.com/billing/rest/v1.0/{0}?state=hashArgs%23".
format(api),
headers={'x-awsbc-xsrf-token': self._xsrf_token()})
if r.status_code != 200:
raise Exception("failed get {0}".format(api))
return r
def _put(self, api, data=None):
if data is None:
r = self.session()._put(
"https://console.aws.amazon.com/billing/rest/v1.0/{0}?state=hashArgs%23".
format(api),
headers={
'x-awsbc-xsrf-token': self._xsrf_token(),
'Content-Type': 'application/json',
})
else:
r = self.session()._put(
"https://console.aws.amazon.com/billing/rest/v1.0/{0}?state=hashArgs%23".
format(api),
headers={
'x-awsbc-xsrf-token': self._xsrf_token(),
'Content-Type': 'application/json',
},
data=json.dumps(data))
if r.status_code != 200:
raise Exception("failed put {}: {}".format(api, r.text))
return r
# billing api
[docs] def list_alternate_contacts(self):
"""
Lists the alternate contacts set for the account. In order to keep the
right people in the loop, you can add an alternate contact for Billing,
Operations, and Security communications.
Request Syntax:
.. code-block:: python
response = client.list_alternate_contacts()
Returns:
dict: Response Syntax
.. code-block:: python
[
{
'contactId': int,
'contactType': 'billing' | 'operations' | 'security',
'email': str,
'name': str,
'phoneNumber': str,
'title': str
},
]
"""
r = self._get('additionalcontacts')
return json.loads(r.text)
[docs] def set_alternate_contacts(self, AlternateContacts):
"""
Sets the alternate contacts set for the account. In order to keep the
right people in the loop, you can add an alternate contact for Billing,
Operations, and Security communications.
Please note that, the primary account holder will continue to receive
all email communications.
Contact Types:
``billing``:
The alternate Billing contact will receive billing-related
notifications, such as invoice availability notifications.
``operations``:
The alternate Operations contact will receive
operations-related notifications.
``security``:
The alternate Security contact will receive
security-related notifications. For additional AWS
security-related notifications, please access the Security
Bulletins RSS Feed.
Request Syntax:
.. code-block:: python
response = client.set_alternate_contacts(
AlternateContacts=[
{
'contactType': 'billing',
'email': str,
'name': str,
'phoneNumber': str,
'title': str
},
{
'contactType': 'operations',
'email': str,
'name': str,
'phoneNumber': str,
'title': str
},
{
'contactType': 'security',
'email': str,
'name': str,
'phoneNumber': str,
'title': str
},
]
)
Args:
AlternateContacts (list): List of alternate contacts.
"""
self._put('additionalcontacts', AlternateContacts)
[docs] def list_tax_registrations(self):
"""
Lists the tax registrations set for the account.
Set your tax information so that your 1099K or W-88EN is generated
appropriately. Setting this information up also allows you to sell more
than 200 transactions or $20,000 in Reserved Instances.
Status:
``Verified``:
Verified
``Pending``:
Pending
``Deleted``:
Deleted
Request Syntax:
.. code-block:: python
response = client.list_tax_registrations()
Returns:
dict: Response Syntax
.. code-block:: python
[
{
'address': {
'addressLine1': str,
'addressLine2': str,
'city': str,
'countryCode': str,
'postalCode': str,
'state': str,
},
'authority': {
'country': str,
'state': str
},
'currentStatus': 'Verified' | 'Pending',
'legalName': str,
'localTaxRegistration': bool,
'registrationId': str
},
]
"""
r = self._get('taxexemption/eu/vat/information')
return json.loads(r.text)['taxRegistrationList']
[docs] def set_tax_registration(self, TaxRegistration):
"""
Set the tax registrations for the account.
Set your tax information so that your 1099K or W-88EN is generated
appropriately. Setting this information up also allows you to sell more
than 200 transactions or $20,000 in Reserved Instances.
Request Syntax:
.. code-block:: python
response = client.set_tax_registration(
TaxRegistration={
'address': {
'addressLine1': str,
'addressLine2': str,
'city': str,
'countryCode': str,
'postalCode': str,
'state': str,
},
'authority': {
'country': str,
'state': str
},
'legalName': str,
'localTaxRegistration': bool,
'registrationId': str,
}
)
Args:
TaxRegistration (dict): Desired tax registration.
"""
self._put('taxexemption/eu/vat/information', TaxRegistration)
[docs] def delete_tax_registration(self, TaxRegistration):
"""
Delete the given tax registrations from the account.
Request Syntax:
.. code-block:: python
response = client.delete_tax_registration(
TaxRegistration={
'address': {
'addressLine1': str,
'addressLine2': str,
'city': str,
'countryCode': str,
'postalCode': str,
'state': str,
},
'authority': {
'country': str,
'state': str
},
'legalName': str,
'localTaxRegistration': bool,
'registrationId': str,
}
)
Args:
TaxRegistration (dict): Tax registration to delete.
"""
TaxRegistration['currentStatus'] = 'Deleted'
return self.set_tax_registration(TaxRegistration)
[docs] def account_status(self):
"""
Obtain the status of the account.
Status:
``ACTIVE``:
Active
``SUSPENDED``:
Suspended, will be deleted within 90 days
Request Syntax:
.. code-block:: python
response = client.account_status()
Returns:
string: status
"""
r = self._get('account/status')
return json.loads(r.text)
[docs] def close_account(self):
"""
Close the account. Returns True iff successful, otherwise throws
an exception.
Request Syntax:
.. code-block:: python
client.close_account()
Returns:
boolean: success
"""
self._put('account')
return True