Skip to content

Commit a3965f3

Browse files
committed
Merge pull request #98 from box/notebooks
Notebooks
2 parents feede5d + a262885 commit a3965f3

File tree

3 files changed

+461
-0
lines changed

3 files changed

+461
-0
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"The Python SDK tries to make it easy to make requests to the Box API.\n",
8+
"\n",
9+
"Part of the ease is the fact that the SDK handles the OAuth2 dance, including token refresh, even for multithreaded applications.\n",
10+
"\n",
11+
"New to the SDK are some OAuth2 subclasses and mixins that enable the SDK to handle auth in a variety of advanced use cases:\n",
12+
"* Cooperative multiprocessing - share token pairs across python processes\n",
13+
"* Remote auth - make API requests on a local client, but handle auth on a remote server to avoid exposing a client secret on clients\n",
14+
"* Distributed cooperative multiprocessing - store token pairs in Redis; share among multiple processes or machines"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": 3,
20+
"metadata": {
21+
"collapsed": false
22+
},
23+
"outputs": [],
24+
"source": [
25+
"from boxsdk import Client\n",
26+
"from boxsdk.auth.redis_managed_oauth2 import RedisManagedOAuth2"
27+
]
28+
},
29+
{
30+
"cell_type": "code",
31+
"execution_count": 1,
32+
"metadata": {
33+
"collapsed": true
34+
},
35+
"outputs": [],
36+
"source": [
37+
"# Get a client ID and secret from a text file (to avoid exposing them in the notebook)\n",
38+
"with open('secrets.txt') as secrets:\n",
39+
" client_id = secrets.readline().strip()\n",
40+
" client_secret = secrets.readline().strip()"
41+
]
42+
},
43+
{
44+
"cell_type": "code",
45+
"execution_count": 5,
46+
"metadata": {
47+
"collapsed": false
48+
},
49+
"outputs": [],
50+
"source": [
51+
"# Instantiate a redis managed auth client\n",
52+
"auth = RedisManagedOAuth2(client_id=client_id, client_secret=client_secret)"
53+
]
54+
},
55+
{
56+
"cell_type": "code",
57+
"execution_count": 10,
58+
"metadata": {
59+
"collapsed": false
60+
},
61+
"outputs": [
62+
{
63+
"data": {
64+
"text/plain": [
65+
"(u'g9katDPiv0C5DxcoDmzxxFzumMKpiH2z',\n",
66+
" u'pvGLrhHFdd70Ka7kPY1xxSAQ5RHAWrZBAuA4zbimV1o2Xrouvu0Ixl7iCERU7yTw')"
67+
]
68+
},
69+
"execution_count": 10,
70+
"metadata": {},
71+
"output_type": "execute_result"
72+
}
73+
],
74+
"source": [
75+
"# Authenticate the instance using an auth code (obtained manually)\n",
76+
"auth.authenticate(auth_code='thZWxpiTRPhJpqZRNidr1vZLsmWpHRLI')"
77+
]
78+
},
79+
{
80+
"cell_type": "markdown",
81+
"metadata": {},
82+
"source": [
83+
"The auth instance automatically saves the tokens to redis.\n",
84+
"\n",
85+
"We can see the values directly in redis."
86+
]
87+
},
88+
{
89+
"cell_type": "code",
90+
"execution_count": 13,
91+
"metadata": {
92+
"collapsed": false
93+
},
94+
"outputs": [
95+
{
96+
"name": "stdout",
97+
"output_type": "stream",
98+
"text": [
99+
"1) \"g9katDPiv0C5DxcoDmzxxFzumMKpiH2z\"\r\n",
100+
"2) \"pvGLrhHFdd70Ka7kPY1xxSAQ5RHAWrZBAuA4zbimV1o2Xrouvu0Ixl7iCERU7yTw\"\r\n"
101+
]
102+
}
103+
],
104+
"source": [
105+
"!redis-cli hvals {str(auth.unique_id)}"
106+
]
107+
},
108+
{
109+
"cell_type": "code",
110+
"execution_count": 15,
111+
"metadata": {
112+
"collapsed": false
113+
},
114+
"outputs": [
115+
{
116+
"data": {
117+
"text/plain": [
118+
"u'g9katDPiv0C5DxcoDmzxxFzumMKpiH2z'"
119+
]
120+
},
121+
"execution_count": 15,
122+
"metadata": {},
123+
"output_type": "execute_result"
124+
}
125+
],
126+
"source": [
127+
"auth.access_token"
128+
]
129+
},
130+
{
131+
"cell_type": "markdown",
132+
"metadata": {},
133+
"source": [
134+
"We can spin up another auth instance that will share tokens.\n",
135+
"\n",
136+
"We just need to use the same unique id."
137+
]
138+
},
139+
{
140+
"cell_type": "code",
141+
"execution_count": 16,
142+
"metadata": {
143+
"collapsed": false
144+
},
145+
"outputs": [
146+
{
147+
"data": {
148+
"text/plain": [
149+
"'g9katDPiv0C5DxcoDmzxxFzumMKpiH2z'"
150+
]
151+
},
152+
"execution_count": 16,
153+
"metadata": {},
154+
"output_type": "execute_result"
155+
}
156+
],
157+
"source": [
158+
"auth2 = RedisManagedOAuth2(client_id=client_id, client_secret=client_secret, unique_id=auth.unique_id)\n",
159+
"auth2.access_token"
160+
]
161+
},
162+
{
163+
"cell_type": "code",
164+
"execution_count": null,
165+
"metadata": {
166+
"collapsed": true
167+
},
168+
"outputs": [],
169+
"source": []
170+
}
171+
],
172+
"metadata": {
173+
"kernelspec": {
174+
"display_name": "Python 2",
175+
"language": "python",
176+
"name": "python2"
177+
},
178+
"language_info": {
179+
"codemirror_mode": {
180+
"name": "ipython",
181+
"version": 2
182+
},
183+
"file_extension": ".py",
184+
"mimetype": "text/x-python",
185+
"name": "python",
186+
"nbconvert_exporter": "python",
187+
"pygments_lexer": "ipython2",
188+
"version": "2.7.9"
189+
}
190+
},
191+
"nbformat": 4,
192+
"nbformat_minor": 0
193+
}

