Skip to content

Commit 6008abb

Browse files
committed
Deploy
1 parent 9c5bbb6 commit 6008abb

File tree

9 files changed

+156
-76
lines changed

9 files changed

+156
-76
lines changed

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
include LICENSE
2-
include README.md
2+
include README.md

README.md

Lines changed: 102 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,102 @@
1-
# Getting Started with bandwidth
2-
3-
Bandwidth's set of APIs
4-
5-
## Install the Package
6-
7-
The package is compatible with Python versions ```2 >=2.7.9``` and ```3 >=3.4```.
8-
Install the package from PyPi using the following pip command:
9-
10-
```python
11-
pip install bandwidth-sdk==5.2.0
12-
```
13-
14-
You can also view the package at:
15-
https://pypi.python.org/pypi/bandwidth-sdk
16-
17-
## Initialize the API Client
18-
19-
The following parameters are configurable for the API Client.
20-
21-
| Parameter | Type | Description |
22-
| --- | --- | --- |
23-
| `messaging_basic_auth_user_name` | `string` | The username to use with basic authentication |
24-
| `messaging_basic_auth_password` | `string` | The password to use with basic authentication |
25-
| `voice_basic_auth_user_name` | `string` | The username to use with basic authentication |
26-
| `voice_basic_auth_password` | `string` | The password to use with basic authentication |
27-
| `environment` | Environment | The API environment. <br> **Default: `Environment.PRODUCTION`** |
28-
| `timeout` | `float` | The value to use for connection timeout. <br> **Default: 60** |
29-
| `max_retries` | `int` | The number of times to retry an endpoint call if it fails. <br> **Default: 3** |
30-
| `backoff_factor` | `float` | A backoff factor to apply between attempts after the second try. <br> **Default: 0** |
31-
32-
The API client can be initialized as following.
33-
34-
```python
35-
from bandwidth.bandwidth_client import BandwidthClient
36-
37-
client = BandwidthClient(
38-
messaging_basic_auth_user_name='MessagingBasicAuthUserName',
39-
messaging_basic_auth_password='MessagingBasicAuthPassword',
40-
voice_basic_auth_user_name='VoiceBasicAuthUserName',
41-
voice_basic_auth_password='VoiceBasicAuthPassword',
42-
environment = Environment.PRODUCTION,)
43-
```
44-
45-
API calls return an `ApiResponse` object that includes the following fields:
46-
47-
| Field | Description |
48-
| --- | --- |
49-
| `status_code` | Status code of the HTTP response |
50-
| `reason_phrase` | Reason phrase of the HTTP response |
51-
| `headers` | Headers of the HTTP response as a dictionary |
52-
| `text` | The body of the HTTP response as a string |
53-
| `request` | HTTP request info |
54-
| `errors` | Errors, if they exist |
55-
| `body` | The deserialized body of the HTTP response |
56-
57-
## Authorization
58-
59-
This API does not require authentication.
60-
61-
## API Reference
62-
63-
### List of APIs
64-
65-
*
66-
1+
# Bandwidth Python SDK
2+
3+
Bandwidth's API docs can be found at https://dev.bandwidth.com
4+
5+
Python specific docs can be found at https://dev.bandwidth.com/sdks/python.html
6+
7+
# Python SDK
8+
9+
## Download & Install
10+
11+
```
12+
pip install bandwidth-sdk
13+
```
14+
15+
## Initialize Bandwidth Client
16+
17+
```python
18+
from bandwidth.bandwidth_client import BandwidthClient
19+
20+
from bandwidth.messaging.models.message_request import MessageRequest
21+
from bandwidth.messaging.exceptions.generic_client_exception import GenericClientException
22+
from bandwidth.messaging.exceptions.path_client_exception import PathClientException
23+
24+
from bandwidth.voice.models.api_create_call_request import ApiCreateCallRequest
25+
from bandwidth.voice.models.modify_call_recording_state import ModifyCallRecordingState
26+
from bandwidth.voice.exceptions.error_response_exception import ErrorResponseException
27+
from bandwidth.voice.bxml.response import Response
28+
from bandwidth.voice.bxml.verbs import *
29+
30+
##Initialize client
31+
voice_basic_auth_user_name = 'username'
32+
voice_basic_auth_password = 'password'
33+
messaging_basic_auth_user_name = 'token'
34+
messaging_basic_auth_password = 'secret'
35+
36+
bandwidth_client = BandwidthClient(
37+
voice_basic_auth_user_name=voice_basic_auth_user_name,
38+
voice_basic_auth_password=voice_basic_auth_password,
39+
messaging_basic_auth_user_name=messaging_basic_auth_user_name,
40+
messaging_basic_auth_password=messaging_basic_auth_password)
41+
```
42+
43+
## Create Phone Call
44+
45+
```python
46+
voice_client = bandwidth_client.voice_client.client
47+
account_id = "1"
48+
49+
##Create phone call
50+
body = ApiCreateCallRequest()
51+
body.mfrom = "+17777777777"
52+
body.to = "+16666666666"
53+
body.application_id = "3-d-4-b-5"
54+
body.answer_url = "https://test.com"
55+
56+
try:
57+
response = voice_client.create_call(account_id, body=body)
58+
print(response.body.call_id) #c-3f758f24-a59bb21e-4f23-4d62-afe9-53o2ls3o4saio4l
59+
print(response.status_code) #201
60+
except ErrorResponseException as e:
61+
print(e.description) #Invalid from: must be an E164 telephone number
62+
print(e.response_code) #400
63+
```
64+
65+
## Generate BXML
66+
67+
```python
68+
response = Response()
69+
speak_sentence = SpeakSentence(
70+
sentence="Test",
71+
voice="susan",
72+
locale="en_US",
73+
gender="female"
74+
)
75+
76+
response.add_verb(speak_sentence)
77+
print(response.to_bxml())
78+
```
79+
80+
## Send Text Message
81+
82+
```python
83+
messaging_client = bandwidth_client.messaging_client.client
84+
account_id = "1"
85+
86+
body = MessageRequest()
87+
body.application_id = "1-d-b"
88+
body.to = ["+17777777777"]
89+
body.mfrom = "+18888888888"
90+
body.text = "Greetings!"
91+
92+
try:
93+
response = messaging_client.create_message(account_id, body=body)
94+
print(response.body.id) #1570819529611mexbyfr7ugrouuxy
95+
print(response.status_code) #202
96+
except GenericClientException as e:
97+
print(e.description) #Your request could not be accepted.
98+
print(e.response_code) #400
99+
except PathClientException as e:
100+
print(e.message) #Access is denied
101+
print(e.response_code) #403
102+
```

