├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.rst
├── example
├── __init__.py
├── authorize_driver.py
├── authorize_rider.py
├── config.driver.yaml
├── config.rider.yaml
├── driver_dashboard.html
├── driver_dashboard.py
├── request_ride.py
├── rider_dashboard.html
├── rider_dashboard.py
└── utils.py
├── requirements.txt
├── setup.cfg
├── setup.py
├── tests
├── __init__.py
├── fixtures
│ ├── test_auth_code_get_session
│ ├── test_cancel_current_ride
│ ├── test_cancel_ride
│ ├── test_client_credential_get_session
│ ├── test_estimate_ride
│ ├── test_estimate_ride_with_places
│ ├── test_estimate_shared_ride
│ ├── test_get_business_receipt
│ ├── test_get_business_trip_invoice_urls
│ ├── test_get_business_trip_receipt_pdf_url
│ ├── test_get_current_ride_details
│ ├── test_get_current_shared_ride_details
│ ├── test_get_driver_payments
│ ├── test_get_driver_profile
│ ├── test_get_driver_trips
│ ├── test_get_home_address
│ ├── test_get_payment_methods
│ ├── test_get_pickup_time_estimates
│ ├── test_get_price_estimates
│ ├── test_get_products
│ ├── test_get_promotions
│ ├── test_get_ride_details
│ ├── test_get_ride_map
│ ├── test_get_ride_receipt
│ ├── test_get_rider_profile
│ ├── test_get_rider_trips
│ ├── test_get_single_product
│ ├── test_get_user_activity
│ ├── test_get_user_profile
│ ├── test_get_work_address
│ ├── test_refresh_auth_code_access_token
│ ├── test_refresh_client_credential_access_token
│ ├── test_request_ride
│ ├── test_request_ride_with_no_default_product
│ ├── test_request_ride_with_places
│ ├── test_request_ride_with_surge
│ ├── test_request_shared_ride
│ ├── test_set_home_address
│ ├── test_set_work_address
│ ├── test_update_ride_destination
│ ├── test_update_ride_destination_with_places
│ ├── test_update_sandbox_driver_trips
│ ├── test_update_sandbox_product
│ └── test_update_sandbox_ride
├── test_auth.py
├── test_client.py
├── test_errors.py
├── test_request_utils.py
├── test_session.py
└── vcr_config.py
└── uber_rides
├── __init__.py
├── auth.py
├── client.py
├── errors.py
├── request.py
├── session.py
└── utils
├── __init__.py
├── auth.py
├── handlers.py
├── http.py
└── request.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local Environment #
2 | #####################
3 | env/
4 |
5 | # PyPi Dist Subdirectories #
6 | ############################
7 | build/
8 | dist/
9 | *.egg-info/
10 |
11 | # Examples
12 | example/oauth*_session_store.yaml
13 |
14 |
15 | # Backup Generated Files #
16 | ##########################
17 | __pycache__/
18 | *.pyo
19 | *.pyc
20 | *~
21 | *#
22 |
23 | # Compiled source #
24 | ###################
25 | *.com
26 | *.class
27 | *.dll
28 | *.exe
29 | *.o
30 | *.so
31 |
32 | # Packages #
33 | ############
34 | *.7z
35 | *.dmg
36 | *.gz
37 | *.iso
38 | *.jar
39 | *.rar
40 | *.tar
41 | *.zip
42 |
43 | # Logs and databases #
44 | ######################
45 | *.log
46 | *.sql
47 | *.sqlite
48 |
49 | # OS generated files #
50 | ######################
51 | .DS_Store
52 | .DS_Store?
53 | ._*
54 | .Spotlight-V100
55 | .Trashes
56 | ehthumbs.db
57 | Thumbs.db
58 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - "2.7"
4 | - "3.3"
5 | - "3.4"
6 | - "3.5"
7 |
8 | install: make bootstrap
9 | script: make
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | v0.6.0 - 14/9/2017
3 | -------------------
4 | - Added support for Uber Driver Sandbox
5 | - BC Break: Renamed auth.CLIENT_CREDENTIAL_GRANT to auth.CLIENT_CREDENTIALS_GRANT
6 |
7 | v0.5.3 - 11/9/2017
8 | -------------------
9 | - Added support for Uber for Business APIs
10 |
11 | v0.5.2 - 22/8/2017
12 | -------------------
13 | - Added flask example apps for Rider + Driver Dashboards
14 |
15 | v0.5.1 - 18/8/2017
16 | -------------------
17 | - Added better examples for Driver APIs
18 | - Added backwards compatibility proxies for legacy rider methods
19 | - Fixed SDK version # to v0.5.1
20 |
21 | v0.5.0 - 17/8/2017
22 | -------------------
23 | - Added support Driver APIs
24 |
25 | v0.4.1 - 2/7/2017
26 | -------------------
27 | - Made state token optional in authorization code grant
28 |
29 | v0.4.0 - 1/23/2017
30 | -------------------
31 | - Upgrade OAuth endpoints to use v2.
32 |
33 | v0.3.1 - 11/12/2016
34 | -------------------
35 | - Removal of rate limiting headers. The headers are deprecated with v1.2: X-Rate-Limit-Limit, X-Rate-Limit-Remaining, X-Rate-Limit-Reset.
36 |
37 | v0.3.0 - 11/12/2016
38 | -------------------
39 | - Release of v1.2 endpoints for the Riders API.
40 | - API base URL would need to reflect the version bump: https://api.uber.com/v1.2/.
41 |
42 | v0.2.7 - 9/28/2016
43 | -------------------
44 | - Added support for Python wheels
45 |
46 | v0.2.6 - 9/28/2016
47 | ------------------
48 | - Added better support for python 2.
49 |
50 | v0.2.5 - 7/18/2016
51 | ------------------
52 | - Add seat_count support to get_price_estimates
53 |
54 | v0.2.4 - 6/10/2016
55 | ------------------
56 | - Added SDK Version header
57 |
58 | v0.2.3 - 6/8/2016
59 | -----------------
60 | - Added Pool support
61 |
62 | v0.2.2 - 6/2/2016
63 | -----------------
64 | - Fixed backwards compatibility setup support for Python 2
65 | - Allowed custom state tokens for authorizations
66 | - Improved ErrorDetails formatting
67 |
68 | v0.2.1 - 3/29/2016
69 | ------------------
70 | - Added support for Python 3
71 |
72 | v0.2.0 - 2/20/2016
73 | ------------------
74 | - Added places support
75 | - Added payment methods support
76 | - Added trip experiences support
77 | - Added optional destination (Fix for Issue #4)
78 | - Added update destinaion support
79 | - Added default product ID support for estimates and ride requests
80 | - Rides Client mode (Sandbox or Production) is explicitly set
81 |
82 | v0.1.0 - 9/26/2015
83 | ------------------
84 | - Initial version.
85 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015-2017 Uber Technologies, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include uber_rides *
2 | recursive-include tests *
3 | recursive-include example *
4 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: test
2 | test:
3 | @py.test -s tests/
4 |
5 | .PHONY: clean
6 | clean:
7 | @find . -type f -name '*.pyc' -exec rm {} ';'
8 |
9 | .PHONY: bootstrap
10 | bootstrap:
11 | @pip install -r requirements.txt
12 | @pip install -e .
13 |
--------------------------------------------------------------------------------
/example/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uber/rides-python-sdk/76ecd75ab5235d792ec1010e36eca679ba285127/example/__init__.py
--------------------------------------------------------------------------------
/example/authorize_driver.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | """Initializes an UberRidesClient with OAuth 2.0 Credentials.
22 |
23 | This example demonstrates how to get an access token through the
24 | OAuth 2.0 Authorization Code Grant and use credentials to create
25 | an UberRidesClient.
26 |
27 | To run this example:
28 |
29 | (1) Set your app credentials in config.driver.yaml
30 | (2) Run `python authorize_driver.py`
31 | (3) A success message will print, 'Hello {YOUR_NAME}'
32 | (4) User OAuth 2.0 credentials are recorded in
33 | 'oauth_driver_session_store.yaml'
34 | """
35 |
36 | from __future__ import absolute_import
37 | from __future__ import division
38 | from __future__ import print_function
39 | from __future__ import unicode_literals
40 |
41 | from builtins import input
42 |
43 | from yaml import safe_dump
44 |
45 | from example import utils # NOQA
46 | from example.utils import fail_print
47 | from example.utils import response_print
48 | from example.utils import success_print
49 | from example.utils import import_app_credentials
50 |
51 | from uber_rides.auth import AuthorizationCodeGrant
52 | from uber_rides.client import UberRidesClient
53 | from uber_rides.errors import ClientError
54 | from uber_rides.errors import ServerError
55 | from uber_rides.errors import UberIllegalState
56 |
57 |
58 | def authorization_code_grant_flow(credentials, storage_filename):
59 | """Get an access token through Authorization Code Grant.
60 |
61 | Parameters
62 | credentials (dict)
63 | All your app credentials and information
64 | imported from the configuration file.
65 | storage_filename (str)
66 | Filename to store OAuth 2.0 Credentials.
67 |
68 | Returns
69 | (UberRidesClient)
70 | An UberRidesClient with OAuth 2.0 Credentials.
71 | """
72 | auth_flow = AuthorizationCodeGrant(
73 | credentials.get('client_id'),
74 | credentials.get('scopes'),
75 | credentials.get('client_secret'),
76 | credentials.get('redirect_url'),
77 | )
78 |
79 | auth_url = auth_flow.get_authorization_url()
80 | login_message = 'Login as a driver and grant access by going to:\n\n{}\n'
81 | login_message = login_message.format(auth_url)
82 | response_print(login_message)
83 |
84 | redirect_url = 'Copy the URL you are redirected to and paste here:\n\n'
85 | result = input(redirect_url).strip()
86 |
87 | try:
88 | session = auth_flow.get_session(result)
89 |
90 | except (ClientError, UberIllegalState) as error:
91 | fail_print(error)
92 | return
93 |
94 | credential = session.oauth2credential
95 |
96 | credential_data = {
97 | 'client_id': credential.client_id,
98 | 'redirect_url': credential.redirect_url,
99 | 'access_token': credential.access_token,
100 | 'expires_in_seconds': credential.expires_in_seconds,
101 | 'scopes': list(credential.scopes),
102 | 'grant_type': credential.grant_type,
103 | 'client_secret': credential.client_secret,
104 | 'refresh_token': credential.refresh_token,
105 | }
106 |
107 | with open(storage_filename, 'w') as yaml_file:
108 | yaml_file.write(safe_dump(credential_data, default_flow_style=False))
109 |
110 | return UberRidesClient(session, sandbox_mode=True)
111 |
112 |
113 | def hello_user(api_client):
114 | """Use an authorized client to fetch and print profile information.
115 |
116 | Parameters
117 | api_client (UberRidesClient)
118 | An UberRidesClient with OAuth 2.0 credentials.
119 | """
120 |
121 | try:
122 | response = api_client.get_driver_profile()
123 |
124 | except (ClientError, ServerError) as error:
125 | fail_print(error)
126 | return
127 |
128 | else:
129 | profile = response.json
130 | first_name = profile.get('first_name')
131 | last_name = profile.get('last_name')
132 | email = profile.get('email')
133 | message = 'Hello, {} {}. Successfully granted access token to {}.'
134 | message = message.format(first_name, last_name, email)
135 | success_print(message)
136 | success_print(profile)
137 |
138 | success_print('---')
139 | response = api_client.get_driver_trips()
140 | trips = response.json
141 | success_print(trips)
142 |
143 | success_print('---')
144 | response = api_client.get_driver_payments()
145 | payments = response.json
146 | success_print(payments)
147 |
148 |
149 | if __name__ == '__main__':
150 | """Run the example.
151 |
152 | Get an access token through the OAuth 2.0 Authorization Code Grant
153 | and use credentials to create an UberRidesClient.
154 | """
155 | credentials = import_app_credentials('config.driver.yaml')
156 |
157 | api_client = authorization_code_grant_flow(
158 | credentials,
159 | 'oauth_driver_session_store.yaml',
160 | )
161 |
162 | hello_user(api_client)
163 |
--------------------------------------------------------------------------------
/example/authorize_rider.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | """Initializes an UberRidesClient with OAuth 2.0 Credentials.
22 |
23 | This example demonstrates how to get an access token through the
24 | OAuth 2.0 Authorization Code Grant and use credentials to create
25 | an UberRidesClient.
26 |
27 | To run this example:
28 |
29 | (1) Set your app credentials in config.yaml
30 | (2) Run `python authorize_rider.py`
31 | (3) A success message will print, 'Hello {YOUR_NAME}'
32 | (4) User OAuth 2.0 credentials are recorded in
33 | 'oauth_rider_session_store.yaml'
34 | """
35 |
36 | from __future__ import absolute_import
37 | from __future__ import division
38 | from __future__ import print_function
39 | from __future__ import unicode_literals
40 |
41 | from builtins import input
42 |
43 | from yaml import safe_dump
44 |
45 | from example import utils # NOQA
46 | from example.utils import fail_print
47 | from example.utils import response_print
48 | from example.utils import success_print
49 | from example.utils import import_app_credentials
50 |
51 | from uber_rides.auth import AuthorizationCodeGrant
52 | from uber_rides.client import UberRidesClient
53 | from uber_rides.errors import ClientError
54 | from uber_rides.errors import ServerError
55 | from uber_rides.errors import UberIllegalState
56 |
57 |
58 | def authorization_code_grant_flow(credentials, storage_filename):
59 | """Get an access token through Authorization Code Grant.
60 |
61 | Parameters
62 | credentials (dict)
63 | All your app credentials and information
64 | imported from the configuration file.
65 | storage_filename (str)
66 | Filename to store OAuth 2.0 Credentials.
67 |
68 | Returns
69 | (UberRidesClient)
70 | An UberRidesClient with OAuth 2.0 Credentials.
71 | """
72 | auth_flow = AuthorizationCodeGrant(
73 | credentials.get('client_id'),
74 | credentials.get('scopes'),
75 | credentials.get('client_secret'),
76 | credentials.get('redirect_url'),
77 | )
78 |
79 | auth_url = auth_flow.get_authorization_url()
80 | login_message = 'Login as a rider and grant access by going to:\n\n{}\n'
81 | login_message = login_message.format(auth_url)
82 | response_print(login_message)
83 |
84 | redirect_url = 'Copy the URL you are redirected to and paste here: \n\n'
85 | result = input(redirect_url).strip()
86 |
87 | try:
88 | session = auth_flow.get_session(result)
89 |
90 | except (ClientError, UberIllegalState) as error:
91 | fail_print(error)
92 | return
93 |
94 | credential = session.oauth2credential
95 |
96 | credential_data = {
97 | 'client_id': credential.client_id,
98 | 'redirect_url': credential.redirect_url,
99 | 'access_token': credential.access_token,
100 | 'expires_in_seconds': credential.expires_in_seconds,
101 | 'scopes': list(credential.scopes),
102 | 'grant_type': credential.grant_type,
103 | 'client_secret': credential.client_secret,
104 | 'refresh_token': credential.refresh_token,
105 | }
106 |
107 | with open(storage_filename, 'w') as yaml_file:
108 | yaml_file.write(safe_dump(credential_data, default_flow_style=False))
109 |
110 | return UberRidesClient(session, sandbox_mode=True)
111 |
112 |
113 | def hello_user(api_client):
114 | """Use an authorized client to fetch and print profile information.
115 |
116 | Parameters
117 | api_client (UberRidesClient)
118 | An UberRidesClient with OAuth 2.0 credentials.
119 | """
120 |
121 | try:
122 | response = api_client.get_user_profile()
123 |
124 | except (ClientError, ServerError) as error:
125 | fail_print(error)
126 | return
127 |
128 | else:
129 | profile = response.json
130 | first_name = profile.get('first_name')
131 | last_name = profile.get('last_name')
132 | email = profile.get('email')
133 | message = 'Hello, {} {}. Successfully granted access token to {}.'
134 | message = message.format(first_name, last_name, email)
135 | success_print(message)
136 | success_print(profile)
137 |
138 | success_print('---')
139 | response = api_client.get_home_address()
140 | address = response.json
141 | success_print(address)
142 |
143 | success_print('---')
144 | response = api_client.get_user_activity()
145 | history = response.json
146 | success_print(history)
147 |
148 |
149 | if __name__ == '__main__':
150 | """Run the example.
151 |
152 | Get an access token through the OAuth 2.0 Authorization Code Grant
153 | and use credentials to create an UberRidesClient.
154 | """
155 | credentials = import_app_credentials('config.rider.yaml')
156 |
157 | api_client = authorization_code_grant_flow(
158 | credentials,
159 | 'oauth_rider_session_store.yaml',
160 | )
161 |
162 | hello_user(api_client)
163 |
--------------------------------------------------------------------------------
/example/config.driver.yaml:
--------------------------------------------------------------------------------
1 | client_id: xxx
2 | client_secret: xxx
3 | redirect_url: http://localhost:8000/uber/connect
4 | scopes:
5 | - partner.accounts
6 | - partner.trips
7 | - partner.payments
8 |
--------------------------------------------------------------------------------
/example/config.rider.yaml:
--------------------------------------------------------------------------------
1 | client_id: xxx
2 | client_secret: xxx
3 | redirect_url: http://localhost:8000/uber/connect
4 | scopes:
5 | - profile
6 | - history
7 | - places
8 | - request
9 | - request_receipt
10 | - all_trips
11 |
--------------------------------------------------------------------------------
/example/driver_dashboard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Uber Driver Dashboard
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
30 |
31 |
33 |
34 |
35 |
36 | Rating: {{ profile.rating }}
37 |
38 | {% if trips.0 %}
39 |
44 | {% else %}
45 | No trips yet!
46 | {% endif %}
47 |
48 | {% if payments.0 %}
49 |
50 |
51 | Made {{ payments | sum(attribute='amount') }}{{ payments.0.currency_code }} for driving {{ trips | sum(attribute='distance') }} miles.
52 |
53 | {% endif %}
54 |
55 |
56 |
57 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/example/driver_dashboard.py:
--------------------------------------------------------------------------------
1 |
2 | from flask import Flask, redirect, request, render_template
3 |
4 | from example import utils # NOQA
5 | from example.utils import import_app_credentials
6 |
7 | from uber_rides.auth import AuthorizationCodeGrant
8 | from uber_rides.client import UberRidesClient
9 |
10 | import datetime
11 |
12 | app = Flask(__name__, template_folder="./")
13 |
14 | credentials = import_app_credentials('config.driver.yaml')
15 |
16 | auth_flow = AuthorizationCodeGrant(
17 | credentials.get('client_id'),
18 | credentials.get('scopes'),
19 | credentials.get('client_secret'),
20 | credentials.get('redirect_url'),
21 | )
22 |
23 |
24 | @app.template_filter('date')
25 | def date(value, format='%b %d, %Y at %H:%M'):
26 | return datetime.datetime.fromtimestamp(value).strftime(format)
27 |
28 |
29 | @app.route('/')
30 | def index():
31 | """Index controller to redirect user to sign in with uber."""
32 | return redirect(auth_flow.get_authorization_url())
33 |
34 |
35 | @app.route('/uber/connect')
36 | def connect():
37 | """Connect controller to handle token exchange and query Uber API."""
38 |
39 | # Exchange authorization code for acceess token and create session
40 | session = auth_flow.get_session(request.url)
41 | client = UberRidesClient(session)
42 |
43 | # Fetch profile for driver
44 | profile = client.get_driver_profile().json
45 |
46 | # Fetch last 50 trips and payments for driver
47 | trips = client.get_driver_trips(0, 50).json
48 | payments = client.get_driver_payments(0, 50).json
49 |
50 | return render_template('driver_dashboard.html',
51 | profile=profile,
52 | trips=trips['trips'],
53 | payments=payments['payments']
54 | )
55 |
56 |
57 | if __name__ == '__main__':
58 | app.run(host='0.0.0.0', port=8000, debug=True)
59 |
--------------------------------------------------------------------------------
/example/rider_dashboard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Uber Rider Dashboard
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
29 |
30 |
32 |
33 |
34 |
35 | You have traveled {{ total_distance_traveled|round|int }} miles in {{ total_rides }} Uber
36 | rides across {{ total_cities }} cities.
37 |
38 |
39 | {% for location in locations %}
40 | - {{ location }} ({{ locations[location] }}x)
41 | {% endfor %}
42 |
43 |
44 |
45 |
46 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/example/rider_dashboard.py:
--------------------------------------------------------------------------------
1 |
2 | from flask import Flask, redirect, request, render_template
3 |
4 | from example import utils # NOQA
5 | from example.utils import import_app_credentials
6 |
7 | from uber_rides.auth import AuthorizationCodeGrant
8 | from uber_rides.client import UberRidesClient
9 |
10 | from collections import OrderedDict, Counter
11 |
12 | app = Flask(__name__, template_folder="./")
13 |
14 | credentials = import_app_credentials('config.rider.yaml')
15 |
16 | auth_flow = AuthorizationCodeGrant(
17 | credentials.get('client_id'),
18 | credentials.get('scopes'),
19 | credentials.get('client_secret'),
20 | credentials.get('redirect_url'),
21 | )
22 |
23 |
24 | @app.route('/')
25 | def index():
26 | """Index controller to redirect user to sign in with uber."""
27 | return redirect(auth_flow.get_authorization_url())
28 |
29 |
30 | @app.route('/uber/connect')
31 | def connect():
32 | """Connect controller to handle token exchange and query Uber API."""
33 |
34 | # Exchange authorization code for acceess token and create session
35 | session = auth_flow.get_session(request.url)
36 | client = UberRidesClient(session)
37 |
38 | # Fetch profile for rider
39 | profile = client.get_rider_profile().json
40 |
41 | # Fetch all trips from history endpoint
42 | trips = []
43 | i = 0
44 | while True:
45 | try:
46 | response = client.get_rider_trips(
47 | limit=50,
48 | offset=i)
49 | i += 50
50 | if len(response.json['history']) > 0:
51 | trips += response.json['history']
52 | else:
53 | break
54 | except:
55 | break
56 | pass
57 |
58 | # Compute trip stats for # of rides and distance
59 | total_rides = 0
60 | total_distance_traveled = 0
61 |
62 | # Compute ranked list of # trips per city
63 | cities = list()
64 | for ride in trips:
65 | cities.append(ride['start_city']['display_name'])
66 |
67 | # only parse actually completed trips
68 | if ride['distance'] > 0:
69 | total_rides += 1
70 | total_distance_traveled += int(ride['distance'])
71 |
72 | total_cities = 0
73 | locations_counter = Counter(cities)
74 | locations = OrderedDict()
75 | cities_by_frequency = sorted(cities, key=lambda x: -locations_counter[x])
76 | for city in list(cities_by_frequency):
77 | if city not in locations:
78 | total_cities += 1
79 | locations[city] = cities.count(city)
80 |
81 | return render_template('rider_dashboard.html',
82 | profile=profile,
83 | trips=trips,
84 | locations=locations,
85 | total_rides=total_rides,
86 | total_cities=total_cities,
87 | total_distance_traveled=total_distance_traveled
88 | )
89 |
90 |
91 | if __name__ == '__main__':
92 | app.run(host='0.0.0.0', port=8000, debug=True)
93 |
--------------------------------------------------------------------------------
/example/utils.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | """General utilities for command line examples."""
22 |
23 | from __future__ import absolute_import
24 | from __future__ import division
25 | from __future__ import print_function
26 | from __future__ import unicode_literals
27 |
28 | from collections import namedtuple
29 | from yaml import safe_load
30 |
31 | from uber_rides.client import UberRidesClient
32 | from uber_rides.session import OAuth2Credential
33 | from uber_rides.session import Session
34 |
35 |
36 | # set your app credentials here
37 | CREDENTIALS_FILENAME = 'example/config.rider.yaml'
38 |
39 | # where your OAuth 2.0 credentials are stored
40 | STORAGE_FILENAME = 'example/oauth2_session_store.yaml'
41 |
42 | DEFAULT_CONFIG_VALUES = frozenset([
43 | 'INSERT_CLIENT_ID_HERE',
44 | 'INSERT_CLIENT_SECRET_HERE',
45 | 'INSERT_REDIRECT_URL_HERE',
46 | ])
47 |
48 | Colors = namedtuple('Colors', 'response, success, fail, end')
49 | COLORS = Colors(
50 | response='\033[94m',
51 | success='\033[92m',
52 | fail='\033[91m',
53 | end='\033[0m',
54 | )
55 |
56 |
57 | def success_print(message):
58 | """Print a message in green text.
59 |
60 | Parameters
61 | message (str)
62 | Message to print.
63 | """
64 | print(COLORS.success, message, COLORS.end)
65 |
66 |
67 | def response_print(message):
68 | """Print a message in blue text.
69 |
70 | Parameters
71 | message (str)
72 | Message to print.
73 | """
74 | print(COLORS.response, message, COLORS.end)
75 |
76 |
77 | def fail_print(error):
78 | """Print an error in red text.
79 |
80 | Parameters
81 | error (HTTPError)
82 | Error object to print.
83 | """
84 | print(COLORS.fail, error.message, COLORS.end)
85 |
86 |
87 | def paragraph_print(message):
88 | """Print message with padded newlines.
89 |
90 | Parameters
91 | message (str)
92 | Message to print.
93 | """
94 | paragraph = '\n{}\n'
95 | print(paragraph.format(message))
96 |
97 |
98 | def import_app_credentials(filename=CREDENTIALS_FILENAME):
99 | """Import app credentials from configuration file.
100 |
101 | Parameters
102 | filename (str)
103 | Name of configuration file.
104 |
105 | Returns
106 | credentials (dict)
107 | All your app credentials and information
108 | imported from the configuration file.
109 | """
110 | with open(filename, 'r') as config_file:
111 | config = safe_load(config_file)
112 |
113 | client_id = config['client_id']
114 | client_secret = config['client_secret']
115 | redirect_url = config['redirect_url']
116 |
117 | config_values = [client_id, client_secret, redirect_url]
118 |
119 | for value in config_values:
120 | if value in DEFAULT_CONFIG_VALUES:
121 | exit('Missing credentials in {}'.format(filename))
122 |
123 | credentials = {
124 | 'client_id': client_id,
125 | 'client_secret': client_secret,
126 | 'redirect_url': redirect_url,
127 | 'scopes': set(config['scopes']),
128 | }
129 |
130 | return credentials
131 |
132 |
133 | def import_oauth2_credentials(filename=STORAGE_FILENAME):
134 | """Import OAuth 2.0 session credentials from storage file.
135 |
136 | Parameters
137 | filename (str)
138 | Name of storage file.
139 |
140 | Returns
141 | credentials (dict)
142 | All your app credentials and information
143 | imported from the configuration file.
144 | """
145 | with open(filename, 'r') as storage_file:
146 | storage = safe_load(storage_file)
147 |
148 | # depending on OAuth 2.0 grant_type, these values may not exist
149 | client_secret = storage.get('client_secret')
150 | redirect_url = storage.get('redirect_url')
151 | refresh_token = storage.get('refresh_token')
152 |
153 | credentials = {
154 | 'access_token': storage['access_token'],
155 | 'client_id': storage['client_id'],
156 | 'client_secret': client_secret,
157 | 'expires_in_seconds': storage['expires_in_seconds'],
158 | 'grant_type': storage['grant_type'],
159 | 'redirect_url': redirect_url,
160 | 'refresh_token': refresh_token,
161 | 'scopes': storage['scopes'],
162 | }
163 |
164 | return credentials
165 |
166 |
167 | def create_uber_client(credentials):
168 | """Create an UberRidesClient from OAuth 2.0 credentials.
169 |
170 | Parameters
171 | credentials (dict)
172 | Dictionary of OAuth 2.0 credentials.
173 |
174 | Returns
175 | (UberRidesClient)
176 | An authorized UberRidesClient to access API resources.
177 | """
178 | oauth2credential = OAuth2Credential(
179 | client_id=credentials.get('client_id'),
180 | access_token=credentials.get('access_token'),
181 | expires_in_seconds=credentials.get('expires_in_seconds'),
182 | scopes=credentials.get('scopes'),
183 | grant_type=credentials.get('grant_type'),
184 | redirect_url=credentials.get('redirect_url'),
185 | client_secret=credentials.get('client_secret'),
186 | refresh_token=credentials.get('refresh_token'),
187 | )
188 | session = Session(oauth2credential=oauth2credential)
189 | return UberRidesClient(session, sandbox_mode=True)
190 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | appdirs==1.4.3
2 | certifi==2017.7.27.1
3 | chardet==3.0.4
4 | contextlib2==0.5.5
5 | funcsigs==1.0.2
6 | future==0.16.0
7 | futures==3.1.1
8 | idna==2.6
9 | mock==2.0.0
10 | packaging==16.8
11 | pbr==3.1.1
12 | py==1.4.34
13 | pyparsing==2.2.0
14 | pytest==3.2.1
15 | PyYAML==3.12
16 | requests==2.18.4
17 | six==1.10.0
18 | urllib3==1.22
19 | vcrpy==1.11.1
20 | wrapt==1.10.11
21 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 |
2 | [bdist_wheel]
3 | universal = 1
4 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from __future__ import absolute_import
3 | from __future__ import division
4 | from __future__ import print_function
5 | from __future__ import unicode_literals
6 |
7 | from setuptools import find_packages
8 | from setuptools import setup
9 |
10 | with open('README.rst') as f:
11 | readme = f.read()
12 |
13 | setup(
14 | name='uber_rides',
15 | version='0.6.0',
16 | packages=find_packages(),
17 | description='Official Uber API Python SDK',
18 | long_description=readme,
19 | url='https://github.com/uber/rides-python-sdk',
20 | license='MIT',
21 | author='Uber Technologies, Inc.',
22 | author_email='dev-advocates@uber.com',
23 | install_requires=['requests', 'pyyaml'],
24 | extras_require={
25 | ':python_version == "2.7"': ['future'],
26 | },
27 | tests_require=['pytest', 'mock', 'vcrpy'],
28 | keywords=['uber', 'api', 'sdk', 'rides', 'library'],
29 | )
30 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uber/rides-python-sdk/76ecd75ab5235d792ec1010e36eca679ba285127/tests/__init__.py
--------------------------------------------------------------------------------
/tests/fixtures/test_auth_code_get_session:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode code=xxx&redirect_uri=https%3A%2F%2Flocalhost%3A8000%2Fapi%2Fv1%2Fuber%2Foauth&client_id=xxx&client_secret=xxx&grant_type=authorization_code
4 | headers:
5 | Accept: ['*/*']
6 | Accept-Encoding: ['gzip, deflate']
7 | Connection: [keep-alive]
8 | Content-Length: ['233']
9 | Content-Type: [application/x-www-form-urlencoded]
10 | User-Agent: [python-requests/2.11.1]
11 | method: POST
12 | uri: https://login.uber.com/oauth/v2/token
13 | response:
14 | body: {string: !!python/unicode '{"last_authenticated":1485210848,"access_token":"xxx","expires_in":2592000,"token_type":"Bearer","scope":"profile
15 | history","refresh_token":"xxx"}'}
16 | headers:
17 | cache-control: [no-store, max-age=0]
18 | connection: [keep-alive]
19 | content-length: ['1017']
20 | content-type: [application/json]
21 | date: ['Tue, 24 Jan 2017 00:04:56 GMT']
22 | pragma: [no-cache]
23 | server: [nginx]
24 | set-cookie: [session=29afa247b81ce9ec_58869a28.WaWYr6GVd75geCKas-8FeDq2GxQ;
25 | Domain=login.uber.com; Secure; HttpOnly; Path=/]
26 | strict-transport-security: [max-age=604800, max-age=2592000]
27 | transfer-encoding: [chunked]
28 | x-content-type-options: [nosniff]
29 | x-frame-options: [SAMEORIGIN]
30 | x-uber-app: [login]
31 | x-xss-protection: [1; mode=block]
32 | status: {code: 200, message: OK}
33 | version: 1
34 |
--------------------------------------------------------------------------------
/tests/fixtures/test_cancel_current_ride:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | Content-Length: ['0']
6 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
7 | method: DELETE
8 | uri: https://sandbox-api.uber.com/v1.2/requests/current
9 | response:
10 | body: {string: !!python/unicode ''}
11 | headers:
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-type: [text/html; charset=UTF-8]
15 | date: ['Thu, 20 Oct 2016 08:36:29 GMT']
16 | server: [nginx]
17 | strict-transport-security: [max-age=0]
18 | x-content-type-options: [nosniff]
19 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
20 | x-xss-protection: [1; mode=block]
21 | status: {code: 204, message: No Content}
22 | - request:
23 | body: null
24 | headers:
25 | Content-Length: ['0']
26 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
27 | method: DELETE
28 | uri: https://sandbox-api.uber.com/v1.2/requests/current
29 | response:
30 | body: {string: !!python/unicode ''}
31 | headers:
32 | connection: [keep-alive]
33 | content-language: [en]
34 | content-type: [text/html; charset=UTF-8]
35 | date: ['Thu, 20 Oct 2016 08:41:46 GMT']
36 | server: [nginx]
37 | strict-transport-security: [max-age=0]
38 | x-content-type-options: [nosniff]
39 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
40 | x-xss-protection: [1; mode=block]
41 | status: {code: 204, message: No Content}
42 | - request:
43 | body: null
44 | headers:
45 | Content-Length: ['0']
46 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
47 | method: DELETE
48 | uri: https://sandbox-api.uber.com/v1.2/requests/current
49 | response:
50 | body: {string: !!python/unicode ''}
51 | headers:
52 | connection: [keep-alive]
53 | content-language: [en]
54 | content-type: [text/html; charset=UTF-8]
55 | date: ['Thu, 20 Oct 2016 08:48:14 GMT']
56 | server: [nginx]
57 | strict-transport-security: [max-age=0]
58 | x-content-type-options: [nosniff]
59 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
60 | x-xss-protection: [1; mode=block]
61 | status: {code: 204, message: No Content}
62 | - request:
63 | body: null
64 | headers:
65 | Content-Length: ['0']
66 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
67 | method: DELETE
68 | uri: https://sandbox-api.uber.com/v1.2/requests/current
69 | response:
70 | body: {string: !!python/unicode ''}
71 | headers:
72 | connection: [keep-alive]
73 | content-language: [en]
74 | content-type: [text/html; charset=UTF-8]
75 | date: ['Thu, 20 Oct 2016 08:49:40 GMT']
76 | server: [nginx]
77 | strict-transport-security: [max-age=0]
78 | x-content-type-options: [nosniff]
79 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
80 | x-xss-protection: [1; mode=block]
81 | status: {code: 204, message: No Content}
82 | version: 1
83 |
--------------------------------------------------------------------------------
/tests/fixtures/test_cancel_ride:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | Content-Length: ['0']
6 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
7 | method: DELETE
8 | uri: https://sandbox-api.uber.com/v1.2/requests/9bdb3278-21bd-46b8-90fa-51404b0d6acf
9 | response:
10 | body: {string: !!python/unicode ''}
11 | headers:
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-type: [text/html; charset=UTF-8]
15 | date: ['Thu, 20 Oct 2016 08:36:29 GMT']
16 | server: [nginx]
17 | strict-transport-security: [max-age=0]
18 | x-content-type-options: [nosniff]
19 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
20 | x-xss-protection: [1; mode=block]
21 | status: {code: 204, message: No Content}
22 | - request:
23 | body: null
24 | headers:
25 | Content-Length: ['0']
26 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
27 | method: DELETE
28 | uri: https://sandbox-api.uber.com/v1.2/requests/610d868b-e21c-483a-9932-97e61b852fd2
29 | response:
30 | body: {string: !!python/unicode ''}
31 | headers:
32 | connection: [keep-alive]
33 | content-language: [en]
34 | content-type: [text/html; charset=UTF-8]
35 | date: ['Thu, 20 Oct 2016 08:41:45 GMT']
36 | server: [nginx]
37 | strict-transport-security: [max-age=0]
38 | x-content-type-options: [nosniff]
39 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
40 | x-xss-protection: [1; mode=block]
41 | status: {code: 204, message: No Content}
42 | - request:
43 | body: null
44 | headers:
45 | Content-Length: ['0']
46 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
47 | method: DELETE
48 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
49 | response:
50 | body: {string: !!python/unicode ''}
51 | headers:
52 | connection: [keep-alive]
53 | content-language: [en]
54 | content-type: [text/html; charset=UTF-8]
55 | date: ['Thu, 20 Oct 2016 08:48:14 GMT']
56 | server: [nginx]
57 | strict-transport-security: [max-age=0]
58 | x-content-type-options: [nosniff]
59 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
60 | x-xss-protection: [1; mode=block]
61 | status: {code: 204, message: No Content}
62 | - request:
63 | body: null
64 | headers:
65 | Content-Length: ['0']
66 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
67 | method: DELETE
68 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
69 | response:
70 | body: {string: !!python/unicode ''}
71 | headers:
72 | connection: [keep-alive]
73 | content-language: [en]
74 | content-type: [text/html; charset=UTF-8]
75 | date: ['Thu, 20 Oct 2016 08:49:39 GMT']
76 | server: [nginx]
77 | strict-transport-security: [max-age=0]
78 | x-content-type-options: [nosniff]
79 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
80 | x-xss-protection: [1; mode=block]
81 | status: {code: 204, message: No Content}
82 | version: 1
83 |
--------------------------------------------------------------------------------
/tests/fixtures/test_client_credential_get_session:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode client_id=xxx&scope=partner.referrals&client_secret=xxx&grant_type=client_credentials
4 | headers:
5 | Accept: ['*/*']
6 | Accept-Encoding: ['gzip, deflate']
7 | Connection: [keep-alive]
8 | Content-Length: ['151']
9 | Content-Type: [application/x-www-form-urlencoded]
10 | User-Agent: [python-requests/2.11.1]
11 | method: POST
12 | uri: https://login.uber.com/oauth/v2/token
13 | response:
14 | body: {string: !!python/unicode '{"access_token":"xxx","token_type":"Bearer","last_authenticated":1485210848,"expires_in":2592000,"scope":"partner.referrals"}'}
15 | headers:
16 | cache-control: [no-store, max-age=0]
17 | connection: [keep-alive]
18 | content-length: ['864']
19 | content-type: [application/json]
20 | date: ['Tue, 24 Jan 2017 00:01:05 GMT']
21 | pragma: [no-cache]
22 | server: [nginx]
23 | set-cookie: [session=1b25e9fc5e9c4380_58869941.6C4QqAV6IdsPJqgrdPkjV46qJQo;
24 | Domain=login.uber.com; Secure; HttpOnly; Path=/]
25 | strict-transport-security: [max-age=604800, max-age=2592000]
26 | transfer-encoding: [chunked]
27 | x-content-type-options: [nosniff]
28 | x-frame-options: [SAMEORIGIN]
29 | x-uber-app: [login]
30 | x-xss-protection: [1; mode=block]
31 | status: {code: 200, message: OK}
32 | version: 1
33 |
--------------------------------------------------------------------------------
/tests/fixtures/test_estimate_ride:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"seat_count": null, "start_longitude": -122.4021253,
4 | "end_longitude": -122.4197513, "product_id": "821415d8-3bd5-4e27-9604-194e4359a449",
5 | "end_latitude": 37.775232, "end_place_id": null, "start_latitude": 37.7899886,
6 | "start_place_id": null}'
7 | headers:
8 | Content-Length: ['241']
9 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
10 | content-type: [application/json]
11 | method: POST
12 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
13 | response:
14 | body: {string: !!python/unicode '{"fare":{"value":11.41,"fare_id":"254f6a83aaa08f12f505f5f75a4ade69f1fe62cd5092dfbc48f5388134681249","expires_at":1476952703,"display":"$11.41","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":540,"distance_estimate":1.96},"pickup_estimate":4}'}
15 | headers:
16 | connection: [keep-alive]
17 | content-geo-system: [wgs-84]
18 | content-language: [en]
19 | content-length: ['267']
20 | content-type: [application/json]
21 | date: ['Thu, 20 Oct 2016 08:36:23 GMT']
22 | server: [nginx]
23 | strict-transport-security: [max-age=0]
24 | x-content-type-options: [nosniff]
25 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
26 | x-xss-protection: [1; mode=block]
27 | status: {code: 200, message: OK}
28 | - request:
29 | body: !!python/unicode '{"seat_count": null, "start_longitude": -122.4021253,
30 | "end_longitude": -122.4197513, "product_id": "821415d8-3bd5-4e27-9604-194e4359a449",
31 | "end_latitude": 37.775232, "end_place_id": null, "start_latitude": 37.7899886,
32 | "start_place_id": null}'
33 | headers:
34 | Content-Length: ['241']
35 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
36 | content-type: [application/json]
37 | method: POST
38 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
39 | response:
40 | body: {string: !!python/unicode '{"fare":{"value":10.8,"fare_id":"a93ccb928ed2d6896810030ba4dda0acb5a41c1782959e7bec1e03a8d5597136","expires_at":1476953019,"display":"$10.80","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":480,"distance_estimate":1.78},"pickup_estimate":4}'}
41 | headers:
42 | connection: [keep-alive]
43 | content-geo-system: [wgs-84]
44 | content-language: [en]
45 | content-length: ['266']
46 | content-type: [application/json]
47 | date: ['Thu, 20 Oct 2016 08:41:39 GMT']
48 | server: [nginx]
49 | strict-transport-security: [max-age=0]
50 | x-content-type-options: [nosniff]
51 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
52 | x-xss-protection: [1; mode=block]
53 | status: {code: 200, message: OK}
54 | - request:
55 | body: !!python/unicode '{"seat_count": null, "start_longitude": -122.4021253,
56 | "end_longitude": -122.4197513, "product_id": "821415d8-3bd5-4e27-9604-194e4359a449",
57 | "end_latitude": 37.775232, "end_place_id": null, "start_latitude": 37.7899886,
58 | "start_place_id": null}'
59 | headers:
60 | Content-Length: ['241']
61 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
62 | content-type: [application/json]
63 | method: POST
64 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
65 | response:
66 | body: {string: !!python/unicode '{"fare":{"value":10.79,"fare_id":"a20f0156059f3bff78b048eb00093869184c4808220e3b42cb93a3470de0b2bd","expires_at":1476953407,"display":"$10.79","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":480,"distance_estimate":1.78},"pickup_estimate":4}'}
67 | headers:
68 | connection: [keep-alive]
69 | content-geo-system: [wgs-84]
70 | content-language: [en]
71 | content-length: ['267']
72 | content-type: [application/json]
73 | date: ['Thu, 20 Oct 2016 08:48:07 GMT']
74 | server: [nginx]
75 | strict-transport-security: [max-age=0]
76 | x-content-type-options: [nosniff]
77 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
78 | x-xss-protection: [1; mode=block]
79 | status: {code: 200, message: OK}
80 | - request:
81 | body: !!python/unicode '{"seat_count": null, "start_longitude": -122.4021253,
82 | "end_longitude": -122.4197513, "product_id": "821415d8-3bd5-4e27-9604-194e4359a449",
83 | "end_latitude": 37.775232, "end_place_id": null, "start_latitude": 37.7899886,
84 | "start_place_id": null}'
85 | headers:
86 | Content-Length: ['241']
87 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
88 | content-type: [application/json]
89 | method: POST
90 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
91 | response:
92 | body: {string: !!python/unicode '{"fare":{"value":11.37,"fare_id":"cfc5e7aea155ab91e8b797ac595abe21f0e0bdb6fe48c8569f39e218a6a9326c","expires_at":1476953493,"display":"$11.37","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":540,"distance_estimate":1.96},"pickup_estimate":4}'}
93 | headers:
94 | connection: [keep-alive]
95 | content-geo-system: [wgs-84]
96 | content-language: [en]
97 | content-length: ['267']
98 | content-type: [application/json]
99 | date: ['Thu, 20 Oct 2016 08:49:33 GMT']
100 | server: [nginx]
101 | strict-transport-security: [max-age=0]
102 | x-content-type-options: [nosniff]
103 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
104 | x-xss-protection: [1; mode=block]
105 | status: {code: 200, message: OK}
106 | version: 1
107 |
--------------------------------------------------------------------------------
/tests/fixtures/test_estimate_ride_with_places:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"seat_count": null, "start_longitude": null, "end_longitude":
4 | null, "product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "end_latitude":
5 | null, "end_place_id": "work", "start_latitude": null, "start_place_id": "home"}'
6 | headers:
7 | Content-Length: ['218']
8 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
9 | content-type: [application/json]
10 | method: POST
11 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
12 | response:
13 | body: {string: !!python/unicode '{"fare":{"value":10.53,"fare_id":"0c00804e559af560519c820d1f16d5e87a71e9bcdc043ad005c3c77392e3e6da","expires_at":1476952704,"display":"$10.53","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":420,"distance_estimate":1.78},"pickup_estimate":3}'}
14 | headers:
15 | connection: [keep-alive]
16 | content-geo-system: [wgs-84]
17 | content-language: [en]
18 | content-length: ['267']
19 | content-type: [application/json]
20 | date: ['Thu, 20 Oct 2016 08:36:24 GMT']
21 | server: [nginx]
22 | strict-transport-security: [max-age=0]
23 | x-content-type-options: [nosniff]
24 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
25 | x-xss-protection: [1; mode=block]
26 | status: {code: 200, message: OK}
27 | - request:
28 | body: !!python/unicode '{"seat_count": null, "start_longitude": null, "end_longitude":
29 | null, "product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "end_latitude":
30 | null, "end_place_id": "work", "start_latitude": null, "start_place_id": "home"}'
31 | headers:
32 | Content-Length: ['218']
33 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
34 | content-type: [application/json]
35 | method: POST
36 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
37 | response:
38 | body: {string: !!python/unicode '{"fare":{"value":10.49,"fare_id":"3b6a75714b629721743f87f288055bfa1da9dc3a460271a4d78cd727ccdaec0f","expires_at":1476953020,"display":"$10.49","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":420,"distance_estimate":1.78},"pickup_estimate":3}'}
39 | headers:
40 | connection: [keep-alive]
41 | content-geo-system: [wgs-84]
42 | content-language: [en]
43 | content-length: ['267']
44 | content-type: [application/json]
45 | date: ['Thu, 20 Oct 2016 08:41:40 GMT']
46 | server: [nginx]
47 | strict-transport-security: [max-age=0]
48 | x-content-type-options: [nosniff]
49 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
50 | x-xss-protection: [1; mode=block]
51 | status: {code: 200, message: OK}
52 | - request:
53 | body: !!python/unicode '{"seat_count": null, "start_longitude": null, "end_longitude":
54 | null, "product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "end_latitude":
55 | null, "end_place_id": "work", "start_latitude": null, "start_place_id": "home"}'
56 | headers:
57 | Content-Length: ['218']
58 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
59 | content-type: [application/json]
60 | method: POST
61 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
62 | response:
63 | body: {string: !!python/unicode '{"fare":{"value":10.59,"fare_id":"f96b1c371386a8226d45547d25c3bf7d6982c9ba71b0903841ea88041e329627","expires_at":1476953409,"display":"$10.59","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":420,"distance_estimate":1.78},"pickup_estimate":3}'}
64 | headers:
65 | connection: [keep-alive]
66 | content-geo-system: [wgs-84]
67 | content-language: [en]
68 | content-length: ['267']
69 | content-type: [application/json]
70 | date: ['Thu, 20 Oct 2016 08:48:09 GMT']
71 | server: [nginx]
72 | strict-transport-security: [max-age=0]
73 | x-content-type-options: [nosniff]
74 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
75 | x-xss-protection: [1; mode=block]
76 | status: {code: 200, message: OK}
77 | - request:
78 | body: !!python/unicode '{"seat_count": null, "start_longitude": null, "end_longitude":
79 | null, "product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "end_latitude":
80 | null, "end_place_id": "work", "start_latitude": null, "start_place_id": "home"}'
81 | headers:
82 | Content-Length: ['218']
83 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
84 | content-type: [application/json]
85 | method: POST
86 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
87 | response:
88 | body: {string: !!python/unicode '{"fare":{"value":10.6,"fare_id":"0d789a6c6ef2c12ceb1bbbca8ec3ea88cb4e55cfdfb8a347ae7a20a003544966","expires_at":1476953494,"display":"$10.60","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":420,"distance_estimate":1.78},"pickup_estimate":3}'}
89 | headers:
90 | connection: [keep-alive]
91 | content-geo-system: [wgs-84]
92 | content-language: [en]
93 | content-length: ['266']
94 | content-type: [application/json]
95 | date: ['Thu, 20 Oct 2016 08:49:34 GMT']
96 | server: [nginx]
97 | strict-transport-security: [max-age=0]
98 | x-content-type-options: [nosniff]
99 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
100 | x-xss-protection: [1; mode=block]
101 | status: {code: 200, message: OK}
102 | version: 1
103 |
--------------------------------------------------------------------------------
/tests/fixtures/test_estimate_shared_ride:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"seat_count": 2, "start_longitude": -122.4021253, "end_longitude":
4 | -122.4197513, "product_id": "26546650-e557-4a7b-86e7-6a3942445247", "end_latitude":
5 | 37.775232, "end_place_id": null, "start_latitude": 37.7899886, "start_place_id":
6 | null}'
7 | headers:
8 | Content-Length: ['238']
9 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
10 | content-type: [application/json]
11 | method: POST
12 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
13 | response:
14 | body: {string: !!python/unicode '{"fare":{"value":7.3,"fare_id":"edff5663d5f237d2998568c68018055cee3cea732eee6dfcc13004f78e04ba29","expires_at":1476952702,"display":"$7.30","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":540,"distance_estimate":1.96},"pickup_estimate":3}'}
15 | headers:
16 | connection: [keep-alive]
17 | content-geo-system: [wgs-84]
18 | content-language: [en]
19 | content-length: ['264']
20 | content-type: [application/json]
21 | date: ['Thu, 20 Oct 2016 08:36:22 GMT']
22 | server: [nginx]
23 | strict-transport-security: [max-age=0]
24 | x-content-type-options: [nosniff]
25 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
26 | x-xss-protection: [1; mode=block]
27 | status: {code: 200, message: OK}
28 | - request:
29 | body: !!python/unicode '{"seat_count": 2, "start_longitude": -122.4021253, "end_longitude":
30 | -122.4197513, "product_id": "26546650-e557-4a7b-86e7-6a3942445247", "end_latitude":
31 | 37.775232, "end_place_id": null, "start_latitude": 37.7899886, "start_place_id":
32 | null}'
33 | headers:
34 | Content-Length: ['238']
35 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
36 | content-type: [application/json]
37 | method: POST
38 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
39 | response:
40 | body: {string: !!python/unicode '{"fare":{"value":6.99,"fare_id":"ca2326c28949fec46f7002f2a502de7ad8c70fb838c9ee0e0ebc12b242c652a9","expires_at":1476953018,"display":"$6.99","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":480,"distance_estimate":1.78},"pickup_estimate":3}'}
41 | headers:
42 | connection: [keep-alive]
43 | content-geo-system: [wgs-84]
44 | content-language: [en]
45 | content-length: ['265']
46 | content-type: [application/json]
47 | date: ['Thu, 20 Oct 2016 08:41:38 GMT']
48 | server: [nginx]
49 | strict-transport-security: [max-age=0]
50 | x-content-type-options: [nosniff]
51 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
52 | x-xss-protection: [1; mode=block]
53 | status: {code: 200, message: OK}
54 | - request:
55 | body: !!python/unicode '{"seat_count": 2, "start_longitude": -122.4021253, "end_longitude":
56 | -122.4197513, "product_id": "26546650-e557-4a7b-86e7-6a3942445247", "end_latitude":
57 | 37.775232, "end_place_id": null, "start_latitude": 37.7899886, "start_place_id":
58 | null}'
59 | headers:
60 | Content-Length: ['238']
61 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
62 | content-type: [application/json]
63 | method: POST
64 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
65 | response:
66 | body: {string: !!python/unicode '{"fare":{"value":6.9,"fare_id":"eb2c7950c4165007a2be115c898fe81bef06a68f8049069c5d4476c00def1212","expires_at":1476953407,"display":"$6.90","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":480,"distance_estimate":1.78},"pickup_estimate":4}'}
67 | headers:
68 | connection: [keep-alive]
69 | content-geo-system: [wgs-84]
70 | content-language: [en]
71 | content-length: ['264']
72 | content-type: [application/json]
73 | date: ['Thu, 20 Oct 2016 08:48:07 GMT']
74 | server: [nginx]
75 | strict-transport-security: [max-age=0]
76 | x-content-type-options: [nosniff]
77 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
78 | x-xss-protection: [1; mode=block]
79 | status: {code: 200, message: OK}
80 | - request:
81 | body: !!python/unicode '{"seat_count": 2, "start_longitude": -122.4021253, "end_longitude":
82 | -122.4197513, "product_id": "26546650-e557-4a7b-86e7-6a3942445247", "end_latitude":
83 | 37.775232, "end_place_id": null, "start_latitude": 37.7899886, "start_place_id":
84 | null}'
85 | headers:
86 | Content-Length: ['238']
87 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
88 | content-type: [application/json]
89 | method: POST
90 | uri: https://sandbox-api.uber.com/v1.2/requests/estimate
91 | response:
92 | body: {string: !!python/unicode '{"fare":{"value":7.22,"fare_id":"c2bf8adcb8004a67022642d0f8dfceebd888f1929156a7ca4c00eaf63e0310a7","expires_at":1476953492,"display":"$7.22","currency_code":"USD"},"trip":{"distance_unit":"mile","duration_estimate":540,"distance_estimate":1.96},"pickup_estimate":5}'}
93 | headers:
94 | connection: [keep-alive]
95 | content-geo-system: [wgs-84]
96 | content-language: [en]
97 | content-length: ['265']
98 | content-type: [application/json]
99 | date: ['Thu, 20 Oct 2016 08:49:32 GMT']
100 | server: [nginx]
101 | strict-transport-security: [max-age=0]
102 | x-content-type-options: [nosniff]
103 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
104 | x-xss-protection: [1; mode=block]
105 | status: {code: 200, message: OK}
106 | version: 1
107 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_business_receipt:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode 'Python Rides SDK v0.6.0']
6 | method: GET
7 | uri: https://api.uber.com/v1/business/trips/5152dcc5-b88d-4754-8b33-975f4067c942/receipt
8 | response:
9 | body: {string: !!python/unicode '{"family_name":"Developer","employee_id":"UUID-01-UD","trip_uuid":"5152dcc5-b88d-4754-8b33-975f4067c942","transaction_history":[{"amount":6.61,"short_reference":"GYYTK","currency_code":"USD","utc_timestamp":"2017-05-07T01:32:39.740Z","transaction_type":"SALE"}],"vat_amount":null,"distance":1.65,"expense_memo":"Jam
10 | on life","distance_unit":"miles","dropoff":{"location":{"city":"San Francisco","country":"US","longitude":-122.4203,"state":"CA","address":"1255
11 | Polk St, San Francisco, CA 94109, USA","latitude":37.7886},"time":{"unix_timestamp":1494120748,"utc_offset":"-07:00","utc_timestamp":"2017-05-07T01:32:28.000Z"}},"total_owed":0.0,"email":"uber.developer@example.com","organization_uuid":"c615e84c-72ea-490e-a060-823f14532632","pickup":{"location":{"city":"San
12 | Francisco","country":"US","longitude":-122.3994,"state":"CA","address":"141
13 | New Montgomery St, San Francisco, CA 94105, USA","latitude":37.7865},"time":{"unix_timestamp":1494120043,"utc_offset":"-07:00","utc_timestamp":"2017-05-07T01:20:43.000Z"}},"expense_code":"JAM","given_name":"Uber","total_charged":6.61,"duration":"00:11:46","product_name":"uberX","currency_code":"USD"}'}
14 | headers:
15 | cache-control: [max-age=0]
16 | connection: [keep-alive]
17 | content-language: [en]
18 | content-length: ['1145']
19 | content-type: [application/json]
20 | date: ['Thu, 14 Sep 2017 23:07:04 GMT']
21 | etag: [W/"18e7d9bd82ca47a8ab264d1b0b2433eaef3b3c92"]
22 | server: [nginx]
23 | strict-transport-security: [max-age=604800, max-age=2592000]
24 | x-content-type-options: [nosniff]
25 | x-frame-options: [SAMEORIGIN]
26 | x-rate-limit-limit: ['2000']
27 | x-rate-limit-remaining: ['1999']
28 | x-rate-limit-reset: ['1505433600']
29 | x-uber-app: [uberex-nonsandbox, optimus]
30 | x-xss-protection: [1; mode=block]
31 | status: {code: 200, message: OK}
32 | version: 1
33 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_business_trip_invoice_urls:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode 'Python Rides SDK v0.6.0']
6 | method: GET
7 | uri: https://api.uber.com/v1/business/trips/5152dcc5-b88d-4754-8b33-975f4067c942/invoice_urls
8 | response:
9 | body: {string: !!python/unicode '{"invoices":[],"organization_uuid":"c615e84c-72ea-490e-a060-823f14532632","trip_uuid":"5152dcc5-b88d-4754-8b33-975f4067c942"}'}
10 | headers:
11 | cache-control: [max-age=0]
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-length: ['125']
15 | content-type: [application/json]
16 | date: ['Thu, 14 Sep 2017 23:11:14 GMT']
17 | etag: [W/"5fee7563ff5c9f335807fc73a9b4dcb7ef9d5964"]
18 | server: [nginx]
19 | strict-transport-security: [max-age=604800, max-age=2592000]
20 | x-content-type-options: [nosniff]
21 | x-frame-options: [SAMEORIGIN]
22 | x-rate-limit-limit: ['2000']
23 | x-rate-limit-remaining: ['1997']
24 | x-rate-limit-reset: ['1505433600']
25 | x-uber-app: [uberex-nonsandbox, optimus]
26 | x-xss-protection: [1; mode=block]
27 | status: {code: 200, message: OK}
28 | version: 1
29 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_business_trip_receipt_pdf_url:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode 'Python Rides SDK v0.6.0']
6 | method: GET
7 | uri: https://api.uber.com/v1/business/trips/5152dcc5-b88d-4754-8b33-975f4067c942/receipt/pdf_url
8 | response:
9 | body: {string: !!python/unicode '{"trip_uuid":"5152dcc5-b88d-4754-8b33-975f4067c942","organization_uuid":"c615e84c-72ea-490e-a060-823f14532632","resource_url": "https://uber-common-public.s3.amazonaws.com/hamlet/b0ecf463.pdf"}'}
10 | headers:
11 | cache-control: [max-age=0]
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-type: [application/json]
15 | date: ['Thu, 14 Sep 2017 23:11:14 GMT']
16 | etag: [W/"5fee7563ff5c9f335807fc73a9b4dcb7ef9d5964"]
17 | server: [nginx]
18 | strict-transport-security: [max-age=604800, max-age=2592000]
19 | x-content-type-options: [nosniff]
20 | x-frame-options: [SAMEORIGIN]
21 | x-rate-limit-limit: ['2000']
22 | x-rate-limit-remaining: ['1994']
23 | x-rate-limit-reset: ['1505433400']
24 | x-uber-app: [uberex-nonsandbox, optimus]
25 | x-xss-protection: [1; mode=block]
26 | status: {code: 200, message: OK}
27 | version: 1
28 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_current_ride_details:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/requests/current
8 | response:
9 | body: {string: !!python/unicode '{"status":"processing","product_id":"821415d8-3bd5-4e27-9604-194e4359a449","destination":{"latitude":37.775232,"longitude":-122.4197513},"driver":null,"pickup":{"latitude":37.7899886,"eta":1,"longitude":-122.4021253},"request_id":"610d868b-e21c-483a-9932-97e61b852fd2","location":null,"vehicle":null,"shared":false}'}
10 | headers:
11 | connection: [keep-alive]
12 | content-geo-system: [wgs-84]
13 | content-language: [en]
14 | content-length: ['315']
15 | content-type: [application/json]
16 | date: ['Thu, 20 Oct 2016 08:36:27 GMT']
17 | etag: ['"ba4cb7f0193b2e0f8098077c09e82a4aef5cf8a5"']
18 | server: [nginx]
19 | strict-transport-security: [max-age=0]
20 | x-content-type-options: [nosniff]
21 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
22 | x-xss-protection: [1; mode=block]
23 | status: {code: 200, message: OK}
24 | - request:
25 | body: null
26 | headers:
27 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
28 | method: GET
29 | uri: https://sandbox-api.uber.com/v1.2/requests/current
30 | response:
31 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":404,"code":"no_current_trip","title":"User
32 | is not currently on a trip."}]}'}
33 | headers:
34 | connection: [keep-alive]
35 | content-length: ['105']
36 | content-type: [application/json]
37 | date: ['Thu, 20 Oct 2016 08:41:43 GMT']
38 | server: [nginx]
39 | strict-transport-security: [max-age=0]
40 | x-content-type-options: [nosniff]
41 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
42 | x-xss-protection: [1; mode=block]
43 | status: {code: 404, message: Not Found}
44 | - request:
45 | body: null
46 | headers:
47 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
48 | method: GET
49 | uri: https://sandbox-api.uber.com/v1.2/requests/current
50 | response:
51 | body: {string: !!python/unicode '{"status":"processing","product_id":"26546650-e557-4a7b-86e7-6a3942445247","destination":{"latitude":37.7899886,"longitude":-122.4021253},"driver":null,"pickup":{"latitude":37.775232,"eta":3,"longitude":-122.4197513},"request_id":"0aec0061-1e20-4239-a0b7-78328e9afec8","location":null,"vehicle":null,"shared":false}'}
52 | headers:
53 | connection: [keep-alive]
54 | content-geo-system: [wgs-84]
55 | content-language: [en]
56 | content-length: ['315']
57 | content-type: [application/json]
58 | date: ['Thu, 20 Oct 2016 08:48:12 GMT']
59 | etag: ['"c40a91960498f2fc6ba4e86530d640079cc012b0"']
60 | server: [nginx]
61 | strict-transport-security: [max-age=0]
62 | x-content-type-options: [nosniff]
63 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
64 | x-xss-protection: [1; mode=block]
65 | status: {code: 200, message: OK}
66 | - request:
67 | body: null
68 | headers:
69 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
70 | method: GET
71 | uri: https://sandbox-api.uber.com/v1.2/requests/current
72 | response:
73 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":404,"code":"no_current_trip","title":"User
74 | is not currently on a trip."}]}'}
75 | headers:
76 | connection: [keep-alive]
77 | content-length: ['105']
78 | content-type: [application/json]
79 | date: ['Thu, 20 Oct 2016 08:49:37 GMT']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 404, message: Not Found}
86 | version: 1
87 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_current_shared_ride_details:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/requests/current
8 | response:
9 | body: {string: !!python/unicode '{"status":"processing","product_id":"821415d8-3bd5-4e27-9604-194e4359a449","destination":{"latitude":37.775232,"longitude":-122.4197513},"driver":null,"pickup":{"latitude":37.7899886,"eta":1,"longitude":-122.4021253},"request_id":"610d868b-e21c-483a-9932-97e61b852fd2","location":null,"vehicle":null,"shared":false}'}
10 | headers:
11 | connection: [keep-alive]
12 | content-geo-system: [wgs-84]
13 | content-language: [en]
14 | content-length: ['315']
15 | content-type: [application/json]
16 | date: ['Thu, 20 Oct 2016 08:36:28 GMT']
17 | etag: ['"ba4cb7f0193b2e0f8098077c09e82a4aef5cf8a5"']
18 | server: [nginx]
19 | strict-transport-security: [max-age=0]
20 | x-content-type-options: [nosniff]
21 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
22 | x-xss-protection: [1; mode=block]
23 | status: {code: 200, message: OK}
24 | - request:
25 | body: null
26 | headers:
27 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
28 | method: GET
29 | uri: https://sandbox-api.uber.com/v1.2/requests/current
30 | response:
31 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":404,"code":"no_current_trip","title":"User
32 | is not currently on a trip."}]}'}
33 | headers:
34 | connection: [keep-alive]
35 | content-length: ['105']
36 | content-type: [application/json]
37 | date: ['Thu, 20 Oct 2016 08:41:43 GMT']
38 | server: [nginx]
39 | strict-transport-security: [max-age=0]
40 | x-content-type-options: [nosniff]
41 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
42 | x-xss-protection: [1; mode=block]
43 | status: {code: 404, message: Not Found}
44 | - request:
45 | body: null
46 | headers:
47 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
48 | method: GET
49 | uri: https://sandbox-api.uber.com/v1.2/requests/current
50 | response:
51 | body: {string: !!python/unicode '{"status":"processing","product_id":"26546650-e557-4a7b-86e7-6a3942445247","destination":{"latitude":37.7899886,"longitude":-122.4021253},"driver":null,"pickup":{"latitude":37.775232,"eta":3,"longitude":-122.4197513},"request_id":"0aec0061-1e20-4239-a0b7-78328e9afec8","location":null,"vehicle":null,"shared":false}'}
52 | headers:
53 | connection: [keep-alive]
54 | content-geo-system: [wgs-84]
55 | content-language: [en]
56 | content-length: ['315']
57 | content-type: [application/json]
58 | date: ['Thu, 20 Oct 2016 08:48:12 GMT']
59 | etag: ['"c40a91960498f2fc6ba4e86530d640079cc012b0"']
60 | server: [nginx]
61 | strict-transport-security: [max-age=0]
62 | x-content-type-options: [nosniff]
63 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
64 | x-xss-protection: [1; mode=block]
65 | status: {code: 200, message: OK}
66 | - request:
67 | body: null
68 | headers:
69 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
70 | method: GET
71 | uri: https://sandbox-api.uber.com/v1.2/requests/current
72 | response:
73 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":404,"code":"no_current_trip","title":"User
74 | is not currently on a trip."}]}'}
75 | headers:
76 | connection: [keep-alive]
77 | content-length: ['105']
78 | content-type: [application/json]
79 | date: ['Thu, 20 Oct 2016 08:49:37 GMT']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 404, message: Not Found}
86 | version: 1
87 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_driver_payments:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://api.uber.com/v1/partners/payments
8 | response:
9 | body: {string: !!python/unicode '{"count":13,"limit":10,"payments":[{"payment_id":"5cb8304c-f3f0-4a46-b6e3-b55e020750d7","category":"fare","event_time":1502842757,"trip_id":"5cb8304c-f3f0-4a46-b6e3-b55e020750d7","cash_collected":0.0,"amount":3.12,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":4.16,"service_fee":-1.04},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"a9d1efa8-f2b1-46a2-acee-6847c752b0eb","category":"fare","event_time":1502841851,"trip_id":"a9d1efa8-f2b1-46a2-acee-6847c752b0eb","cash_collected":0.0,"amount":4.49,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":5.99,"service_fee":-1.5},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"da30d9ce-4592-40fe-9ba9-c9b970d1d391","category":"fare","event_time":1502841640,"trip_id":"da30d9ce-4592-40fe-9ba9-c9b970d1d391","cash_collected":0.0,"amount":3.0,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":4.0,"service_fee":-1.0},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"b5613b6a-fe74-4704-a637-50f8d51a8bb1","category":"fare","event_time":1502843894,"trip_id":"b5613b6a-fe74-4704-a637-50f8d51a8bb1","cash_collected":0.0,"amount":3.0,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":4.0,"service_fee":-1.0},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"50eebfa4-9985-41ca-bbd9-be0150e32d4c","category":"fare","event_time":1502842172,"trip_id":"50eebfa4-9985-41ca-bbd9-be0150e32d4c","cash_collected":0.0,"amount":3.0,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":4.0,"service_fee":-1.0},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"ba950c43-c57a-4ab8-a8db-2057dd30756b","category":"fare","event_time":1502842655,"trip_id":"ba950c43-c57a-4ab8-a8db-2057dd30756b","cash_collected":0.0,"amount":3.0,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":4.0,"service_fee":-1.0},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"9ffeb986-0a73-4312-bb5e-22a1cc13e495","category":"fare","event_time":1502842917,"trip_id":"9ffeb986-0a73-4312-bb5e-22a1cc13e495","cash_collected":0.0,"amount":3.0,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":4.0,"service_fee":-1.0},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"4415e5f6-60f2-451f-ade1-c3d6ae286d76","category":"fare","event_time":1502843623,"trip_id":"4415e5f6-60f2-451f-ade1-c3d6ae286d76","cash_collected":0.0,"amount":3.0,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":4.0,"service_fee":-1.0},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"43851410-34ba-4054-9a4e-711e4e6a8fe5","category":"fare","event_time":1502843338,"trip_id":"43851410-34ba-4054-9a4e-711e4e6a8fe5","cash_collected":0.0,"amount":3.0,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":4.0,"service_fee":-1.0},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"},{"payment_id":"020f251b-e8ac-4ad1-ae9f-543a0db6b294","category":"fare","event_time":1502830183,"trip_id":"020f251b-e8ac-4ad1-ae9f-543a0db6b294","cash_collected":0.0,"amount":4.34,"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown":{"other":5.79,"service_fee":-1.45},"rider_fees":{},"partner_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code":"USD"}],"offset":0}'}
10 | headers:
11 | cache-control: [max-age=0]
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-type: [application/json]
15 | date: ['Wed, 16 Aug 2017 22:54:50 GMT']
16 | etag: [W/"a757f6e22e2dffdb1ccece2423b5f517f01ca791"]
17 | server: [nginx]
18 | strict-transport-security: [max-age=604800, max-age=2592000]
19 | transfer-encoding: [chunked]
20 | x-content-type-options: [nosniff]
21 | x-frame-options: [SAMEORIGIN]
22 | x-rate-limit-limit: ['2000']
23 | x-rate-limit-remaining: ['1995']
24 | x-rate-limit-reset: ['1502924400']
25 | x-uber-app: [uberex-nonsandbox, optimus]
26 | x-xss-protection: [1; mode=block]
27 | status: {code: 200, message: OK}
28 | version: 1
29 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_driver_profile:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://api.uber.com/v1/partners/me
8 | response:
9 | body: {string: !!python/unicode '{"phone_number":"+14075550001","picture":"https:\/\/d1w2poirtb3as9.cloudfront.net\/16ce502f4767f17b120e.jpeg","first_name":"Uber","last_name":"Tester","promo_code":"ubert4544ue","rating":5.0,"activation_status":"active","driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","email":"uber.developer+tester@example.com"}'}
10 | headers:
11 | cache-control: [max-age=0]
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-length: ['419']
15 | content-type: [application/json]
16 | date: ['Wed, 16 Aug 2017 22:54:50 GMT']
17 | etag: [W/"d76d91610e42a7b0d6e551766905af177b466447"]
18 | server: [nginx]
19 | strict-transport-security: [max-age=604800, max-age=2592000]
20 | x-content-type-options: [nosniff]
21 | x-frame-options: [SAMEORIGIN]
22 | x-rate-limit-limit: ['2000']
23 | x-rate-limit-remaining: ['1997']
24 | x-rate-limit-reset: ['1502924400']
25 | x-uber-app: [uberex-nonsandbox, optimus]
26 | x-xss-protection: [1; mode=block]
27 | status: {code: 200, message: OK}
28 | version: 1
29 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_driver_trips:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://api.uber.com/v1/partners/trips
8 | response:
9 | body: {string: !!python/unicode '{"count":13,"limit":10,"trips":[{"fare":6.2,"dropoff":{"timestamp":1502844378},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":0.37,"start_city":{"latitude":38.3498,"display_name":"Charleston,
10 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502843899},{"status":"driver_arrived","timestamp":1502843900},{"status":"trip_began","timestamp":1502843903},{"status":"completed","timestamp":1502844378}],"surge_multiplier":1.0,"pickup":{"timestamp":1502843903},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":475,"trip_id":"b5613b6a-fe74-4704-a637-50f8d51a8bb1","currency_code":"USD"},{"fare":6.4,"dropoff":{"timestamp":1502843883},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":0.96,"start_city":{"latitude":38.3498,"display_name":"Charleston,
11 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502843627},{"status":"driver_arrived","timestamp":1502843627},{"status":"trip_began","timestamp":1502843631},{"status":"completed","timestamp":1502843883}],"surge_multiplier":1.0,"pickup":{"timestamp":1502843631},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":253,"trip_id":"4415e5f6-60f2-451f-ade1-c3d6ae286d76","currency_code":"USD"},{"fare":6.2,"dropoff":{"timestamp":1502843563},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":0.0,"start_city":{"latitude":38.3498,"display_name":"Charleston,
12 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502843343},{"status":"driver_arrived","timestamp":1502843343},{"status":"trip_began","timestamp":1502843346},{"status":"completed","timestamp":1502843563}],"surge_multiplier":1.0,"pickup":{"timestamp":1502843346},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":217,"trip_id":"43851410-34ba-4054-9a4e-711e4e6a8fe5","currency_code":"USD"},{"fare":13.35,"dropoff":{"timestamp":1502843227},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":3.51,"start_city":{"latitude":38.3498,"display_name":"Charleston,
13 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502843039},{"status":"driver_arrived","timestamp":1502843040},{"status":"trip_began","timestamp":1502843043},{"status":"completed","timestamp":1502843227}],"surge_multiplier":1.0,"pickup":{"timestamp":1502843043},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":184,"trip_id":"fe8f00d9-2bd0-464a-82fe-8ce1ffd27057","currency_code":"USD"},{"fare":6.55,"dropoff":{"timestamp":1502843010},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":1.14,"start_city":{"latitude":38.3498,"display_name":"Charleston,
14 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502842919},{"status":"driver_arrived","timestamp":1502842919},{"status":"trip_began","timestamp":1502842922},{"status":"completed","timestamp":1502843010}],"surge_multiplier":1.0,"pickup":{"timestamp":1502842922},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":88,"trip_id":"9ffeb986-0a73-4312-bb5e-22a1cc13e495","currency_code":"USD"},{"fare":7.13,"dropoff":{"timestamp":1502842902},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":1.42,"start_city":{"latitude":38.3498,"display_name":"Charleston,
15 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502842761},{"status":"driver_arrived","timestamp":1502842761},{"status":"trip_began","timestamp":1502842763},{"status":"completed","timestamp":1502842902}],"surge_multiplier":1.0,"pickup":{"timestamp":1502842763},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":140,"trip_id":"5cb8304c-f3f0-4a46-b6e3-b55e020750d7","currency_code":"USD"},{"fare":6.53,"dropoff":null,"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":0.72,"start_city":{"latitude":38.3498,"display_name":"Charleston,
16 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502842659},{"status":"driver_arrived","timestamp":1502842660},{"status":"trip_began","timestamp":1502842662},{"status":"rider_canceled","timestamp":1502842731}],"surge_multiplier":1.0,"pickup":{"timestamp":1502842662},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"rider_canceled","duration":68,"trip_id":"ba950c43-c57a-4ab8-a8db-2057dd30756b","currency_code":"USD"},{"fare":9.68,"dropoff":{"timestamp":1502842611},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":3.82,"start_city":{"latitude":38.3498,"display_name":"Charleston,
17 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502842336},{"status":"driver_arrived","timestamp":1502842336},{"status":"trip_began","timestamp":1502842338},{"status":"completed","timestamp":1502842611}],"surge_multiplier":1.0,"pickup":{"timestamp":1502842338},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":273,"trip_id":"d80ea4dd-3eca-4215-8224-4162cd72eefb","currency_code":"USD"},{"fare":6.2,"dropoff":{"timestamp":1502842242},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":0.38,"start_city":{"latitude":38.3498,"display_name":"Charleston,
18 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502842176},{"status":"driver_arrived","timestamp":1502842177},{"status":"trip_began","timestamp":1502842180},{"status":"completed","timestamp":1502842242}],"surge_multiplier":1.0,"pickup":{"timestamp":1502842180},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":63,"trip_id":"50eebfa4-9985-41ca-bbd9-be0150e32d4c","currency_code":"USD"},{"fare":8.99,"dropoff":{"timestamp":1502842126},"vehicle_id":"0082b54a-6a5e-4f6b-b999-b0649f286381","distance":2.8,"start_city":{"latitude":38.3498,"display_name":"Charleston,
19 | WV","longitude":-81.6326},"status_changes":[{"status":"accepted","timestamp":1502841856},{"status":"driver_arrived","timestamp":1502841859},{"status":"trip_began","timestamp":1502841861},{"status":"completed","timestamp":1502842126}],"surge_multiplier":1.0,"pickup":{"timestamp":1502841861},"driver_id":"8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status":"completed","duration":264,"trip_id":"a9d1efa8-f2b1-46a2-acee-6847c752b0eb","currency_code":"USD"}],"offset":0}'}
20 | headers:
21 | cache-control: [max-age=0]
22 | connection: [keep-alive]
23 | content-language: [en]
24 | content-type: [application/json]
25 | date: ['Wed, 16 Aug 2017 22:54:50 GMT']
26 | etag: [W/"7341e30342fe59d8119b66b04f314ce1a7ab275f"]
27 | server: [nginx]
28 | strict-transport-security: [max-age=604800, max-age=2592000]
29 | transfer-encoding: [chunked]
30 | x-content-type-options: [nosniff]
31 | x-frame-options: [SAMEORIGIN]
32 | x-rate-limit-limit: ['2000']
33 | x-rate-limit-remaining: ['1996']
34 | x-rate-limit-reset: ['1502924400']
35 | x-uber-app: [uberex-nonsandbox, optimus]
36 | x-xss-protection: [1; mode=block]
37 | status: {code: 200, message: OK}
38 | version: 1
39 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_home_address:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/places/home
8 | response:
9 | body: {string: !!python/unicode '{"address":"555 Market St, San Francisco, CA
10 | 94105, USA"}'}
11 | headers:
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-length: ['57']
15 | content-type: [application/json]
16 | date: ['Thu, 20 Oct 2016 08:36:31 GMT']
17 | etag: ['"74feeed8e00d30505b9f97504dc53e839be347cc"']
18 | server: [nginx]
19 | strict-transport-security: [max-age=0]
20 | x-content-type-options: [nosniff]
21 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
22 | x-xss-protection: [1; mode=block]
23 | status: {code: 200, message: OK}
24 | - request:
25 | body: null
26 | headers:
27 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
28 | method: GET
29 | uri: https://sandbox-api.uber.com/v1.2/places/home
30 | response:
31 | body: {string: !!python/unicode '{"address":"555 Market St, San Francisco, CA
32 | 94105, USA"}'}
33 | headers:
34 | connection: [keep-alive]
35 | content-language: [en]
36 | content-length: ['57']
37 | content-type: [application/json]
38 | date: ['Thu, 20 Oct 2016 08:41:47 GMT']
39 | etag: ['"74feeed8e00d30505b9f97504dc53e839be347cc"']
40 | server: [nginx]
41 | strict-transport-security: [max-age=0]
42 | x-content-type-options: [nosniff]
43 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
44 | x-xss-protection: [1; mode=block]
45 | status: {code: 200, message: OK}
46 | - request:
47 | body: null
48 | headers:
49 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
50 | method: GET
51 | uri: https://sandbox-api.uber.com/v1.2/places/home
52 | response:
53 | body: {string: !!python/unicode '{"address":"555 Market St, San Francisco, CA
54 | 94105, USA"}'}
55 | headers:
56 | connection: [keep-alive]
57 | content-language: [en]
58 | content-length: ['57']
59 | content-type: [application/json]
60 | date: ['Thu, 20 Oct 2016 08:48:16 GMT']
61 | etag: ['"74feeed8e00d30505b9f97504dc53e839be347cc"']
62 | server: [nginx]
63 | strict-transport-security: [max-age=0]
64 | x-content-type-options: [nosniff]
65 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
66 | x-xss-protection: [1; mode=block]
67 | status: {code: 200, message: OK}
68 | - request:
69 | body: null
70 | headers:
71 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
72 | method: GET
73 | uri: https://sandbox-api.uber.com/v1.2/places/home
74 | response:
75 | body: {string: !!python/unicode '{"address":"555 Market St, San Francisco, CA
76 | 94105, USA"}'}
77 | headers:
78 | connection: [keep-alive]
79 | content-language: [en]
80 | content-length: ['57']
81 | content-type: [application/json]
82 | date: ['Thu, 20 Oct 2016 08:49:42 GMT']
83 | etag: ['"74feeed8e00d30505b9f97504dc53e839be347cc"']
84 | server: [nginx]
85 | strict-transport-security: [max-age=0]
86 | x-content-type-options: [nosniff]
87 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
88 | x-xss-protection: [1; mode=block]
89 | status: {code: 200, message: OK}
90 | version: 1
91 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_payment_methods:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/payment-methods
8 | response:
9 | body: {string: !!python/unicode '{"last_used":"517a6c29-3a2b-45cb-94a3-35d679909a71","payment_methods":[{"type":"american_express","description":"***05","payment_method_id":"517a6c29-3a2b-45cb-94a3-35d679909a71"}]}'}
10 | headers:
11 | connection: [keep-alive]
12 | content-language: [en]
13 | content-length: ['181']
14 | content-type: [application/json]
15 | date: ['Thu, 20 Oct 2016 08:36:32 GMT']
16 | etag: ['"2a24b71e77e897541be036fa1a578268e9df376c"']
17 | server: [nginx]
18 | strict-transport-security: [max-age=0]
19 | x-content-type-options: [nosniff]
20 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
21 | x-xss-protection: [1; mode=block]
22 | status: {code: 200, message: OK}
23 | - request:
24 | body: null
25 | headers:
26 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
27 | method: GET
28 | uri: https://sandbox-api.uber.com/v1.2/payment-methods
29 | response:
30 | body: {string: !!python/unicode '{"last_used":"517a6c29-3a2b-45cb-94a3-35d679909a71","payment_methods":[{"type":"american_express","description":"***05","payment_method_id":"517a6c29-3a2b-45cb-94a3-35d679909a71"}]}'}
31 | headers:
32 | connection: [keep-alive]
33 | content-language: [en]
34 | content-length: ['181']
35 | content-type: [application/json]
36 | date: ['Thu, 20 Oct 2016 08:41:48 GMT']
37 | etag: ['"2a24b71e77e897541be036fa1a578268e9df376c"']
38 | server: [nginx]
39 | strict-transport-security: [max-age=0]
40 | x-content-type-options: [nosniff]
41 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
42 | x-xss-protection: [1; mode=block]
43 | status: {code: 200, message: OK}
44 | - request:
45 | body: null
46 | headers:
47 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
48 | method: GET
49 | uri: https://sandbox-api.uber.com/v1.2/payment-methods
50 | response:
51 | body: {string: !!python/unicode '{"last_used":"517a6c29-3a2b-45cb-94a3-35d679909a71","payment_methods":[{"type":"american_express","description":"***05","payment_method_id":"517a6c29-3a2b-45cb-94a3-35d679909a71"}]}'}
52 | headers:
53 | connection: [keep-alive]
54 | content-language: [en]
55 | content-length: ['181']
56 | content-type: [application/json]
57 | date: ['Thu, 20 Oct 2016 08:48:17 GMT']
58 | etag: ['"2a24b71e77e897541be036fa1a578268e9df376c"']
59 | server: [nginx]
60 | strict-transport-security: [max-age=0]
61 | x-content-type-options: [nosniff]
62 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
63 | x-xss-protection: [1; mode=block]
64 | status: {code: 200, message: OK}
65 | - request:
66 | body: null
67 | headers:
68 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
69 | method: GET
70 | uri: https://sandbox-api.uber.com/v1.2/payment-methods
71 | response:
72 | body: {string: !!python/unicode '{"last_used":"517a6c29-3a2b-45cb-94a3-35d679909a71","payment_methods":[{"type":"american_express","description":"***05","payment_method_id":"517a6c29-3a2b-45cb-94a3-35d679909a71"}]}'}
73 | headers:
74 | connection: [keep-alive]
75 | content-language: [en]
76 | content-length: ['181']
77 | content-type: [application/json]
78 | date: ['Thu, 20 Oct 2016 08:49:43 GMT']
79 | etag: ['"2a24b71e77e897541be036fa1a578268e9df376c"']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 200, message: OK}
86 | version: 1
87 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_promotions:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/promotions?start_latitude=37.7899886&start_longitude=-122.4021253&end_latitude=37.775232&end_longitude=-122.4197513
8 | response:
9 | body: {string: !!python/unicode '{"display_text":"Free ride up to $15","localized_value":"$15","type":"trip_credit","value":15.0,"currency_code":"USD"}'}
10 | headers:
11 | connection: [keep-alive]
12 | content-language: [en]
13 | content-length: ['118']
14 | content-type: [application/json]
15 | date: ['Thu, 20 Oct 2016 08:22:37 GMT']
16 | etag: ['"2e4fdbfb8dcaa81fadf58188042048488eef7538"']
17 | server: [nginx]
18 | strict-transport-security: [max-age=0]
19 | x-content-type-options: [nosniff]
20 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
21 | x-xss-protection: [1; mode=block]
22 | status: {code: 200, message: OK}
23 | - request:
24 | body: null
25 | headers:
26 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
27 | method: GET
28 | uri: https://api.uber.com/v1.2/promotions?start_latitude=37.7899886&start_longitude=-122.4021253&end_latitude=37.775232&end_longitude=-122.4197513
29 | response:
30 | body: {string: !!python/unicode '{"display_text":"Free ride up to $15","localized_value":"$15","type":"trip_credit","value":15.0,"currency_code":"USD"}'}
31 | headers:
32 | connection: [keep-alive]
33 | content-language: [en]
34 | content-length: ['118']
35 | content-type: [application/json]
36 | date: ['Thu, 20 Oct 2016 08:22:37 GMT']
37 | etag: ['"2e4fdbfb8dcaa81fadf58188042048488eef7538"']
38 | server: [nginx]
39 | strict-transport-security: [max-age=0]
40 | x-content-type-options: [nosniff]
41 | x-uber-app: [uberex-nonsandbox, migrator-uberex-optimus]
42 | x-xss-protection: [1; mode=block]
43 | status: {code: 200, message: OK}
44 | - request:
45 | body: null
46 | headers:
47 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
48 | method: GET
49 | uri: https://sandbox-api.uber.com/v1.2/promotions?start_latitude=37.7899886&start_longitude=-122.4021253&end_latitude=37.775232&end_longitude=-122.4197513
50 | response:
51 | body: {string: !!python/unicode '{"display_text":"Free ride up to $15","localized_value":"$15","type":"trip_credit","value":15.0,"currency_code":"USD"}'}
52 | headers:
53 | connection: [keep-alive]
54 | content-language: [en]
55 | content-length: ['118']
56 | content-type: [application/json]
57 | date: ['Thu, 20 Oct 2016 08:41:37 GMT']
58 | etag: ['"2e4fdbfb8dcaa81fadf58188042048488eef7538"']
59 | server: [nginx]
60 | strict-transport-security: [max-age=0]
61 | x-content-type-options: [nosniff]
62 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
63 | x-xss-protection: [1; mode=block]
64 | status: {code: 200, message: OK}
65 | - request:
66 | body: null
67 | headers:
68 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
69 | method: GET
70 | uri: https://api.uber.com/v1.2/promotions?start_latitude=37.7899886&start_longitude=-122.4021253&end_latitude=37.775232&end_longitude=-122.4197513
71 | response:
72 | body: {string: !!python/unicode '{"display_text":"Free ride up to $15","localized_value":"$15","type":"trip_credit","value":15.0,"currency_code":"USD"}'}
73 | headers:
74 | connection: [keep-alive]
75 | content-language: [en]
76 | content-length: ['118']
77 | content-type: [application/json]
78 | date: ['Thu, 20 Oct 2016 08:41:37 GMT']
79 | etag: ['"2e4fdbfb8dcaa81fadf58188042048488eef7538"']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-nonsandbox, migrator-uberex-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 200, message: OK}
86 | - request:
87 | body: null
88 | headers:
89 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
90 | method: GET
91 | uri: https://sandbox-api.uber.com/v1.2/promotions?start_latitude=37.7899886&start_longitude=-122.4021253&end_latitude=37.775232&end_longitude=-122.4197513
92 | response:
93 | body: {string: !!python/unicode '{"display_text":"Free ride up to $15","localized_value":"$15","type":"trip_credit","value":15.0,"currency_code":"USD"}'}
94 | headers:
95 | connection: [keep-alive]
96 | content-language: [en]
97 | content-length: ['118']
98 | content-type: [application/json]
99 | date: ['Thu, 20 Oct 2016 08:48:05 GMT']
100 | etag: ['"2e4fdbfb8dcaa81fadf58188042048488eef7538"']
101 | server: [nginx]
102 | strict-transport-security: [max-age=0]
103 | x-content-type-options: [nosniff]
104 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
105 | x-xss-protection: [1; mode=block]
106 | status: {code: 200, message: OK}
107 | - request:
108 | body: null
109 | headers:
110 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
111 | method: GET
112 | uri: https://api.uber.com/v1.2/promotions?start_latitude=37.7899886&start_longitude=-122.4021253&end_latitude=37.775232&end_longitude=-122.4197513
113 | response:
114 | body: {string: !!python/unicode '{"display_text":"Free ride up to $15","localized_value":"$15","type":"trip_credit","value":15.0,"currency_code":"USD"}'}
115 | headers:
116 | connection: [keep-alive]
117 | content-language: [en]
118 | content-length: ['118']
119 | content-type: [application/json]
120 | date: ['Thu, 20 Oct 2016 08:48:05 GMT']
121 | etag: ['"2e4fdbfb8dcaa81fadf58188042048488eef7538"']
122 | server: [nginx]
123 | strict-transport-security: [max-age=0]
124 | x-content-type-options: [nosniff]
125 | x-uber-app: [uberex-nonsandbox, migrator-uberex-optimus]
126 | x-xss-protection: [1; mode=block]
127 | status: {code: 200, message: OK}
128 | - request:
129 | body: null
130 | headers:
131 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
132 | method: GET
133 | uri: https://sandbox-api.uber.com/v1.2/promotions?start_latitude=37.7899886&start_longitude=-122.4021253&end_latitude=37.775232&end_longitude=-122.4197513
134 | response:
135 | body: {string: !!python/unicode '{"display_text":"Free ride up to $15","localized_value":"$15","type":"trip_credit","value":15.0,"currency_code":"USD"}'}
136 | headers:
137 | connection: [keep-alive]
138 | content-language: [en]
139 | content-length: ['118']
140 | content-type: [application/json]
141 | date: ['Thu, 20 Oct 2016 08:49:31 GMT']
142 | etag: ['"2e4fdbfb8dcaa81fadf58188042048488eef7538"']
143 | server: [nginx]
144 | strict-transport-security: [max-age=0]
145 | x-content-type-options: [nosniff]
146 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
147 | x-xss-protection: [1; mode=block]
148 | status: {code: 200, message: OK}
149 | - request:
150 | body: null
151 | headers:
152 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
153 | method: GET
154 | uri: https://api.uber.com/v1.2/promotions?start_latitude=37.7899886&start_longitude=-122.4021253&end_latitude=37.775232&end_longitude=-122.4197513
155 | response:
156 | body: {string: !!python/unicode '{"display_text":"Free ride up to $15","localized_value":"$15","type":"trip_credit","value":15.0,"currency_code":"USD"}'}
157 | headers:
158 | connection: [keep-alive]
159 | content-language: [en]
160 | content-length: ['118']
161 | content-type: [application/json]
162 | date: ['Thu, 20 Oct 2016 08:49:31 GMT']
163 | etag: ['"2e4fdbfb8dcaa81fadf58188042048488eef7538"']
164 | server: [nginx]
165 | strict-transport-security: [max-age=0]
166 | x-content-type-options: [nosniff]
167 | x-uber-app: [uberex-nonsandbox, migrator-uberex-optimus]
168 | x-xss-protection: [1; mode=block]
169 | status: {code: 200, message: OK}
170 | version: 1
171 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_ride_details:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/requests/9bdb3278-21bd-46b8-90fa-51404b0d6acf
8 | response:
9 | body: {string: !!python/unicode '{"message":"cannot find trip","code":"not_found"}'}
10 | headers:
11 | connection: [keep-alive]
12 | content-length: ['49']
13 | content-type: [application/json]
14 | date: ['Thu, 20 Oct 2016 08:36:27 GMT']
15 | server: [nginx]
16 | strict-transport-security: [max-age=0]
17 | x-content-type-options: [nosniff]
18 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
19 | x-xss-protection: [1; mode=block]
20 | status: {code: 404, message: Not Found}
21 | - request:
22 | body: null
23 | headers:
24 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
25 | method: GET
26 | uri: https://sandbox-api.uber.com/v1.2/requests/610d868b-e21c-483a-9932-97e61b852fd2
27 | response:
28 | body: {string: !!python/unicode '{"status":"rider_canceled","request_id":"610d868b-e21c-483a-9932-97e61b852fd2","driver":null,"location":null,"vehicle":null,"shared":false}'}
29 | headers:
30 | connection: [keep-alive]
31 | content-language: [en]
32 | content-length: ['139']
33 | content-type: [application/json]
34 | date: ['Thu, 20 Oct 2016 08:41:43 GMT']
35 | etag: ['"6fe60292e1aacfced16eb479e34f8998c099fac0"']
36 | server: [nginx]
37 | strict-transport-security: [max-age=0]
38 | x-content-type-options: [nosniff]
39 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
40 | x-xss-protection: [1; mode=block]
41 | status: {code: 200, message: OK}
42 | - request:
43 | body: null
44 | headers:
45 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
46 | method: GET
47 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
48 | response:
49 | body: {string: !!python/unicode '{"status":"processing","product_id":"26546650-e557-4a7b-86e7-6a3942445247","destination":{"latitude":37.7899886,"longitude":-122.4021253},"driver":null,"pickup":{"latitude":37.775232,"longitude":-122.4197513},"request_id":"0aec0061-1e20-4239-a0b7-78328e9afec8","location":null,"vehicle":null,"shared":false}'}
50 | headers:
51 | connection: [keep-alive]
52 | content-geo-system: [wgs-84]
53 | content-language: [en]
54 | content-length: ['307']
55 | content-type: [application/json]
56 | date: ['Thu, 20 Oct 2016 08:48:11 GMT']
57 | etag: ['"0472dd46bc441b9471f36592774c7b544d7aca13"']
58 | server: [nginx]
59 | strict-transport-security: [max-age=0]
60 | x-content-type-options: [nosniff]
61 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
62 | x-xss-protection: [1; mode=block]
63 | status: {code: 200, message: OK}
64 | - request:
65 | body: null
66 | headers:
67 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
68 | method: GET
69 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
70 | response:
71 | body: {string: !!python/unicode '{"status":"rider_canceled","request_id":"0aec0061-1e20-4239-a0b7-78328e9afec8","driver":null,"location":null,"vehicle":null,"shared":false}'}
72 | headers:
73 | connection: [keep-alive]
74 | content-language: [en]
75 | content-length: ['139']
76 | content-type: [application/json]
77 | date: ['Thu, 20 Oct 2016 08:49:37 GMT']
78 | etag: ['"e2040920cf35ec4f320fc0a04592f2541397bea9"']
79 | server: [nginx]
80 | strict-transport-security: [max-age=0]
81 | x-content-type-options: [nosniff]
82 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
83 | x-xss-protection: [1; mode=block]
84 | status: {code: 200, message: OK}
85 | version: 1
86 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_ride_map:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8/map
8 | response:
9 | body: {string: !!python/unicode '{"href":"https:\/\/sandbox-api.uber.com\/v1\/sandbox\/map","request_id":"0aec0061-1e20-4239-a0b7-78328e9afec8"}'}
10 | headers:
11 | connection: [keep-alive]
12 | content-language: [en]
13 | content-length: ['111']
14 | content-type: [application/json]
15 | date: ['Fri, 21 Oct 2016 01:15:00 GMT']
16 | etag: ['"0843ec9a5bf0314e51a0e83b2de31b5d3ac21f47"']
17 | server: [nginx]
18 | strict-transport-security: [max-age=0]
19 | x-content-type-options: [nosniff]
20 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
21 | x-xss-protection: [1; mode=block]
22 | status: {code: 200, message: OK}
23 | version: 1
24 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_ride_receipt:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8/receipt
8 | response:
9 | body: {string: !!python/unicode '{"distance":"1.87","charge_adjustments":[{"amount":"2.25","type":"booking_fee","name":"Booking
10 | Fee"}],"total_owed":null,"distance_label":"miles","total_charged":"$9.00","request_id":"0aec0061-1e20-4239-a0b7-78328e9afec8","duration":"00:11:32","total_fare":"$9.00","subtotal":"$9.00","currency_code":"USD"}'}
11 | headers:
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-length: ['305']
15 | content-type: [application/json]
16 | date: ['Fri, 21 Oct 2016 01:17:15 GMT']
17 | etag: ['"7f5216c11382891ac55db6557ec37f174b17637f"']
18 | server: [nginx]
19 | strict-transport-security: [max-age=0]
20 | x-content-type-options: [nosniff]
21 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
22 | x-xss-protection: [1; mode=block]
23 | status: {code: 200, message: OK}
24 | version: 1
25 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_rider_profile:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode 'Python Rides SDK v0.6.0']
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/me
8 | response:
9 | body: {string: !!python/unicode '{"picture":"https:\/\/d1w2poirtb3as9.cloudfront.net\/16ce502f4767f17b120e.png","first_name":"Uber","last_name":"Tester","promo_code":"uber_tester","rider_id":"8LvXuRBq254Ogmr8EMkovekFNa2848lyMaQevIto-aXmdbbwlDSvy50HMoiAHsFc8N7WW3gdo6smNKnmT2uJIlirAkhUmtNdzDytTda9qGwWHQiswLMo5jHET7k4RQsEPw==","email":"uber.developer+tester@example.com","mobile_verified":true,"uuid":"5cbc8ff1-29bb-469d-b31d-71126648bbb0"}'}
10 | headers:
11 | cache-control: [max-age=0]
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-length: ['395']
15 | content-type: [application/json]
16 | date: ['Fri, 18 Aug 2017 00:04:24 GMT']
17 | etag: [W/"bbb14deefec4704ee540ccc25c838f833f9f9689"]
18 | server: [nginx]
19 | strict-transport-security: [max-age=604800, max-age=2592000]
20 | x-content-type-options: [nosniff]
21 | x-frame-options: [SAMEORIGIN]
22 | x-uber-app: [uberex-sandbox, optimus]
23 | x-xss-protection: [1; mode=block]
24 | status: {code: 200, message: OK}
25 | version: 1
26 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_rider_trips:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode 'Python Rides SDK v0.6.0']
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/history
8 | response:
9 | body: {string: !!python/unicode '{"count":1678,"history":[{"status":"completed","distance":1.2917022901,"product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d","start_time":1502994399,"start_city":{"latitude":37.7749295,"display_name":"San
10 | Francisco","longitude":-122.4194155},"fare":8.02,"end_time":1502994827,"request_id":"d903203a-da02-45a3-964d-dd402174e3ae","currency_code":"USD","request_time":1502994212},{"status":"completed","distance":1.4490403973,"product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d","start_time":1502935226,"start_city":{"latitude":37.7749295,"display_name":"San
11 | Francisco","longitude":-122.4194155},"fare":7.34,"end_time":1502935773,"request_id":"f09af6aa-816d-4356-b5ed-98749cbcb145","currency_code":"USD","request_time":1502935075},{"status":"completed","distance":1.2886012532,"product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d","start_time":1502908015,"start_city":{"latitude":37.7749295,"display_name":"San
12 | Francisco","longitude":-122.4194155},"fare":8.1,"end_time":1502908400,"request_id":"dafa189b-747e-4273-bbc6-178a62b8046c","currency_code":"USD","request_time":1502907880},{"status":"completed","distance":1.4457831309,"product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d","start_time":1502845436,"start_city":{"latitude":37.7749295,"display_name":"San
13 | Francisco","longitude":-122.4194155},"fare":1.23,"end_time":1502846061,"request_id":"5f40ed6a-2654-4b1b-802c-80b578bb14cd","currency_code":"USD","request_time":1502845218},{"status":"completed","distance":1.3627998333,"product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d","start_time":1502819334,"start_city":{"latitude":37.7749295,"display_name":"San
14 | Francisco","longitude":-122.4194155},"fare":6.89,"end_time":1502819720,"request_id":"ad1f6cff-3587-41d9-905e-c80d7b0b9de1","currency_code":"USD","request_time":1502819209}],"limit":5,"offset":0}'}
15 | headers:
16 | cache-control: [max-age=0]
17 | connection: [keep-alive]
18 | content-language: [en]
19 | content-length: ['1796']
20 | content-type: [application/json]
21 | date: ['Fri, 18 Aug 2017 00:04:24 GMT']
22 | etag: [W/"710a1952efbc2724739c986c6b34c9e5ae3eaf46"]
23 | server: [nginx]
24 | strict-transport-security: [max-age=604800, max-age=2592000]
25 | x-content-type-options: [nosniff]
26 | x-frame-options: [SAMEORIGIN]
27 | x-rate-limit-limit: ['2000']
28 | x-rate-limit-remaining: ['1999']
29 | x-rate-limit-reset: ['1503018000']
30 | x-uber-app: [uberex-sandbox, optimus]
31 | x-xss-protection: [1; mode=block]
32 | status: {code: 200, message: OK}
33 | version: 1
34 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_user_profile:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/me
8 | response:
9 | body: {string: !!python/unicode '{"picture":"https:\/\/d1w2poirtb3as9.cloudfront.net\/f3be498cb0bbf570aa3d.jpeg","first_name":"Uber","last_name":"Developer","uuid":"f4a416e3-6016-4623-8ec9-d5ee105a6e27","rider_id":"8OlTlUG1TyeAQf1JiBZZdkKxuSSOUwu2IkO0Hf9d2HV52Pm25A0NvsbmbnZr85tLVi-s8CckpBK8Eq0Nke4X-no3AcSHfeVh6J5O6LiQt5LsBZDSi4qyVUdSLeYDnTtirw==","email":"uberdevelopers@gmail.com","mobile_verified":true,"promo_code":"uberd340ue"}'}
10 | headers:
11 | connection: [keep-alive]
12 | content-language: [en]
13 | content-length: ['400']
14 | content-type: [application/json]
15 | date: ['Thu, 20 Oct 2016 08:28:33 GMT']
16 | etag: ['"97ce42cf42a0c9c030421237f8ce7a28c0c1494f"']
17 | server: [nginx]
18 | strict-transport-security: [max-age=0]
19 | x-content-type-options: [nosniff]
20 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
21 | x-xss-protection: [1; mode=block]
22 | status: {code: 200, message: OK}
23 | - request:
24 | body: null
25 | headers:
26 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
27 | method: GET
28 | uri: https://sandbox-api.uber.com/v1.2/me
29 | response:
30 | body: {string: !!python/unicode '{"picture":"https:\/\/d1w2poirtb3as9.cloudfront.net\/f3be498cb0bbf570aa3d.jpeg","first_name":"Uber","last_name":"Developer","uuid":"f4a416e3-6016-4623-8ec9-d5ee105a6e27","rider_id":"8OlTlUG1TyeAQf1JiBZZdkKxuSSOUwu2IkO0Hf9d2HV52Pm25A0NvsbmbnZr85tLVi-s8CckpBK8Eq0Nke4X-no3AcSHfeVh6J5O6LiQt5LsBZDSi4qyVUdSLeYDnTtirw==","email":"uberdevelopers@gmail.com","mobile_verified":true,"promo_code":"uberd340ue"}'}
31 | headers:
32 | connection: [keep-alive]
33 | content-language: [en]
34 | content-length: ['400']
35 | content-type: [application/json]
36 | date: ['Thu, 20 Oct 2016 08:41:38 GMT']
37 | etag: ['"97ce42cf42a0c9c030421237f8ce7a28c0c1494f"']
38 | server: [nginx]
39 | strict-transport-security: [max-age=0]
40 | x-content-type-options: [nosniff]
41 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
42 | x-xss-protection: [1; mode=block]
43 | status: {code: 200, message: OK}
44 | - request:
45 | body: null
46 | headers:
47 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
48 | method: GET
49 | uri: https://sandbox-api.uber.com/v1.2/me
50 | response:
51 | body: {string: !!python/unicode '{"picture":"https:\/\/d1w2poirtb3as9.cloudfront.net\/f3be498cb0bbf570aa3d.jpeg","first_name":"Uber","last_name":"Developer","uuid":"f4a416e3-6016-4623-8ec9-d5ee105a6e27","rider_id":"8OlTlUG1TyeAQf1JiBZZdkKxuSSOUwu2IkO0Hf9d2HV52Pm25A0NvsbmbnZr85tLVi-s8CckpBK8Eq0Nke4X-no3AcSHfeVh6J5O6LiQt5LsBZDSi4qyVUdSLeYDnTtirw==","email":"uberdevelopers@gmail.com","mobile_verified":true,"promo_code":"uberd340ue"}'}
52 | headers:
53 | connection: [keep-alive]
54 | content-language: [en]
55 | content-length: ['400']
56 | content-type: [application/json]
57 | date: ['Thu, 20 Oct 2016 08:48:06 GMT']
58 | etag: ['"97ce42cf42a0c9c030421237f8ce7a28c0c1494f"']
59 | server: [nginx]
60 | strict-transport-security: [max-age=0]
61 | x-content-type-options: [nosniff]
62 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
63 | x-xss-protection: [1; mode=block]
64 | status: {code: 200, message: OK}
65 | - request:
66 | body: null
67 | headers:
68 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
69 | method: GET
70 | uri: https://sandbox-api.uber.com/v1.2/me
71 | response:
72 | body: {string: !!python/unicode '{"picture":"https:\/\/d1w2poirtb3as9.cloudfront.net\/f3be498cb0bbf570aa3d.jpeg","first_name":"Uber","last_name":"Developer","uuid":"f4a416e3-6016-4623-8ec9-d5ee105a6e27","rider_id":"8OlTlUG1TyeAQf1JiBZZdkKxuSSOUwu2IkO0Hf9d2HV52Pm25A0NvsbmbnZr85tLVi-s8CckpBK8Eq0Nke4X-no3AcSHfeVh6J5O6LiQt5LsBZDSi4qyVUdSLeYDnTtirw==","email":"uberdevelopers@gmail.com","mobile_verified":true,"promo_code":"uberd340ue"}'}
73 | headers:
74 | connection: [keep-alive]
75 | content-language: [en]
76 | content-length: ['400']
77 | content-type: [application/json]
78 | date: ['Thu, 20 Oct 2016 08:49:31 GMT']
79 | etag: ['"97ce42cf42a0c9c030421237f8ce7a28c0c1494f"']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 200, message: OK}
86 | version: 1
87 |
--------------------------------------------------------------------------------
/tests/fixtures/test_get_work_address:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: null
4 | headers:
5 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
6 | method: GET
7 | uri: https://sandbox-api.uber.com/v1.2/places/work
8 | response:
9 | body: {string: !!python/unicode '{"address":"1455 Market St, San Francisco, CA
10 | 94103, USA"}'}
11 | headers:
12 | connection: [keep-alive]
13 | content-language: [en]
14 | content-length: ['58']
15 | content-type: [application/json]
16 | date: ['Thu, 20 Oct 2016 08:36:32 GMT']
17 | etag: ['"9bc62a15a6f4b45bf80257930416c505b9cde3cd"']
18 | server: [nginx]
19 | strict-transport-security: [max-age=0]
20 | x-content-type-options: [nosniff]
21 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
22 | x-xss-protection: [1; mode=block]
23 | status: {code: 200, message: OK}
24 | - request:
25 | body: null
26 | headers:
27 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
28 | method: GET
29 | uri: https://sandbox-api.uber.com/v1.2/places/work
30 | response:
31 | body: {string: !!python/unicode '{"address":"1455 Market St, San Francisco, CA
32 | 94103, USA"}'}
33 | headers:
34 | connection: [keep-alive]
35 | content-language: [en]
36 | content-length: ['58']
37 | content-type: [application/json]
38 | date: ['Thu, 20 Oct 2016 08:41:48 GMT']
39 | etag: ['"9bc62a15a6f4b45bf80257930416c505b9cde3cd"']
40 | server: [nginx]
41 | strict-transport-security: [max-age=0]
42 | x-content-type-options: [nosniff]
43 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
44 | x-xss-protection: [1; mode=block]
45 | status: {code: 200, message: OK}
46 | - request:
47 | body: null
48 | headers:
49 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
50 | method: GET
51 | uri: https://sandbox-api.uber.com/v1.2/places/work
52 | response:
53 | body: {string: !!python/unicode '{"address":"1455 Market St, San Francisco, CA
54 | 94103, USA"}'}
55 | headers:
56 | connection: [keep-alive]
57 | content-language: [en]
58 | content-length: ['58']
59 | content-type: [application/json]
60 | date: ['Thu, 20 Oct 2016 08:48:16 GMT']
61 | etag: ['"9bc62a15a6f4b45bf80257930416c505b9cde3cd"']
62 | server: [nginx]
63 | strict-transport-security: [max-age=0]
64 | x-content-type-options: [nosniff]
65 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
66 | x-xss-protection: [1; mode=block]
67 | status: {code: 200, message: OK}
68 | - request:
69 | body: null
70 | headers:
71 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
72 | method: GET
73 | uri: https://sandbox-api.uber.com/v1.2/places/work
74 | response:
75 | body: {string: !!python/unicode '{"address":"1455 Market St, San Francisco, CA
76 | 94103, USA"}'}
77 | headers:
78 | connection: [keep-alive]
79 | content-language: [en]
80 | content-length: ['58']
81 | content-type: [application/json]
82 | date: ['Thu, 20 Oct 2016 08:49:42 GMT']
83 | etag: ['"9bc62a15a6f4b45bf80257930416c505b9cde3cd"']
84 | server: [nginx]
85 | strict-transport-security: [max-age=0]
86 | x-content-type-options: [nosniff]
87 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
88 | x-xss-protection: [1; mode=block]
89 | status: {code: 200, message: OK}
90 | version: 1
91 |
--------------------------------------------------------------------------------
/tests/fixtures/test_refresh_auth_code_access_token:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode redirect_uri=https%3A%2F%2Flocalhost%3A8000%2Fapi%2Fv1%2Fuber%2Foauth&client_id=xxx&client_secret=xxx&grant_type=refresh_token&refresh_token=xxx
4 | headers:
5 | Accept: ['*/*']
6 | Accept-Encoding: ['gzip, deflate']
7 | Connection: [keep-alive]
8 | Content-Length: ['235']
9 | Content-Type: [application/x-www-form-urlencoded]
10 | User-Agent: [python-requests/2.11.1]
11 | method: POST
12 | uri: https://login.uber.com/oauth/v2/token
13 | response:
14 | body: {string: !!python/unicode '{"last_authenticated":1485210848,"access_token":"xxx","expires_in":2592000,"token_type":"Bearer","scope":"profile
15 | history","refresh_token":"xxx"}'}
16 | headers:
17 | cache-control: [no-store, max-age=0]
18 | connection: [keep-alive]
19 | content-length: ['911']
20 | content-type: [application/json]
21 | date: ['Tue, 24 Jan 2017 01:14:57 GMT']
22 | pragma: [no-cache]
23 | server: [nginx]
24 | set-cookie: [session=e5b4c855402bec82_5886aa91.wNBLxxu2Z074BTuO-EP8DhuIY2U;
25 | Domain=login.uber.com; Secure; HttpOnly; Path=/]
26 | strict-transport-security: [max-age=604800, max-age=2592000]
27 | transfer-encoding: [chunked]
28 | x-content-type-options: [nosniff]
29 | x-frame-options: [SAMEORIGIN]
30 | x-uber-app: [login]
31 | x-xss-protection: [1; mode=block]
32 | status: {code: 200, message: OK}
33 | version: 1
34 |
--------------------------------------------------------------------------------
/tests/fixtures/test_refresh_client_credential_access_token:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode client_id=xxx&scope=partner.referrals&client_secret=xxx&grant_type=client_credentials
4 | headers:
5 | Accept: ['*/*']
6 | Accept-Encoding: ['gzip, deflate']
7 | Connection: [keep-alive]
8 | Content-Length: ['151']
9 | Content-Type: [application/x-www-form-urlencoded]
10 | User-Agent: [python-requests/2.11.1]
11 | method: POST
12 | uri: https://login.uber.com/oauth/v2/token
13 | response:
14 | body: {string: !!python/unicode '{"access_token":"xxx","token_type":"Bearer","last_authenticated":1485210848,"expires_in":2592000,"scope":"partner.referrals"}'}
15 | headers:
16 | cache-control: [no-store, max-age=0]
17 | connection: [keep-alive]
18 | content-length: ['864']
19 | content-type: [application/json]
20 | date: ['Mon, 23 Jan 2017 22:57:35 GMT']
21 | pragma: [no-cache]
22 | server: [nginx]
23 | set-cookie: [session=bcbf256d4922c558_58868a5f.wJPhMqR1PV7dIs_zelHBTAesgY8;
24 | Domain=login.uber.com; Secure; HttpOnly; Path=/]
25 | strict-transport-security: [max-age=604800, max-age=2592000]
26 | transfer-encoding: [chunked]
27 | x-content-type-options: [nosniff]
28 | x-frame-options: [SAMEORIGIN]
29 | x-uber-app: [login]
30 | x-xss-protection: [1; mode=block]
31 | status: {code: 200, message: OK}
32 | version: 1
33 |
--------------------------------------------------------------------------------
/tests/fixtures/test_request_ride:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
4 | null, "start_address": null, "end_place_id": null, "fare_id": "8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c",
5 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
6 | "product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "seat_count": null, "end_address":
7 | null, "end_nickname": null, "start_place_id": null, "start_longitude": -122.4021253,
8 | "start_latitude": 37.7899886}'
9 | headers:
10 | Content-Length: ['468']
11 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
12 | content-type: [application/json]
13 | method: POST
14 | uri: https://sandbox-api.uber.com/v1.2/requests
15 | response:
16 | body: {string: !!python/unicode '{"status":"processing","product_id":"821415d8-3bd5-4e27-9604-194e4359a449","destination":{"latitude":37.775232,"longitude":-122.4197513},"driver":null,"pickup":{"latitude":37.7899886,"longitude":-122.4021253},"request_id":"610d868b-e21c-483a-9932-97e61b852fd2","eta":null,"location":null,"vehicle":null,"shared":false}'}
17 | headers:
18 | connection: [keep-alive]
19 | content-geo-system: [wgs-84]
20 | content-language: [en]
21 | content-length: ['318']
22 | content-type: [application/json]
23 | date: ['Thu, 20 Oct 2016 08:36:25 GMT']
24 | server: [nginx]
25 | strict-transport-security: [max-age=0]
26 | x-content-type-options: [nosniff]
27 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
28 | x-xss-protection: [1; mode=block]
29 | status: {code: 202, message: Accepted}
30 | - request:
31 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
32 | null, "start_address": null, "end_place_id": null, "fare_id": "8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c",
33 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
34 | "product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "seat_count": null, "end_address":
35 | null, "end_nickname": null, "start_place_id": null, "start_longitude": -122.4021253,
36 | "start_latitude": 37.7899886}'
37 | headers:
38 | Content-Length: ['468']
39 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
40 | content-type: [application/json]
41 | method: POST
42 | uri: https://sandbox-api.uber.com/v1.2/requests
43 | response:
44 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
45 | fare id: 8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c"}]}'}
46 | headers:
47 | connection: [keep-alive]
48 | content-geo-system: [wgs-84]
49 | content-length: ['154']
50 | content-type: [application/json]
51 | date: ['Thu, 20 Oct 2016 08:41:41 GMT']
52 | server: [nginx]
53 | strict-transport-security: [max-age=0]
54 | x-content-type-options: [nosniff]
55 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
56 | x-xss-protection: [1; mode=block]
57 | status: {code: 422, message: Unprocessable Entity}
58 | - request:
59 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
60 | null, "start_address": null, "end_place_id": null, "fare_id": "7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264",
61 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
62 | "product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "seat_count": null, "end_address":
63 | null, "end_nickname": null, "start_place_id": null, "start_longitude": -122.4021253,
64 | "start_latitude": 37.7899886}'
65 | headers:
66 | Content-Length: ['468']
67 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
68 | content-type: [application/json]
69 | method: POST
70 | uri: https://sandbox-api.uber.com/v1.2/requests
71 | response:
72 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
73 | fare id: 7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264"}]}'}
74 | headers:
75 | connection: [keep-alive]
76 | content-geo-system: [wgs-84]
77 | content-length: ['154']
78 | content-type: [application/json]
79 | date: ['Thu, 20 Oct 2016 08:48:09 GMT']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 422, message: Unprocessable Entity}
86 | - request:
87 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
88 | null, "start_address": null, "end_place_id": null, "fare_id": "7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264",
89 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
90 | "product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "seat_count": null, "end_address":
91 | null, "end_nickname": null, "start_place_id": null, "start_longitude": -122.4021253,
92 | "start_latitude": 37.7899886}'
93 | headers:
94 | Content-Length: ['468']
95 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
96 | content-type: [application/json]
97 | method: POST
98 | uri: https://sandbox-api.uber.com/v1.2/requests
99 | response:
100 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
101 | fare id: 7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264"}]}'}
102 | headers:
103 | connection: [keep-alive]
104 | content-geo-system: [wgs-84]
105 | content-length: ['154']
106 | content-type: [application/json]
107 | date: ['Thu, 20 Oct 2016 08:49:35 GMT']
108 | server: [nginx]
109 | strict-transport-security: [max-age=0]
110 | x-content-type-options: [nosniff]
111 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
112 | x-xss-protection: [1; mode=block]
113 | status: {code: 422, message: Unprocessable Entity}
114 | version: 1
115 |
--------------------------------------------------------------------------------
/tests/fixtures/test_request_ride_with_no_default_product:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
4 | null, "start_address": null, "end_place_id": null, "fare_id": "8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c",
5 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
6 | "product_id": null, "seat_count": null, "end_address": null, "end_nickname":
7 | null, "start_place_id": null, "start_longitude": -122.4021253, "start_latitude":
8 | 37.7899886}'
9 | headers:
10 | Content-Length: ['434']
11 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
12 | content-type: [application/json]
13 | method: POST
14 | uri: https://sandbox-api.uber.com/v1.2/requests
15 | response:
16 | body: {string: !!python/unicode '{"status":"processing","product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d","destination":{"latitude":37.775232,"longitude":-122.4197513},"driver":null,"pickup":{"latitude":37.7899886,"longitude":-122.4021253},"request_id":"610d868b-e21c-483a-9932-97e61b852fd2","eta":null,"location":null,"vehicle":null,"shared":false}'}
17 | headers:
18 | connection: [keep-alive]
19 | content-geo-system: [wgs-84]
20 | content-language: [en]
21 | content-length: ['318']
22 | content-type: [application/json]
23 | date: ['Thu, 20 Oct 2016 08:36:26 GMT']
24 | server: [nginx]
25 | strict-transport-security: [max-age=0]
26 | x-content-type-options: [nosniff]
27 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
28 | x-xss-protection: [1; mode=block]
29 | status: {code: 202, message: Accepted}
30 | - request:
31 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
32 | null, "start_address": null, "end_place_id": null, "fare_id": "8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c",
33 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
34 | "product_id": null, "seat_count": null, "end_address": null, "end_nickname":
35 | null, "start_place_id": null, "start_longitude": -122.4021253, "start_latitude":
36 | 37.7899886}'
37 | headers:
38 | Content-Length: ['434']
39 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
40 | content-type: [application/json]
41 | method: POST
42 | uri: https://sandbox-api.uber.com/v1.2/requests
43 | response:
44 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
45 | fare id: 8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c"}]}'}
46 | headers:
47 | connection: [keep-alive]
48 | content-geo-system: [wgs-84]
49 | content-length: ['154']
50 | content-type: [application/json]
51 | date: ['Thu, 20 Oct 2016 08:41:42 GMT']
52 | server: [nginx]
53 | strict-transport-security: [max-age=0]
54 | x-content-type-options: [nosniff]
55 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
56 | x-xss-protection: [1; mode=block]
57 | status: {code: 422, message: Unprocessable Entity}
58 | - request:
59 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
60 | null, "start_address": null, "end_place_id": null, "fare_id": "7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264",
61 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
62 | "product_id": null, "seat_count": null, "end_address": null, "end_nickname":
63 | null, "start_place_id": null, "start_longitude": -122.4021253, "start_latitude":
64 | 37.7899886}'
65 | headers:
66 | Content-Length: ['434']
67 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
68 | content-type: [application/json]
69 | method: POST
70 | uri: https://sandbox-api.uber.com/v1.2/requests
71 | response:
72 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
73 | fare id: 7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264"}]}'}
74 | headers:
75 | connection: [keep-alive]
76 | content-geo-system: [wgs-84]
77 | content-length: ['154']
78 | content-type: [application/json]
79 | date: ['Thu, 20 Oct 2016 08:48:10 GMT']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 422, message: Unprocessable Entity}
86 | - request:
87 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
88 | null, "start_address": null, "end_place_id": null, "fare_id": "7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264",
89 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
90 | "product_id": null, "seat_count": null, "end_address": null, "end_nickname":
91 | null, "start_place_id": null, "start_longitude": -122.4021253, "start_latitude":
92 | 37.7899886}'
93 | headers:
94 | Content-Length: ['434']
95 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
96 | content-type: [application/json]
97 | method: POST
98 | uri: https://sandbox-api.uber.com/v1.2/requests
99 | response:
100 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
101 | fare id: 7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264"}]}'}
102 | headers:
103 | connection: [keep-alive]
104 | content-geo-system: [wgs-84]
105 | content-length: ['154']
106 | content-type: [application/json]
107 | date: ['Thu, 20 Oct 2016 08:49:36 GMT']
108 | server: [nginx]
109 | strict-transport-security: [max-age=0]
110 | x-content-type-options: [nosniff]
111 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
112 | x-xss-protection: [1; mode=block]
113 | status: {code: 422, message: Unprocessable Entity}
114 | version: 1
115 |
--------------------------------------------------------------------------------
/tests/fixtures/test_request_ride_with_places:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"end_longitude": null, "surge_confirmation_id": null,
4 | "start_address": null, "end_place_id": "work", "fare_id": "8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c",
5 | "start_nickname": null, "end_latitude": null, "payment_method_id": null, "product_id":
6 | "821415d8-3bd5-4e27-9604-194e4359a449", "seat_count": null, "end_address": null,
7 | "end_nickname": null, "start_place_id": "home", "start_longitude": null, "start_latitude":
8 | null}'
9 | headers:
10 | Content-Length: ['445']
11 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
12 | content-type: [application/json]
13 | method: POST
14 | uri: https://sandbox-api.uber.com/v1.2/requests
15 | response:
16 | body: {string: !!python/unicode '{"status":"processing","product_id":"821415d8-3bd5-4e27-9604-194e4359a449","destination":{"latitude":37.775232,"longitude":-122.4197513},"driver":null,"pickup":{"latitude":37.7899886,"longitude":-122.4021253},"request_id":"610d868b-e21c-483a-9932-97e61b852fd2","eta":null,"location":null,"vehicle":null,"shared":false}'}
17 | headers:
18 | connection: [keep-alive]
19 | content-geo-system: [wgs-84]
20 | content-language: [en]
21 | content-length: ['318']
22 | content-type: [application/json]
23 | date: ['Thu, 20 Oct 2016 08:36:27 GMT']
24 | server: [nginx]
25 | strict-transport-security: [max-age=0]
26 | x-content-type-options: [nosniff]
27 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
28 | x-xss-protection: [1; mode=block]
29 | status: {code: 202, message: Accepted}
30 | - request:
31 | body: !!python/unicode '{"end_longitude": null, "surge_confirmation_id": null,
32 | "start_address": null, "end_place_id": "work", "fare_id": "8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c",
33 | "start_nickname": null, "end_latitude": null, "payment_method_id": null, "product_id":
34 | "821415d8-3bd5-4e27-9604-194e4359a449", "seat_count": null, "end_address": null,
35 | "end_nickname": null, "start_place_id": "home", "start_longitude": null, "start_latitude":
36 | null}'
37 | headers:
38 | Content-Length: ['445']
39 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
40 | content-type: [application/json]
41 | method: POST
42 | uri: https://sandbox-api.uber.com/v1.2/requests
43 | response:
44 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
45 | fare id: 8692d3a4e304b6071b1f6a8b64efa9546e327e79de1ba428a4829a00246d527c"}]}'}
46 | headers:
47 | connection: [keep-alive]
48 | content-geo-system: [wgs-84]
49 | content-length: ['154']
50 | content-type: [application/json]
51 | date: ['Thu, 20 Oct 2016 08:41:42 GMT']
52 | server: [nginx]
53 | strict-transport-security: [max-age=0]
54 | x-content-type-options: [nosniff]
55 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
56 | x-xss-protection: [1; mode=block]
57 | status: {code: 422, message: Unprocessable Entity}
58 | - request:
59 | body: !!python/unicode '{"end_longitude": null, "surge_confirmation_id": null,
60 | "start_address": null, "end_place_id": "work", "fare_id": "7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264",
61 | "start_nickname": null, "end_latitude": null, "payment_method_id": null, "product_id":
62 | "821415d8-3bd5-4e27-9604-194e4359a449", "seat_count": null, "end_address": null,
63 | "end_nickname": null, "start_place_id": "home", "start_longitude": null, "start_latitude":
64 | null}'
65 | headers:
66 | Content-Length: ['445']
67 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
68 | content-type: [application/json]
69 | method: POST
70 | uri: https://sandbox-api.uber.com/v1.2/requests
71 | response:
72 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
73 | fare id: 7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264"}]}'}
74 | headers:
75 | connection: [keep-alive]
76 | content-geo-system: [wgs-84]
77 | content-length: ['154']
78 | content-type: [application/json]
79 | date: ['Thu, 20 Oct 2016 08:48:11 GMT']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 422, message: Unprocessable Entity}
86 | - request:
87 | body: !!python/unicode '{"end_longitude": null, "surge_confirmation_id": null,
88 | "start_address": null, "end_place_id": "work", "fare_id": "7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264",
89 | "start_nickname": null, "end_latitude": null, "payment_method_id": null, "product_id":
90 | "821415d8-3bd5-4e27-9604-194e4359a449", "seat_count": null, "end_address": null,
91 | "end_nickname": null, "start_place_id": "home", "start_longitude": null, "start_latitude":
92 | null}'
93 | headers:
94 | Content-Length: ['445']
95 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
96 | content-type: [application/json]
97 | method: POST
98 | uri: https://sandbox-api.uber.com/v1.2/requests
99 | response:
100 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
101 | fare id: 7dad38f13eab3124621d16604c35fb26e30395e76937c507565fb1b4aa4a8264"}]}'}
102 | headers:
103 | connection: [keep-alive]
104 | content-geo-system: [wgs-84]
105 | content-length: ['154']
106 | content-type: [application/json]
107 | date: ['Thu, 20 Oct 2016 08:49:37 GMT']
108 | server: [nginx]
109 | strict-transport-security: [max-age=0]
110 | x-content-type-options: [nosniff]
111 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
112 | x-xss-protection: [1; mode=block]
113 | status: {code: 422, message: Unprocessable Entity}
114 | version: 1
115 |
--------------------------------------------------------------------------------
/tests/fixtures/test_request_ride_with_surge:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"end_longitude": -43.1925661, "surge_confirmation_id":
4 | null, "start_address": null, "end_place_id": null, "fare_id": null, "start_nickname":
5 | null, "end_latitude": -22.9883286, "payment_method_id": null, "product_id":
6 | "d5ef01d9-7d54-413e-b265-425948d06e92", "seat_count": null, "end_address": null,
7 | "end_nickname": null, "start_place_id": null, "start_longitude": -43.1801978,
8 | "start_latitude": -22.9674153}'
9 | headers:
10 | Content-Length: ['407']
11 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
12 | content-type: [application/json]
13 | method: POST
14 | uri: https://sandbox-api.uber.com/v1.2/requests
15 | response:
16 | body: {string: !!python/unicode '{"meta":{"surge_confirmation":{"href":"https:\/\/sandbox-api.uber.com\/surge-confirmations\/2674678f-c07e-4161-b4c8-17b13a985036","expires_at":1476953606,"multiplier":2.0,"surge_confirmation_id":"2674678f-c07e-4161-b4c8-17b13a985036"}},"errors":[{"status":409,"code":"surge","title":"Surge
17 | pricing is currently in effect for this product."}]}'}
18 | headers:
19 | connection: [keep-alive]
20 | content-geo-system: [wgs-84]
21 | content-length: ['342']
22 | content-type: [application/json]
23 | date: ['Thu, 20 Oct 2016 08:51:26 GMT']
24 | server: [nginx]
25 | strict-transport-security: [max-age=0]
26 | x-content-type-options: [nosniff]
27 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
28 | x-xss-protection: [1; mode=block]
29 | status: {code: 409, message: Conflict}
30 | version: 1
31 |
--------------------------------------------------------------------------------
/tests/fixtures/test_request_shared_ride:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
4 | null, "start_address": null, "end_place_id": null, "fare_id": "eab9a73fe7f9bf7e9c4e0df27c112635a195b8b00b1305766ebd91132fa47719",
5 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
6 | "product_id": "26546650-e557-4a7b-86e7-6a3942445247", "seat_count": 2, "end_address":
7 | null, "end_nickname": null, "start_place_id": null, "start_longitude": -122.4021253,
8 | "start_latitude": 37.7899886}'
9 | headers:
10 | Content-Length: ['465']
11 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
12 | content-type: [application/json]
13 | method: POST
14 | uri: https://sandbox-api.uber.com/v1.2/requests
15 | response:
16 | body: {string: !!python/unicode '{"status":"processing","product_id":"26546650-e557-4a7b-86e7-6a3942445247","destination":{"latitude":37.775232,"longitude":-122.4197513},"driver":null,"pickup":{"latitude":37.7899886,"longitude":-122.4021253},"request_id":"610d868b-e21c-483a-9932-97e61b852fd2","eta":null,"location":null,"vehicle":null,"shared":false}'}
17 | headers:
18 | connection: [keep-alive]
19 | content-geo-system: [wgs-84]
20 | content-language: [en]
21 | content-length: ['318']
22 | content-type: [application/json]
23 | date: ['Thu, 20 Oct 2016 08:36:25 GMT']
24 | server: [nginx]
25 | strict-transport-security: [max-age=0]
26 | x-content-type-options: [nosniff]
27 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
28 | x-xss-protection: [1; mode=block]
29 | status: {code: 202, message: Accepted}
30 | - request:
31 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
32 | null, "start_address": null, "end_place_id": null, "fare_id": "eab9a73fe7f9bf7e9c4e0df27c112635a195b8b00b1305766ebd91132fa47719",
33 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
34 | "product_id": "26546650-e557-4a7b-86e7-6a3942445247", "seat_count": 2, "end_address":
35 | null, "end_nickname": null, "start_place_id": null, "start_longitude": -122.4021253,
36 | "start_latitude": 37.7899886}'
37 | headers:
38 | Content-Length: ['465']
39 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
40 | content-type: [application/json]
41 | method: POST
42 | uri: https://sandbox-api.uber.com/v1.2/requests
43 | response:
44 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
45 | fare id: eab9a73fe7f9bf7e9c4e0df27c112635a195b8b00b1305766ebd91132fa47719"}]}'}
46 | headers:
47 | connection: [keep-alive]
48 | content-geo-system: [wgs-84]
49 | content-length: ['154']
50 | content-type: [application/json]
51 | date: ['Thu, 20 Oct 2016 08:41:41 GMT']
52 | server: [nginx]
53 | strict-transport-security: [max-age=0]
54 | x-content-type-options: [nosniff]
55 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
56 | x-xss-protection: [1; mode=block]
57 | status: {code: 422, message: Unprocessable Entity}
58 | - request:
59 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
60 | null, "start_address": null, "end_place_id": null, "fare_id": "d30e732b8bba22c9cdc10513ee86380087cb4a6f89e37ad21ba2a39f3a1ba960",
61 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
62 | "product_id": "26546650-e557-4a7b-86e7-6a3942445247", "seat_count": 2, "end_address":
63 | null, "end_nickname": null, "start_place_id": null, "start_longitude": -122.4021253,
64 | "start_latitude": 37.7899886}'
65 | headers:
66 | Content-Length: ['465']
67 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
68 | content-type: [application/json]
69 | method: POST
70 | uri: https://sandbox-api.uber.com/v1.2/requests
71 | response:
72 | body: {string: !!python/unicode '{"status":"processing","product_id":"26546650-e557-4a7b-86e7-6a3942445247","destination":{"latitude":37.7899886,"longitude":-122.4021253},"driver":null,"pickup":{"latitude":37.775232,"longitude":-122.4197513},"request_id":"0aec0061-1e20-4239-a0b7-78328e9afec8","eta":null,"location":null,"vehicle":null,"shared":false}'}
73 | headers:
74 | connection: [keep-alive]
75 | content-geo-system: [wgs-84]
76 | content-language: [en]
77 | content-length: ['318']
78 | content-type: [application/json]
79 | date: ['Thu, 20 Oct 2016 08:48:09 GMT']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 202, message: Accepted}
86 | - request:
87 | body: !!python/unicode '{"end_longitude": -122.4197513, "surge_confirmation_id":
88 | null, "start_address": null, "end_place_id": null, "fare_id": "d30e732b8bba22c9cdc10513ee86380087cb4a6f89e37ad21ba2a39f3a1ba960",
89 | "start_nickname": null, "end_latitude": 37.775232, "payment_method_id": null,
90 | "product_id": "26546650-e557-4a7b-86e7-6a3942445247", "seat_count": 2, "end_address":
91 | null, "end_nickname": null, "start_place_id": null, "start_longitude": -122.4021253,
92 | "start_latitude": 37.7899886}'
93 | headers:
94 | Content-Length: ['465']
95 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
96 | content-type: [application/json]
97 | method: POST
98 | uri: https://sandbox-api.uber.com/v1.2/requests
99 | response:
100 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":422,"code":"invalid_fare_id","title":"Invalid
101 | fare id: d30e732b8bba22c9cdc10513ee86380087cb4a6f89e37ad21ba2a39f3a1ba960"}]}'}
102 | headers:
103 | connection: [keep-alive]
104 | content-geo-system: [wgs-84]
105 | content-length: ['154']
106 | content-type: [application/json]
107 | date: ['Thu, 20 Oct 2016 08:49:35 GMT']
108 | server: [nginx]
109 | strict-transport-security: [max-age=0]
110 | x-content-type-options: [nosniff]
111 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
112 | x-xss-protection: [1; mode=block]
113 | status: {code: 422, message: Unprocessable Entity}
114 | version: 1
115 |
--------------------------------------------------------------------------------
/tests/fixtures/test_set_home_address:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"address": "555 Market Street, SF"}'
4 | headers:
5 | Content-Length: ['36']
6 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
7 | content-type: [application/json]
8 | method: PUT
9 | uri: https://sandbox-api.uber.com/v1.2/places/home
10 | response:
11 | body: {string: !!python/unicode '{"address":"555 Market St, San Francisco, CA
12 | 94105, USA"}'}
13 | headers:
14 | connection: [keep-alive]
15 | content-language: [en]
16 | content-length: ['57']
17 | content-type: [application/json]
18 | date: ['Thu, 20 Oct 2016 08:36:31 GMT']
19 | server: [nginx]
20 | strict-transport-security: [max-age=0]
21 | x-content-type-options: [nosniff]
22 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
23 | x-xss-protection: [1; mode=block]
24 | status: {code: 200, message: OK}
25 | - request:
26 | body: !!python/unicode '{"address": "555 Market Street, SF"}'
27 | headers:
28 | Content-Length: ['36']
29 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
30 | content-type: [application/json]
31 | method: PUT
32 | uri: https://sandbox-api.uber.com/v1.2/places/home
33 | response:
34 | body: {string: !!python/unicode '{"address":"555 Market St, San Francisco, CA
35 | 94105, USA"}'}
36 | headers:
37 | connection: [keep-alive]
38 | content-language: [en]
39 | content-length: ['57']
40 | content-type: [application/json]
41 | date: ['Thu, 20 Oct 2016 08:41:47 GMT']
42 | server: [nginx]
43 | strict-transport-security: [max-age=0]
44 | x-content-type-options: [nosniff]
45 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
46 | x-xss-protection: [1; mode=block]
47 | status: {code: 200, message: OK}
48 | - request:
49 | body: !!python/unicode '{"address": "555 Market Street, SF"}'
50 | headers:
51 | Content-Length: ['36']
52 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
53 | content-type: [application/json]
54 | method: PUT
55 | uri: https://sandbox-api.uber.com/v1.2/places/home
56 | response:
57 | body: {string: !!python/unicode '{"address":"555 Market St, San Francisco, CA
58 | 94105, USA"}'}
59 | headers:
60 | connection: [keep-alive]
61 | content-language: [en]
62 | content-length: ['57']
63 | content-type: [application/json]
64 | date: ['Thu, 20 Oct 2016 08:48:15 GMT']
65 | server: [nginx]
66 | strict-transport-security: [max-age=0]
67 | x-content-type-options: [nosniff]
68 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
69 | x-xss-protection: [1; mode=block]
70 | status: {code: 200, message: OK}
71 | - request:
72 | body: !!python/unicode '{"address": "555 Market Street, SF"}'
73 | headers:
74 | Content-Length: ['36']
75 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
76 | content-type: [application/json]
77 | method: PUT
78 | uri: https://sandbox-api.uber.com/v1.2/places/home
79 | response:
80 | body: {string: !!python/unicode '{"address":"555 Market St, San Francisco, CA
81 | 94105, USA"}'}
82 | headers:
83 | connection: [keep-alive]
84 | content-language: [en]
85 | content-length: ['57']
86 | content-type: [application/json]
87 | date: ['Thu, 20 Oct 2016 08:49:41 GMT']
88 | server: [nginx]
89 | strict-transport-security: [max-age=0]
90 | x-content-type-options: [nosniff]
91 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
92 | x-xss-protection: [1; mode=block]
93 | status: {code: 200, message: OK}
94 | version: 1
95 |
--------------------------------------------------------------------------------
/tests/fixtures/test_set_work_address:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"address": "1455 Market Street, SF"}'
4 | headers:
5 | Content-Length: ['37']
6 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
7 | content-type: [application/json]
8 | method: PUT
9 | uri: https://sandbox-api.uber.com/v1.2/places/work
10 | response:
11 | body: {string: !!python/unicode '{"address":"1455 Market St, San Francisco, CA
12 | 94103, USA"}'}
13 | headers:
14 | connection: [keep-alive]
15 | content-language: [en]
16 | content-length: ['58']
17 | content-type: [application/json]
18 | date: ['Thu, 20 Oct 2016 08:36:31 GMT']
19 | server: [nginx]
20 | strict-transport-security: [max-age=0]
21 | x-content-type-options: [nosniff]
22 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
23 | x-xss-protection: [1; mode=block]
24 | status: {code: 200, message: OK}
25 | - request:
26 | body: !!python/unicode '{"address": "1455 Market Street, SF"}'
27 | headers:
28 | Content-Length: ['37']
29 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
30 | content-type: [application/json]
31 | method: PUT
32 | uri: https://sandbox-api.uber.com/v1.2/places/work
33 | response:
34 | body: {string: !!python/unicode '{"address":"1455 Market St, San Francisco, CA
35 | 94103, USA"}'}
36 | headers:
37 | connection: [keep-alive]
38 | content-language: [en]
39 | content-length: ['58']
40 | content-type: [application/json]
41 | date: ['Thu, 20 Oct 2016 08:41:48 GMT']
42 | server: [nginx]
43 | strict-transport-security: [max-age=0]
44 | x-content-type-options: [nosniff]
45 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
46 | x-xss-protection: [1; mode=block]
47 | status: {code: 200, message: OK}
48 | - request:
49 | body: !!python/unicode '{"address": "1455 Market Street, SF"}'
50 | headers:
51 | Content-Length: ['37']
52 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
53 | content-type: [application/json]
54 | method: PUT
55 | uri: https://sandbox-api.uber.com/v1.2/places/work
56 | response:
57 | body: {string: !!python/unicode '{"address":"1455 Market St, San Francisco, CA
58 | 94103, USA"}'}
59 | headers:
60 | connection: [keep-alive]
61 | content-language: [en]
62 | content-length: ['58']
63 | content-type: [application/json]
64 | date: ['Thu, 20 Oct 2016 08:48:16 GMT']
65 | server: [nginx]
66 | strict-transport-security: [max-age=0]
67 | x-content-type-options: [nosniff]
68 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
69 | x-xss-protection: [1; mode=block]
70 | status: {code: 200, message: OK}
71 | - request:
72 | body: !!python/unicode '{"address": "1455 Market Street, SF"}'
73 | headers:
74 | Content-Length: ['37']
75 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
76 | content-type: [application/json]
77 | method: PUT
78 | uri: https://sandbox-api.uber.com/v1.2/places/work
79 | response:
80 | body: {string: !!python/unicode '{"address":"1455 Market St, San Francisco, CA
81 | 94103, USA"}'}
82 | headers:
83 | connection: [keep-alive]
84 | content-language: [en]
85 | content-length: ['58']
86 | content-type: [application/json]
87 | date: ['Thu, 20 Oct 2016 08:49:42 GMT']
88 | server: [nginx]
89 | strict-transport-security: [max-age=0]
90 | x-content-type-options: [nosniff]
91 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
92 | x-xss-protection: [1; mode=block]
93 | status: {code: 200, message: OK}
94 | version: 1
95 |
--------------------------------------------------------------------------------
/tests/fixtures/test_update_ride_destination:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"end_longitude": -122.4197515, "end_latitude": 37.775234}'
4 | headers:
5 | Content-Length: ['58']
6 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
7 | content-type: [application/json]
8 | method: PATCH
9 | uri: https://sandbox-api.uber.com/v1.2/requests/9bdb3278-21bd-46b8-90fa-51404b0d6acf
10 | response:
11 | body: {string: !!python/unicode '{"message":"Forbidden","code":"forbidden"}'}
12 | headers:
13 | connection: [keep-alive]
14 | content-geo-system: [wgs-84]
15 | content-length: ['42']
16 | content-type: [application/json]
17 | date: ['Thu, 20 Oct 2016 08:36:28 GMT']
18 | server: [nginx]
19 | strict-transport-security: [max-age=0]
20 | x-content-type-options: [nosniff]
21 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
22 | x-xss-protection: [1; mode=block]
23 | status: {code: 403, message: Forbidden}
24 | - request:
25 | body: !!python/unicode '{"end_longitude": -122.4197515, "end_latitude": 37.775234}'
26 | headers:
27 | Content-Length: ['58']
28 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
29 | content-type: [application/json]
30 | method: PATCH
31 | uri: https://sandbox-api.uber.com/v1.2/requests/610d868b-e21c-483a-9932-97e61b852fd2
32 | response:
33 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":404,"code":"trip_not_found","title":"Trip
34 | not found."}]}'}
35 | headers:
36 | connection: [keep-alive]
37 | content-geo-system: [wgs-84]
38 | content-length: ['87']
39 | content-type: [application/json]
40 | date: ['Thu, 20 Oct 2016 08:41:44 GMT']
41 | server: [nginx]
42 | strict-transport-security: [max-age=0]
43 | x-content-type-options: [nosniff]
44 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
45 | x-xss-protection: [1; mode=block]
46 | status: {code: 404, message: Not Found}
47 | - request:
48 | body: !!python/unicode '{"end_longitude": -122.4197515, "end_latitude": 37.775234}'
49 | headers:
50 | Content-Length: ['58']
51 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
52 | content-type: [application/json]
53 | method: PATCH
54 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
55 | response:
56 | body: {string: !!python/unicode ''}
57 | headers:
58 | connection: [keep-alive]
59 | content-language: [en]
60 | content-type: [text/html; charset=UTF-8]
61 | date: ['Thu, 20 Oct 2016 08:48:12 GMT']
62 | server: [nginx]
63 | strict-transport-security: [max-age=0]
64 | x-content-type-options: [nosniff]
65 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
66 | x-xss-protection: [1; mode=block]
67 | status: {code: 204, message: No Content}
68 | - request:
69 | body: !!python/unicode '{"end_longitude": -122.4197515, "end_latitude": 37.775234}'
70 | headers:
71 | Content-Length: ['58']
72 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
73 | content-type: [application/json]
74 | method: PATCH
75 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
76 | response:
77 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":404,"code":"trip_not_found","title":"Trip
78 | not found."}]}'}
79 | headers:
80 | connection: [keep-alive]
81 | content-geo-system: [wgs-84]
82 | content-length: ['87']
83 | content-type: [application/json]
84 | date: ['Thu, 20 Oct 2016 08:49:38 GMT']
85 | server: [nginx]
86 | strict-transport-security: [max-age=0]
87 | x-content-type-options: [nosniff]
88 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
89 | x-xss-protection: [1; mode=block]
90 | status: {code: 404, message: Not Found}
91 | version: 1
92 |
--------------------------------------------------------------------------------
/tests/fixtures/test_update_ride_destination_with_places:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"end_place_id": "work"}'
4 | headers:
5 | Content-Length: ['24']
6 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
7 | content-type: [application/json]
8 | method: PATCH
9 | uri: https://sandbox-api.uber.com/v1.2/requests/9bdb3278-21bd-46b8-90fa-51404b0d6acf
10 | response:
11 | body: {string: !!python/unicode '{"message":"Forbidden","code":"forbidden"}'}
12 | headers:
13 | connection: [keep-alive]
14 | content-geo-system: [wgs-84]
15 | content-length: ['42']
16 | content-type: [application/json]
17 | date: ['Thu, 20 Oct 2016 08:36:28 GMT']
18 | server: [nginx]
19 | strict-transport-security: [max-age=0]
20 | x-content-type-options: [nosniff]
21 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
22 | x-xss-protection: [1; mode=block]
23 | status: {code: 403, message: Forbidden}
24 | - request:
25 | body: !!python/unicode '{"end_place_id": "work"}'
26 | headers:
27 | Content-Length: ['24']
28 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
29 | content-type: [application/json]
30 | method: PATCH
31 | uri: https://sandbox-api.uber.com/v1.2/requests/610d868b-e21c-483a-9932-97e61b852fd2
32 | response:
33 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":404,"code":"trip_not_found","title":"Trip
34 | not found."}]}'}
35 | headers:
36 | connection: [keep-alive]
37 | content-geo-system: [wgs-84]
38 | content-length: ['87']
39 | content-type: [application/json]
40 | date: ['Thu, 20 Oct 2016 08:41:44 GMT']
41 | server: [nginx]
42 | strict-transport-security: [max-age=0]
43 | x-content-type-options: [nosniff]
44 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
45 | x-xss-protection: [1; mode=block]
46 | status: {code: 404, message: Not Found}
47 | - request:
48 | body: !!python/unicode '{"end_place_id": "work"}'
49 | headers:
50 | Content-Length: ['24']
51 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
52 | content-type: [application/json]
53 | method: PATCH
54 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
55 | response:
56 | body: {string: !!python/unicode ''}
57 | headers:
58 | connection: [keep-alive]
59 | content-language: [en]
60 | content-type: [text/html; charset=UTF-8]
61 | date: ['Thu, 20 Oct 2016 08:48:13 GMT']
62 | server: [nginx]
63 | strict-transport-security: [max-age=0]
64 | x-content-type-options: [nosniff]
65 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
66 | x-xss-protection: [1; mode=block]
67 | status: {code: 204, message: No Content}
68 | - request:
69 | body: !!python/unicode '{"end_place_id": "work"}'
70 | headers:
71 | Content-Length: ['24']
72 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
73 | content-type: [application/json]
74 | method: PATCH
75 | uri: https://sandbox-api.uber.com/v1.2/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
76 | response:
77 | body: {string: !!python/unicode '{"meta":{},"errors":[{"status":404,"code":"trip_not_found","title":"Trip
78 | not found."}]}'}
79 | headers:
80 | connection: [keep-alive]
81 | content-geo-system: [wgs-84]
82 | content-length: ['87']
83 | content-type: [application/json]
84 | date: ['Thu, 20 Oct 2016 08:49:38 GMT']
85 | server: [nginx]
86 | strict-transport-security: [max-age=0]
87 | x-content-type-options: [nosniff]
88 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
89 | x-xss-protection: [1; mode=block]
90 | status: {code: 404, message: Not Found}
91 | version: 1
92 |
--------------------------------------------------------------------------------
/tests/fixtures/test_update_sandbox_driver_trips:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"trips": []}'
4 | headers:
5 | Content-Length: ['13']
6 | X-Uber-User-Agent: [!!python/unicode 'Python Rides SDK v0.6.0']
7 | content-type: [application/json]
8 | method: PUT
9 | uri: https://sandbox-api.uber.com/v1/sandbox/partners/trips
10 | response:
11 | body: {string: !!python/unicode ''}
12 | headers:
13 | cache-control: [max-age=0]
14 | connection: [keep-alive]
15 | content-language: [en]
16 | content-type: [text/html; charset=UTF-8]
17 | date: ['Fri, 15 Sep 2017 00:09:51 GMT']
18 | server: [nginx]
19 | strict-transport-security: [max-age=604800, max-age=2592000]
20 | x-content-type-options: [nosniff]
21 | x-frame-options: [SAMEORIGIN]
22 | x-rate-limit-limit: ['2000']
23 | x-rate-limit-remaining: ['1992']
24 | x-rate-limit-reset: ['1505437200']
25 | x-uber-app: [uberex-sandbox, optimus]
26 | x-xss-protection: [1; mode=block]
27 | status: {code: 204, message: No Content}
28 | version: 1
29 |
--------------------------------------------------------------------------------
/tests/fixtures/test_update_sandbox_product:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"surge_multiplier": 2, "drivers_available": null}'
4 | headers:
5 | Content-Length: ['50']
6 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
7 | content-type: [application/json]
8 | method: PUT
9 | uri: https://sandbox-api.uber.com/v1.2/sandbox/products/d5ef01d9-7d54-413e-b265-425948d06e92
10 | response:
11 | body: {string: !!python/unicode ''}
12 | headers:
13 | connection: [keep-alive]
14 | content-language: [en]
15 | content-type: [text/html; charset=UTF-8]
16 | date: ['Thu, 20 Oct 2016 08:36:30 GMT']
17 | server: [nginx]
18 | strict-transport-security: [max-age=0]
19 | x-content-type-options: [nosniff]
20 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
21 | x-xss-protection: [1; mode=block]
22 | status: {code: 204, message: No Content}
23 | - request:
24 | body: !!python/unicode '{"surge_multiplier": 2, "drivers_available": null}'
25 | headers:
26 | Content-Length: ['50']
27 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
28 | content-type: [application/json]
29 | method: PUT
30 | uri: https://sandbox-api.uber.com/v1.2/sandbox/products/d5ef01d9-7d54-413e-b265-425948d06e92
31 | response:
32 | body: {string: !!python/unicode ''}
33 | headers:
34 | connection: [keep-alive]
35 | content-language: [en]
36 | content-type: [text/html; charset=UTF-8]
37 | date: ['Thu, 20 Oct 2016 08:41:46 GMT']
38 | server: [nginx]
39 | strict-transport-security: [max-age=0]
40 | x-content-type-options: [nosniff]
41 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
42 | x-xss-protection: [1; mode=block]
43 | status: {code: 204, message: No Content}
44 | - request:
45 | body: !!python/unicode '{"surge_multiplier": 2, "drivers_available": null}'
46 | headers:
47 | Content-Length: ['50']
48 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
49 | content-type: [application/json]
50 | method: PUT
51 | uri: https://sandbox-api.uber.com/v1.2/sandbox/products/d5ef01d9-7d54-413e-b265-425948d06e92
52 | response:
53 | body: {string: !!python/unicode ''}
54 | headers:
55 | connection: [keep-alive]
56 | content-language: [en]
57 | content-type: [text/html; charset=UTF-8]
58 | date: ['Thu, 20 Oct 2016 08:48:14 GMT']
59 | server: [nginx]
60 | strict-transport-security: [max-age=0]
61 | x-content-type-options: [nosniff]
62 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
63 | x-xss-protection: [1; mode=block]
64 | status: {code: 204, message: No Content}
65 | - request:
66 | body: !!python/unicode '{"surge_multiplier": 2, "drivers_available": null}'
67 | headers:
68 | Content-Length: ['50']
69 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
70 | content-type: [application/json]
71 | method: PUT
72 | uri: https://sandbox-api.uber.com/v1.2/sandbox/products/d5ef01d9-7d54-413e-b265-425948d06e92
73 | response:
74 | body: {string: !!python/unicode ''}
75 | headers:
76 | connection: [keep-alive]
77 | content-language: [en]
78 | content-type: [text/html; charset=UTF-8]
79 | date: ['Thu, 20 Oct 2016 08:49:40 GMT']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 204, message: No Content}
86 | version: 1
87 |
--------------------------------------------------------------------------------
/tests/fixtures/test_update_sandbox_ride:
--------------------------------------------------------------------------------
1 | interactions:
2 | - request:
3 | body: !!python/unicode '{"status": "accepted"}'
4 | headers:
5 | Content-Length: ['22']
6 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
7 | content-type: [application/json]
8 | method: PUT
9 | uri: https://sandbox-api.uber.com/v1.2/sandbox/requests/9bdb3278-21bd-46b8-90fa-51404b0d6acf
10 | response:
11 | body: {string: !!python/unicode '{"message":"No trip with id=9bdb3278-21bd-46b8-90fa-51404b0d6acf","code":"not_found"}'}
12 | headers:
13 | connection: [keep-alive]
14 | content-length: ['85']
15 | content-type: [application/json]
16 | date: ['Thu, 20 Oct 2016 08:36:29 GMT']
17 | server: [nginx]
18 | strict-transport-security: [max-age=0]
19 | x-content-type-options: [nosniff]
20 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
21 | x-xss-protection: [1; mode=block]
22 | status: {code: 404, message: Not Found}
23 | - request:
24 | body: !!python/unicode '{"status": "accepted"}'
25 | headers:
26 | Content-Length: ['22']
27 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
28 | content-type: [application/json]
29 | method: PUT
30 | uri: https://sandbox-api.uber.com/v1.2/sandbox/requests/610d868b-e21c-483a-9932-97e61b852fd2
31 | response:
32 | body: {string: !!python/unicode '{"message":"No trip with id=610d868b-e21c-483a-9932-97e61b852fd2","code":"not_found"}'}
33 | headers:
34 | connection: [keep-alive]
35 | content-length: ['85']
36 | content-type: [application/json]
37 | date: ['Thu, 20 Oct 2016 08:41:45 GMT']
38 | server: [nginx]
39 | strict-transport-security: [max-age=0]
40 | x-content-type-options: [nosniff]
41 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
42 | x-xss-protection: [1; mode=block]
43 | status: {code: 404, message: Not Found}
44 | - request:
45 | body: !!python/unicode '{"status": "accepted"}'
46 | headers:
47 | Content-Length: ['22']
48 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
49 | content-type: [application/json]
50 | method: PUT
51 | uri: https://sandbox-api.uber.com/v1.2/sandbox/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
52 | response:
53 | body: {string: !!python/unicode ''}
54 | headers:
55 | connection: [keep-alive]
56 | content-language: [en]
57 | content-type: [text/html; charset=UTF-8]
58 | date: ['Thu, 20 Oct 2016 08:48:13 GMT']
59 | server: [nginx]
60 | strict-transport-security: [max-age=0]
61 | x-content-type-options: [nosniff]
62 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
63 | x-xss-protection: [1; mode=block]
64 | status: {code: 204, message: No Content}
65 | - request:
66 | body: !!python/unicode '{"status": "accepted"}'
67 | headers:
68 | Content-Length: ['22']
69 | X-Uber-User-Agent: [!!python/unicode Python Rides SDK v0.6.0]
70 | content-type: [application/json]
71 | method: PUT
72 | uri: https://sandbox-api.uber.com/v1.2/sandbox/requests/0aec0061-1e20-4239-a0b7-78328e9afec8
73 | response:
74 | body: {string: !!python/unicode '{"message":"No trip with id=0aec0061-1e20-4239-a0b7-78328e9afec8","code":"not_found"}'}
75 | headers:
76 | connection: [keep-alive]
77 | content-length: ['85']
78 | content-type: [application/json]
79 | date: ['Thu, 20 Oct 2016 08:49:39 GMT']
80 | server: [nginx]
81 | strict-transport-security: [max-age=0]
82 | x-content-type-options: [nosniff]
83 | x-uber-app: [uberex-sandbox, migrator-uberex-sandbox-optimus]
84 | x-xss-protection: [1; mode=block]
85 | status: {code: 404, message: Not Found}
86 | version: 1
87 |
--------------------------------------------------------------------------------
/tests/test_request_utils.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | from __future__ import absolute_import
22 | from __future__ import division
23 | from __future__ import print_function
24 | from __future__ import unicode_literals
25 |
26 | from collections import OrderedDict
27 |
28 | from pytest import fixture
29 |
30 | from uber_rides.utils.request import build_url
31 | from uber_rides.utils.request import generate_data
32 |
33 |
34 | LAT = 37.775232
35 | LNG = -122.4197513
36 | HOST = 'api.uber.com'
37 | DEFAULT_TARGET = 'v1.2/products'
38 | SPECIAL_CHAR_TARGET = 'v1.2/~products'
39 | DEFAULT_BASE_URL = 'https://api.uber.com/v1.2/products'
40 |
41 |
42 | @fixture
43 | def default_http_arguments_as_json():
44 | return OrderedDict([
45 | ('latitude', LAT),
46 | ('longitude', LNG),
47 | ])
48 |
49 |
50 | @fixture
51 | def default_http_arguments_as_string():
52 | return '{{"latitude": {}, "longitude": {}}}'.format(LAT, LNG)
53 |
54 |
55 | def test_generate_data_with_POST(
56 | default_http_arguments_as_json,
57 | default_http_arguments_as_string,
58 | ):
59 | """Assign arguments to body of request in POST."""
60 | data, params = generate_data('POST', default_http_arguments_as_json)
61 | assert not params
62 | assert data == default_http_arguments_as_string
63 |
64 |
65 | def test_generate_data_with_PATCH(
66 | default_http_arguments_as_json,
67 | default_http_arguments_as_string,
68 | ):
69 | """Assign arguments to body of request in PATCH."""
70 | data, params = generate_data('PATCH', default_http_arguments_as_json)
71 | assert not params
72 | assert data == default_http_arguments_as_string
73 |
74 |
75 | def test_generate_data_with_PUT(
76 | default_http_arguments_as_json,
77 | default_http_arguments_as_string,
78 | ):
79 | """Assign arguments to body of request in PUT."""
80 | data, params = generate_data('PUT', default_http_arguments_as_json)
81 | assert not params
82 | assert data == default_http_arguments_as_string
83 |
84 |
85 | def test_generate_data_with_GET(default_http_arguments_as_json):
86 | """Assign arguments to querystring params in GET."""
87 | data, params = generate_data('GET', default_http_arguments_as_json)
88 | assert params == default_http_arguments_as_json
89 | assert not data
90 |
91 |
92 | def test_generate_data_with_DELETE(default_http_arguments_as_json,):
93 | """Assign arguments to querystring params in DELETE."""
94 | data, params = generate_data('DELETE', default_http_arguments_as_json)
95 | assert params == default_http_arguments_as_json
96 | assert not data
97 |
98 |
99 | def test_build_url_no_params():
100 | """Build URL with no parameters."""
101 | url = build_url(HOST, DEFAULT_TARGET)
102 | assert url == DEFAULT_BASE_URL
103 |
104 |
105 | def test_build_url_with_scheme():
106 | """Build URL with https scheme."""
107 | url = build_url(HOST, DEFAULT_TARGET)
108 | assert url == DEFAULT_BASE_URL
109 |
110 |
111 | def test_build_special_char_url():
112 | """Build URL special characters."""
113 | url = build_url(HOST, SPECIAL_CHAR_TARGET)
114 | assert url == 'https://api.uber.com/v1.2/%7Eproducts'
115 |
116 |
117 | def test_build_url_params(default_http_arguments_as_json):
118 | """Build URL with querystring parameters."""
119 | url = build_url(HOST, DEFAULT_TARGET, default_http_arguments_as_json)
120 | url_with_params = '{}?latitude={}&longitude={}'
121 | assert url == url_with_params.format(DEFAULT_BASE_URL, LAT, LNG)
122 |
--------------------------------------------------------------------------------
/tests/vcr_config.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | """Configure vcr to record test fixtures.
22 |
23 | This file overrides vcrpy's default settings.
24 | You can set options individually. Such per-cassette
25 | overrides will take precedent over the global
26 | configuration below.
27 | """
28 |
29 | from __future__ import absolute_import
30 | from __future__ import division
31 | from __future__ import print_function
32 | from __future__ import unicode_literals
33 |
34 | import vcr
35 |
36 | uber_vcr = vcr.VCR(
37 | serializer='yaml',
38 | cassette_library_dir='tests/fixtures',
39 |
40 | # disable gzip
41 | decode_compressed_response=True,
42 |
43 | # you can record_mode='all' to force re-record all cassettes
44 | record_mode='once',
45 |
46 | # configure matching features that vcr uses to identify identical requests
47 | match_on=['uri', 'method'],
48 |
49 | # scrub sensitive information from cassette files
50 | filter_headers=['Authorization'],
51 | )
52 |
--------------------------------------------------------------------------------
/uber_rides/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uber/rides-python-sdk/76ecd75ab5235d792ec1010e36eca679ba285127/uber_rides/__init__.py
--------------------------------------------------------------------------------
/uber_rides/errors.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | from __future__ import absolute_import
22 | from __future__ import division
23 | from __future__ import print_function
24 | from __future__ import unicode_literals
25 |
26 |
27 | class APIError(Exception):
28 | """Parent class of all Uber API errors."""
29 | pass
30 |
31 |
32 | class HTTPError(APIError):
33 | """Parent class of all HTTP errors."""
34 |
35 | def _adapt_response(self, response):
36 | """Convert error responses to standardized ErrorDetails."""
37 | if response.headers['content-type'] == 'application/json':
38 | body = response.json()
39 | status = response.status_code
40 |
41 | if body.get('errors'):
42 | return self._complex_response_to_error_adapter(body)
43 |
44 | elif body.get('code') and body.get('message'):
45 | return self._simple_response_to_error_adapter(status, body)
46 |
47 | elif body.get('error'):
48 | code = response.reason
49 | return self._message_to_error_adapter(status, code, body)
50 |
51 | raise UnknownHttpError(response)
52 |
53 | def _complex_response_to_error_adapter(self, body):
54 | """Convert a list of error responses."""
55 | meta = body.get('meta')
56 | errors = body.get('errors')
57 | e = []
58 |
59 | for error in errors:
60 | status = error['status']
61 | code = error['code']
62 | title = error['title']
63 |
64 | e.append(ErrorDetails(status, code, title))
65 |
66 | return e, meta
67 |
68 | def _simple_response_to_error_adapter(self, status, original_body):
69 | """Convert a single error response."""
70 | body = original_body.copy()
71 | code = body.pop('code')
72 | title = body.pop('message')
73 | meta = body # save whatever is left in the response
74 |
75 | e = [ErrorDetails(status, code, title)]
76 |
77 | return e, meta
78 |
79 | def _message_to_error_adapter(self, status, code, original_body):
80 | """Convert single string message to error response."""
81 | body = original_body.copy()
82 | title = body.pop('error')
83 | meta = body # save whatever is left in the response
84 |
85 | e = [ErrorDetails(status, code, title)]
86 |
87 | return e, meta
88 |
89 |
90 | class ClientError(HTTPError):
91 | """Raise for 4XX Errors.
92 |
93 | Contains an array of ErrorDetails objects.
94 | """
95 |
96 | def __init__(self, response, message=None):
97 | """
98 | Parameters
99 | response
100 | The 4XX HTTP response.
101 | message
102 | An error message string. If one is not provided, the
103 | default message is used.
104 | """
105 | if not message:
106 | message = (
107 | 'The request contains bad syntax or cannot be filled '
108 | 'due to a fault from the client sending the request.'
109 | )
110 |
111 | super(ClientError, self).__init__(message)
112 | errors, meta = super(ClientError, self)._adapt_response(response)
113 | self.errors = errors
114 | self.meta = meta
115 |
116 |
117 | class ServerError(HTTPError):
118 | """Raise for 5XX Errors.
119 |
120 | Contains a single ErrorDetails object.
121 | """
122 |
123 | def __init__(self, response, message=None):
124 | """
125 | Parameters
126 | response
127 | The 5XX HTTP response.
128 | message
129 | An error message string. If one is not provided, the
130 | default message is used.
131 | """
132 | if not message:
133 | message = (
134 | 'The server encounter an error or is '
135 | 'unable to process the request.'
136 | )
137 |
138 | super(ServerError, self).__init__(message)
139 | self.error, self.meta = self._adapt_response(response)
140 |
141 | def _adapt_response(self, response):
142 | """Convert various error responses to standardized ErrorDetails."""
143 | errors, meta = super(ServerError, self)._adapt_response(response)
144 | return errors[0], meta # single error instead of array
145 |
146 |
147 | class ErrorDetails(object):
148 | """Class to standardize all errors."""
149 |
150 | def __init__(self, status, code, title):
151 | self.status = status
152 | self.code = code
153 | self.title = title
154 |
155 | def __repr__(self):
156 | return "ErrorDetails: {} {} {}".format(
157 | str(self.status),
158 | str(self.code),
159 | str(self.title)
160 | )
161 |
162 |
163 | class UnknownHttpError(APIError):
164 | """Throw when an unknown HTTP error occurs.
165 |
166 | Thrown when a previously unseen error is
167 | received and there is no standard schema to convert
168 | it into a well-formed HttpError.
169 | """
170 |
171 | def __init__(self, response):
172 | super(UnknownHttpError, self).__init__()
173 | self.response = response
174 |
175 |
176 | class UberIllegalState(APIError):
177 | """Raise for Illegal State Errors.
178 |
179 | Thrown when the environment or class is not in an
180 | appropriate state for the requested operation.
181 | """
182 | pass
183 |
--------------------------------------------------------------------------------
/uber_rides/request.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | """Internal module for HTTP Requests and Responses."""
22 |
23 | from __future__ import absolute_import
24 | from __future__ import division
25 | from __future__ import print_function
26 | from __future__ import unicode_literals
27 |
28 | from requests import Session
29 | from string import ascii_letters
30 | from string import digits
31 |
32 | from uber_rides.errors import UberIllegalState
33 | from uber_rides.utils import http
34 | from uber_rides.utils.request import build_url
35 | from uber_rides.utils.request import generate_data
36 | from uber_rides.utils.request import generate_prepared_request
37 |
38 |
39 | LIB_VERSION = '0.6.0'
40 |
41 |
42 | class Response(object):
43 | """The response from an HTTP request."""
44 |
45 | def __init__(self, response):
46 | """Initialize a Response.
47 |
48 | Parameters
49 | response (requests.Response)
50 | The HTTP response from an API request.
51 | """
52 | self.status_code = response.status_code
53 | self.request = response.request
54 | self.headers = response.headers
55 |
56 | try:
57 | self.json = response.json()
58 | except:
59 | self.json = None
60 |
61 |
62 | class Request(object):
63 | """Request containing information to send to server."""
64 |
65 | def __init__(
66 | self,
67 | auth_session,
68 | api_host,
69 | method,
70 | path,
71 | handlers=None,
72 | args=None,
73 | ):
74 | """Initialize a Request.
75 |
76 | Parameters
77 | auth_session (Session)
78 | Session object containing OAuth 2.0 credentials. Optional
79 | for any HTTP Requests that don't need access headers.
80 | api_host (str)
81 | Base URL of the Uber Server that handles API calls.
82 | method (str)
83 | HTTP Method (e.g. 'POST').
84 | path (str)
85 | The endpoint path. (e.g. 'v1.2/products')
86 | handlers (list[handler])
87 | Optional list of error handlers to attach to the request.
88 | args (dict)
89 | Optional dictionary of arguments to add to the request.
90 | """
91 | self.auth_session = auth_session
92 | self.api_host = api_host
93 | self.path = path
94 | self.method = method
95 | self.handlers = handlers or []
96 | self.args = args
97 |
98 | def _prepare(self):
99 | """Builds a URL and return a PreparedRequest.
100 |
101 | Returns
102 | (requests.PreparedRequest)
103 |
104 | Raises
105 | UberIllegalState (APIError)
106 | """
107 | if self.method not in http.ALLOWED_METHODS:
108 | raise UberIllegalState('Unsupported HTTP Method.')
109 |
110 | api_host = self.api_host
111 | headers = self._build_headers(self.method, self.auth_session)
112 | url = build_url(api_host, self.path)
113 | data, params = generate_data(self.method, self.args)
114 |
115 | return generate_prepared_request(
116 | self.method,
117 | url,
118 | headers,
119 | data,
120 | params,
121 | self.handlers,
122 | )
123 |
124 | def _send(self, prepared_request):
125 | """Send a PreparedRequest to the server.
126 |
127 | Parameters
128 | prepared_request (requests.PreparedRequest)
129 |
130 | Returns
131 | (Response)
132 | A Response object, whichcontains a server's
133 | response to an HTTP request.
134 | """
135 | session = Session()
136 | response = session.send(prepared_request)
137 | return Response(response)
138 |
139 | def execute(self):
140 | """Prepare and send the Request, return a Response.
141 |
142 | Returns
143 | (Response)
144 | The HTTP Response from an API Request
145 | to the server.
146 |
147 | Example
148 | request = Request(session, 'api.uber.com', 'GET', 'v1.2/profile')
149 | response = request.execute()
150 | """
151 | prepared_request = self._prepare()
152 | return self._send(prepared_request)
153 |
154 | def _build_headers(self, method, auth_session):
155 | """Create headers for the request.
156 |
157 | Parameters
158 | method (str)
159 | HTTP method (e.g. 'POST').
160 | auth_session (Session)
161 | The Session object containing OAuth 2.0 credentials.
162 |
163 | Returns
164 | headers (dict)
165 | Dictionary of access headers to attach to request.
166 |
167 | Raises
168 | UberIllegalState (ApiError)
169 | Raised if headers are invalid.
170 | """
171 | token_type = auth_session.token_type
172 |
173 | if auth_session.server_token:
174 | token = auth_session.server_token
175 | else:
176 | token = auth_session.oauth2credential.access_token
177 |
178 | if not self._authorization_headers_valid(token_type, token):
179 | message = 'Invalid token_type or token.'
180 | raise UberIllegalState(message)
181 |
182 | headers = {
183 | 'Authorization': ' '.join([token_type, token]),
184 | 'X-Uber-User-Agent': 'Python Rides SDK v{}'.format(LIB_VERSION),
185 | }
186 |
187 | if method in http.BODY_METHODS:
188 | headers.update(http.DEFAULT_CONTENT_HEADERS)
189 |
190 | return headers
191 |
192 | def _authorization_headers_valid(self, token_type, token):
193 | """Verify authorization headers for a request.
194 |
195 | Parameters
196 | token_type (str)
197 | Type of token to access resources.
198 | token (str)
199 | Server Token or OAuth 2.0 Access Token.
200 |
201 | Returns
202 | (bool)
203 | True iff token_type and token are valid.
204 | """
205 | if token_type not in http.VALID_TOKEN_TYPES:
206 | return False
207 |
208 | allowed_chars = ascii_letters + digits + '.' + '_' + '-' + '='
209 |
210 | # True if token only contains allowed_chars
211 | return all(characters in allowed_chars for characters in token)
212 |
--------------------------------------------------------------------------------
/uber_rides/session.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | from __future__ import absolute_import
22 | from __future__ import division
23 | from __future__ import print_function
24 | from __future__ import unicode_literals
25 |
26 | from requests import codes
27 | from time import time
28 |
29 | from uber_rides.errors import ClientError
30 | from uber_rides.errors import UberIllegalState
31 | from uber_rides.utils import auth
32 |
33 |
34 | EXPIRES_THRESHOLD_SECONDS = 500
35 |
36 |
37 | class Session(object):
38 | """A class to store credentials.
39 |
40 | A Session can be initialized with a Server Token or with a set of
41 | OAuth 2.0 Credentials, but not with both. A Session uses credentials
42 | to properly construct requests to Uber and access protected resources.
43 | """
44 |
45 | def __init__(
46 | self,
47 | server_token=None,
48 | oauth2credential=None,
49 | ):
50 | """Initialize a Session.
51 |
52 | Parameters
53 | sever_token (str)
54 | Your application's server token. Available at
55 | developer.uber.com.
56 | oauth2credential (OAuth2Credential)
57 | Access token and additional OAuth 2.0 credentials used
58 | to access protected resources.
59 |
60 | Raises
61 | UberIllegalState (APIError)
62 | Raised if there is an attempt to create session with
63 | both server token and access token.
64 | """
65 | if server_token and oauth2credential:
66 | message = (
67 | 'Session cannot have both Server '
68 | 'and OAuth 2.0 Credentials.'
69 | )
70 | raise UberIllegalState(message)
71 |
72 | if server_token is None and oauth2credential is None:
73 | message = (
74 | 'Session must have either Server '
75 | 'Token or OAuth 2.0 Credentials.'
76 | )
77 | raise UberIllegalState(message)
78 |
79 | if server_token:
80 | self.server_token = server_token
81 | self.token_type = auth.SERVER_TOKEN_TYPE
82 | self.oauth2credential = None
83 |
84 | elif oauth2credential:
85 | self.oauth2credential = oauth2credential
86 | self.token_type = auth.OAUTH_TOKEN_TYPE
87 | self.server_token = None
88 |
89 |
90 | class OAuth2Credential(object):
91 | """A class to store OAuth 2.0 credentials.
92 |
93 | OAuth 2.0 credentials are used to properly construct requests
94 | to Uber and access protected resources. The class also stores
95 | app information (such as client_id) to refresh or request new
96 | access tokens if they expire or are revoked.
97 | """
98 |
99 | def __init__(
100 | self,
101 | client_id,
102 | access_token,
103 | expires_in_seconds,
104 | scopes,
105 | grant_type,
106 | redirect_url=None,
107 | client_secret=None,
108 | refresh_token=None,
109 | ):
110 | """Initialize an OAuth2Credential.
111 |
112 | Parameters
113 | client_id (str)
114 | Your app's Client ID.
115 | access_token (str)
116 | Access token received from OAuth 2.0 Authorization.
117 | expires_in_seconds (int)
118 | Seconds after initial grant when access token will expire.
119 | scopes (set)
120 | Set of permission scopes to request.
121 | (e.g. {'profile', 'history'}) Keep this list minimal so
122 | users feel safe granting your app access to their information.
123 | grant_type (str)
124 | Type of OAuth 2.0 Grant used to obtain access token.
125 | (e.g. 'authorization_code')
126 | redirect_url (str)
127 | The URL that the Uber server will redirect to.
128 | client_secret (str)
129 | Your app's Client Secret.
130 | refresh_token (str)
131 | Optional refresh token used to get a new access token.
132 | Only used for Authorization Code Grant.
133 | """
134 | self.client_id = client_id
135 | self.access_token = access_token
136 | self.expires_in_seconds = self._now() + int(expires_in_seconds)
137 | self.scopes = scopes
138 | self.grant_type = grant_type
139 | self.redirect_url = redirect_url
140 | self.client_secret = client_secret
141 | self.refresh_token = refresh_token
142 |
143 | @classmethod
144 | def make_from_response(
145 | cls,
146 | response,
147 | grant_type,
148 | client_id,
149 | client_secret=None,
150 | redirect_url=None,
151 | ):
152 | """Alternate constructor for OAuth2Credential().
153 |
154 | Create an OAuth2Credential from an HTTP Response.
155 |
156 | Parameters
157 | response (Response)
158 | HTTP Response containing OAuth 2.0 credentials.
159 | grant_type (str)
160 | Type of OAuth 2.0 Grant used to obtain access token.
161 | (e.g. 'authorization_code')
162 | client_id (str)
163 | Your app's Client ID.
164 | client_secret (str)
165 | Your app's Client Secret.
166 | redirect_url (str)
167 | The URL that the Uber server will redirect to.
168 |
169 | Returns
170 | (OAuth2Credential)
171 |
172 | Raises
173 | ClientError (APIError)
174 | Raised if the response is invalid.
175 | """
176 | if response.status_code != codes.ok:
177 | message = 'Error with Access Token Request: {}'
178 | message = message.format(response.reason)
179 | raise ClientError(response, message)
180 |
181 | response = response.json()
182 |
183 | # convert space delimited string to set
184 | scopes = response.get('scope')
185 | scopes_set = {scope for scope in scopes.split()}
186 |
187 | return cls(
188 | client_id=client_id,
189 | client_secret=client_secret,
190 | redirect_url=redirect_url,
191 | access_token=response.get('access_token'),
192 | expires_in_seconds=response.get('expires_in'),
193 | scopes=scopes_set,
194 | grant_type=grant_type,
195 | refresh_token=response.get('refresh_token', None),
196 | )
197 |
198 | def is_stale(self):
199 | """Check whether the session's current access token is about to expire.
200 |
201 | Returns
202 | (bool)
203 | True if access_token expires within threshold
204 | """
205 | expires_in_seconds = self.expires_in_seconds - self._now()
206 | return expires_in_seconds < EXPIRES_THRESHOLD_SECONDS
207 |
208 | def _now(self):
209 | return int(time())
210 |
--------------------------------------------------------------------------------
/uber_rides/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uber/rides-python-sdk/76ecd75ab5235d792ec1010e36eca679ba285127/uber_rides/utils/__init__.py
--------------------------------------------------------------------------------
/uber_rides/utils/auth.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | SERVER_TOKEN_TYPE = 'Token'
22 | OAUTH_TOKEN_TYPE = 'Bearer'
23 | AUTHORIZATION_CODE_GRANT = 'authorization_code'
24 | CLIENT_CREDENTIALS_GRANT = 'client_credentials'
25 | IMPLICIT_GRANT = 'implicit'
26 | REFRESH_TOKEN = 'refresh_token'
27 | AUTH_HOST = 'login.uber.com'
28 | ACCESS_TOKEN_PATH = 'oauth/v2/token'
29 | AUTHORIZE_PATH = 'oauth/v2/authorize'
30 | REVOKE_PATH = 'oauth/v2/revoke'
31 | CODE_RESPONSE_TYPE = 'code'
32 | TOKEN_RESPONSE_TYPE = 'token'
33 | VALID_RESPONSE_TYPES = frozenset([
34 | CODE_RESPONSE_TYPE,
35 | TOKEN_RESPONSE_TYPE,
36 | ])
37 |
--------------------------------------------------------------------------------
/uber_rides/utils/handlers.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | from __future__ import absolute_import
22 | from __future__ import division
23 | from __future__ import print_function
24 | from __future__ import unicode_literals
25 |
26 | from uber_rides.errors import ClientError
27 | from uber_rides.errors import ServerError
28 |
29 |
30 | def error_handler(response, **kwargs):
31 | """Error Handler to surface 4XX and 5XX errors.
32 |
33 | Attached as a callback hook on the Request object.
34 |
35 | Parameters
36 | response (requests.Response)
37 | The HTTP response from an API request.
38 | **kwargs
39 | Arbitrary keyword arguments.
40 |
41 | Raises
42 | ClientError (ApiError)
43 | Raised if response contains a 4XX status code.
44 | ServerError (ApiError)
45 | Raised if response contains a 5XX status code.
46 |
47 | Returns
48 | response (requests.Response)
49 | The original HTTP response from the API request.
50 | """
51 | try:
52 | body = response.json()
53 | except ValueError:
54 | body = {}
55 | status_code = response.status_code
56 | message = body.get('message', '')
57 | fields = body.get('fields', '')
58 | error_message = str(status_code) + ': ' + message + ' ' + str(fields)
59 | if 400 <= status_code <= 499:
60 | raise ClientError(response, error_message)
61 |
62 | elif 500 <= status_code <= 599:
63 | raise ServerError(response, error_message)
64 |
65 | return response
66 |
--------------------------------------------------------------------------------
/uber_rides/utils/http.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | URL_SCHEME = 'https://'
22 |
23 | ALLOWED_METHODS = frozenset(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])
24 | BODY_METHODS = frozenset(['POST', 'PUT', 'PATCH'])
25 | QUERY_METHODS = frozenset(['GET', 'DELETE'])
26 |
27 | DEFAULT_CONTENT_HEADERS = {'content-type': 'application/json'}
28 |
29 | STATUS_OK = 200
30 | STATUS_UNAUTHORIZED = 401
31 | STATUS_CONFLICT = 409
32 | STATUS_UNPROCESSABLE_ENTITY = 422
33 | STATUS_INTERNAL_SERVER_ERROR = 500
34 | STATUS_SERVICE_UNAVAILABLE = 503
35 |
36 | ERROR_CODE_DESCRIPTION_DICT = {
37 | 'distance_exceeded': 'Distance between two points exceeds 100 miles.',
38 | 'unauthorized': 'Invalid OAuth 2.0 credentials provided.',
39 | 'validation_failed': 'Invalid request.',
40 | 'internal_server_error': 'Unexpected internal server error occurred.',
41 | 'service_unavailable': 'Service temporarily unavailable.',
42 | 'surge': 'Surge pricing is in effect.',
43 | 'same_pickup_dropoff': 'Pickup and Dropoff can\'t be the same.',
44 | }
45 |
46 | VALID_TOKEN_TYPES = frozenset(['Token', 'Bearer'])
47 |
--------------------------------------------------------------------------------
/uber_rides/utils/request.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2017 Uber Technologies, Inc.
2 | #
3 | # Permission is hereby granted, free of charge, to any person obtaining a copy
4 | # of this software and associated documentation files (the "Software"), to deal
5 | # in the Software without restriction, including without limitation the rights
6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | # copies of the Software, and to permit persons to whom the Software is
8 | # furnished to do so, subject to the following conditions:
9 | #
10 | # The above copyright notice and this permission notice shall be included in
11 | # all copies or substantial portions of the Software.
12 | #
13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | # THE SOFTWARE.
20 |
21 | from __future__ import absolute_import
22 | from __future__ import division
23 | from __future__ import print_function
24 | from __future__ import unicode_literals
25 |
26 | from json import dumps
27 | from requests import Request
28 |
29 | try:
30 | from urllib.parse import quote
31 | from urllib.parse import urlencode
32 | from urllib.parse import urljoin
33 | except ImportError:
34 | from urllib import quote
35 | from urllib import urlencode
36 | from urlparse import urljoin
37 |
38 | from uber_rides.utils.handlers import error_handler
39 | from uber_rides.utils import http
40 |
41 |
42 | def generate_data(method, args):
43 | """Assign arguments to body or URL of an HTTP request.
44 |
45 | Parameters
46 | method (str)
47 | HTTP Method. (e.g. 'POST')
48 | args (dict)
49 | Dictionary of data to attach to each Request.
50 | e.g. {'latitude': 37.561, 'longitude': -122.742}
51 |
52 | Returns
53 | (str or dict)
54 | Either params containing the dictionary of arguments
55 | or data containing arugments in JSON-formatted string.
56 | """
57 | data = {}
58 | params = {}
59 |
60 | if method in http.BODY_METHODS:
61 | data = dumps(args)
62 | else:
63 | params = args
64 | return data, params
65 |
66 |
67 | def generate_prepared_request(method, url, headers, data, params, handlers):
68 | """Add handlers and prepare a Request.
69 |
70 | Parameters
71 | method (str)
72 | HTTP Method. (e.g. 'POST')
73 | headers (dict)
74 | Headers to send.
75 | data (JSON-formatted str)
76 | Body to attach to the request.
77 | params (dict)
78 | Dictionary of URL parameters to append to the URL.
79 | handlers (list)
80 | List of callback hooks, for error handling.
81 |
82 | Returns
83 | (requests.PreparedRequest)
84 | The fully mutable PreparedRequest object,
85 | containing the exact bytes to send to the server.
86 | """
87 | request = Request(
88 | method=method,
89 | url=url,
90 | headers=headers,
91 | data=data,
92 | params=params,
93 | )
94 |
95 | handlers.append(error_handler)
96 |
97 | for handler in handlers:
98 | request.register_hook('response', handler)
99 |
100 | return request.prepare()
101 |
102 |
103 | def build_url(host, path, params=None):
104 | """Build a URL.
105 |
106 | This method encodes the parameters and adds them
107 | to the end of the base URL, then adds scheme and hostname.
108 |
109 | Parameters
110 | host (str)
111 | Base URL of the Uber Server that handles API calls.
112 | path (str)
113 | Target path to add to the host (e.g. 'v1.2/products').
114 | params (dict)
115 | Optional dictionary of parameters to add to the URL.
116 |
117 | Returns
118 | (str)
119 | The fully formed URL.
120 | """
121 | path = quote(path)
122 | params = params or {}
123 |
124 | if params:
125 | path = '/{}?{}'.format(path, urlencode(params))
126 | else:
127 | path = '/{}'.format(path)
128 |
129 | if not host.startswith(http.URL_SCHEME):
130 | host = '{}{}'.format(http.URL_SCHEME, host)
131 |
132 | return urljoin(host, path)
133 |
--------------------------------------------------------------------------------