demo/Logging Network.ipynb

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"The `LoggingNetwork` network layer is a great tool for debugging your Python SDK applications, or just quickly making requests to the Box Content API."
8+
]
9+
},
10+
{
11+
"cell_type": "code",
12+
"execution_count": 1,
13+
"metadata": {
14+
"collapsed": true
15+
},
16+
"outputs": [],
17+
"source": [
18+
"from boxsdk import Client, OAuth2\n",
19+
"from boxsdk.network.logging_network import LoggingNetwork"
20+
]
21+
},
22+
{
23+
"cell_type": "code",
24+
"execution_count": 2,
25+
"metadata": {
26+
"collapsed": true
27+
},
28+
"outputs": [],
29+
"source": [
30+
"import logging\n",
31+
"root_logger = logging.getLogger()\n",
32+
"for handler in root_logger.handlers:\n",
33+
" root_logger.removeHandler(handler)"
34+
]
35+
},
36+
{
37+
"cell_type": "code",
38+
"execution_count": 3,
39+
"metadata": {
40+
"collapsed": true
41+
},
42+
"outputs": [],
43+
"source": [
44+
"# Create a new instance of the logging network to be used for auth and API requests\n",
45+
"logging_network = LoggingNetwork()\n",
46+
"# Create an auth object that uses a developer token\n",
47+
"DEV_TOKEN = 'g3T46nWfprIRhuHyjfD5LBldwkFEG1RP'\n",
48+
"auth = OAuth2(client_id=None, client_secret=None, access_token=DEV_TOKEN)\n",
49+
"# Create an API client that uses the logging network layer\n",
50+
"client = Client(auth, network_layer=logging_network)"
51+
]
52+
},
53+
{
54+
"cell_type": "code",
55+
"execution_count": 4,
56+
"metadata": {
57+
"collapsed": false
58+
},
59+
"outputs": [
60+
{
61+
"name": "stdout",
62+
"output_type": "stream",
63+
"text": [
64+
"\u001b[36mGET https://api.box.com/2.0/users/me {'headers': {u'Authorization': u'Bearer g3T46nWfprIRhuHyjfD5LBldwkFEG1RP'},\n",
65+
" 'params': None}\u001b[0m\n",
66+
"\u001b[32m{\"type\":\"user\",\"id\":\"202476009\",\"name\":\"Jeffrey Meadows\",\"login\":\"[email protected]\",\"created_at\":\"2013-09-09T14:35:35-07:00\",\"modified_at\":\"2015-12-07T21:49:14-08:00\",\"language\":\"en\",\"timezone\":\"America\\/Los_Angeles\",\"space_amount\":1.0e+15,\"space_used\":28861619684,\"max_upload_size\":16106127360,\"status\":\"active\",\"job_title\":\"\",\"phone\":\"\",\"address\":\"\",\"avatar_url\":\"https:\\/\\/cloud.app.box.com\\/api\\/avatar\\/large\\/202476009\"}\u001b[0m\n"
67+
]
68+
}
69+
],
70+
"source": [
71+
"# Make an API call to get the current user\n",
72+
"me = client.user('me').get()"
73+
]
74+
},
75+
{
76+
"cell_type": "code",
77+
"execution_count": 6,
78+
"metadata": {
79+
"collapsed": false
80+
},
81+
"outputs": [
82+
{
83+
"name": "stdout",
84+
"output_type": "stream",
85+
"text": [
86+
"\u001b[36mGET https://api.box.com/2.0/files/404 {'headers': {u'Authorization': u'Bearer g3T46nWfprIRhuHyjfD5LBldwkFEG1RP'},\n",
87+
" 'params': None}\u001b[0m\n",
88+
"\u001b[31m404\n",
89+
"{'Content-Length': '234', 'Content-Encoding': 'gzip', 'Age': '0', 'Vary': 'Accept-Encoding', 'Server': 'ATS', 'Connection': 'keep-alive', 'Cache-Control': 'no-cache, no-store', 'Date': 'Tue, 08 Dec 2015 19:18:34 GMT', 'Content-Type': 'application/json'}\n",
90+
"'{\"type\":\"error\",\"status\":404,\"code\":\"not_found\",\"context_info\":{\"errors\":[{\"reason\":\"invalid_parameter\",\"name\":\"item\",\"message\":\"Invalid value \\'f_404\\'. \\'item\\' with value \\'f_404\\' not found\"}]},\"help_url\":\"http:\\\\/\\\\/developers.box.com\\\\/docs\\\\/#errors\",\"message\":\"Not Found\",\"request_id\":\"80397196256672d0a379ae\"}'\n",
91+
"\u001b[0m\n"
92+
]
93+
}
94+
],
95+
"source": [
96+
"from boxsdk.exception import BoxAPIException\n",
97+
"# Make an API call to get a nonexistent file\n",
98+
"try:\n",
99+
" four_oh_four = client.file('404').get()\n",
100+
"except BoxAPIException:\n",
101+
" pass"
102+
]
103+
},
104+
{
105+
"cell_type": "markdown",
106+
"metadata": {},
107+
"source": [
108+
"**Requests** are logged in blue; **successful responses** in green, **error responses** in red."
109+
]
110+
}
111+
],
112+
"metadata": {
113+
"kernelspec": {
114+
"display_name": "Python 2",
115+
"language": "python",
116+
"name": "python2"
117+
},
118+
"language_info": {
119+
"codemirror_mode": {
120+
"name": "ipython",
121+
"version": 2
122+
},
123+
"file_extension": ".py",
124+
"mimetype": "text/x-python",
125+
"name": "python",
126+
"nbconvert_exporter": "python",
127+
"pygments_lexer": "ipython2",
128+
"version": "2.7.9"
129+
}
130+
},
131+
"nbformat": 4,
132+
"nbformat_minor": 0
133+
}

0 commit comments

Comments
 (0)