bandwidth/messaging/controllers/api_controller.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from bandwidth.api_helper import APIHelper
1010
from bandwidth.configuration import Server
1111
from bandwidth.http.api_response import ApiResponse
12+
from bandwidth.utilities.file_wrapper import FileWrapper
1213
from bandwidth.messaging.controllers.base_controller import BaseController
1314
from bandwidth.http.auth.messaging_basic_auth import MessagingBasicAuth
1415
from bandwidth.messaging.models.media import Media
@@ -191,7 +192,7 @@ def upload_media(self,
191192
media_id,
192193
content_length,
193194
body,
194-
content_type=None,
195+
content_type='application/octet-stream',
195196
cache_control=None):
196197
"""Does a PUT request to /users/{userId}/media/{mediaId}.
197198
@@ -203,6 +204,7 @@ def upload_media(self,
203204
content_length (long|int): TODO: type description here.
204205
body (string): TODO: type description here.
205206
content_type (string, optional): TODO: type description here.
207+
Example: application/octet-stream
206208
cache_control (string, optional): TODO: type description here.
207209
208210
Returns:
@@ -226,15 +228,22 @@ def upload_media(self,
226228
_query_builder += _url_path
227229
_query_url = APIHelper.clean_url(_query_builder)
228230

231+
if isinstance(body, FileWrapper):
232+
body_wrapper = body.file_stream
233+
body_content_type = body.content_type
234+
else:
235+
body_wrapper = body
236+
body_content_type = content_type
237+
229238
# Prepare headers
230239
_headers = {
240+
'content-type': body_content_type,
231241
'Content-Length': content_length,
232-
'Content-Type': content_type,
233242
'Cache-Control': cache_control
234243
}
235244

236245
# Prepare and execute request
237-
_request = self.config.http_client.put(_query_url, headers=_headers, parameters=body)
246+
_request = self.config.http_client.put(_query_url, headers=_headers, parameters=body_wrapper)
238247
MessagingBasicAuth.apply(self.config, _request)
239248
_response = self.execute_request(_request)
240249

bandwidth/utilities/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__all__ = [
2+
'file_wrapper.py',
3+
]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
bandwidth
5+
6+
This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ).
7+
"""
8+
9+
10+
class FileWrapper():
11+
12+
"""A wrapper to allow passing in content type for file uploads."""
13+
14+
def __init__(self, file, content_type='application/octet-stream'):
15+
self._file_stream = file
16+
self._content_type = content_type
17+
18+
@property
19+
def file_stream(self):
20+
return self._file_stream
21+
22+
@property
23+
def content_type(self):
24+
return self._content_type

bandwidth/voice/bxml/verbs/phone_number.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515

1616
class PhoneNumber(AbstractBxmlVerb):
1717

18-
def __init__(self, number=None, transfer_answer_url=None, transfer_answer_method=None, username=None, password=None, tag=None):
18+
def __init__(self, number=None, transfer_answer_url=None, transfer_answer_method=None, username=None, password=None, tag=None, transfer_disconnect_url=None, transfer_disconnect_method=None):
1919
"""
2020
Initializes the PhoneNumber class with the following parameters
2121
2222
:param str number: The phone number
2323
:param str transfer_answer_url: The url to send the transfer event to
2424
:param str transfer_answer_method: The http method of the transfer event request
25+
:param str transfer_disconnect_url: The url to send the transfer disconnect event to
26+
:param str transfer_disconnect_method: The http method of the transfer disconnect event request
2527
:param str username: The username to authenticate on the transfer event url
2628
:param str password: The password to authenticate on the transfer event url
2729
:param str tag: Custom string sent in the callback
@@ -32,6 +34,8 @@ def __init__(self, number=None, transfer_answer_url=None, transfer_answer_method
3234
self.username = username
3335
self.password = password
3436
self.tag = tag
37+
self.transfer_disconnect_method = transfer_disconnect_method
38+
self.transfer_disconnect_url = transfer_disconnect_url
3539

3640
def to_etree_element(self):
3741
"""
@@ -52,6 +56,10 @@ def to_etree_element(self):
5256
root.set("password", self.password)
5357
if self.tag is not None:
5458
root.set("tag", self.tag)
59+
if self.transfer_disconnect_method is not None:
60+
root.set("transferDisconnectMethod", self.transfer_disconnect_method)
61+
if self.transfer_disconnect_url is not None:
62+
root.set("transferDisconnectUrl", self.transfer_disconnect_url)
5563
return root
5664

5765
def to_bxml(self):

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
setup(
1414
name='bandwidth-sdk',
15-
version='5.2.0',
15+
version='5.2.1',
1616
description='Bandwidth\'s set of APIs',
1717
long_description=long_description,
1818
long_description_content_type="text/markdown",

test-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nose==1.3.7
1+
nose==1.3.7

tox.ini

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[tox]
2-
envlist = py27, py35
2+
envlist = py35
33

44
[testenv]
55
commands = nosetests
6-
deps =
7-
nose
6+
deps =
7+
nose

0 commit comments

Comments
 (0)