|
5 | 5 | "metadata": {}, |
6 | 6 | "source": [ |
7 | 7 | "# Batch Result Download\n", |
8 | | - "Download a batch of Conveyal regional analysis results\n", |
| 8 | + "Download a batch of Conveyal regional analysis results. This script was streamlined in April 2024 with the v7.2 Conveyal / R5 release.\n", |
9 | 9 | "\n", |
10 | 10 | "Setup requires:\n", |
11 | 11 | " - Completed regional analysis results, viewable in the Conveyal user interface\n", |
12 | | - " - JSON with array values for the keys `analysisIds`, `cutoffs`, `pointSetId`, and `percentile`, plus the `regionId` saved to `config/regionalAnalysisParameters.json`. The values in the arrays can be derived from the URL of a regional analysis results page in the Conveyal user interface: `https://analysis.conveyal.com/regions/[regionId]/regional/[analysisId]?cutoff=[cutoff]&pointSetId=[pointSetId]&percentile=[percentile]`\n", |
| 12 | + " - JSON with array values for the key `analysisIds` saved to `config/regionalAnalysisParameters.json`. The values in the array can be derived from the URL of regional analysis results pages in the Conveyal user interface: `https://analysis.conveyal.com/regions/[regionId]/regional/[analysisId]`\n", |
13 | 13 | " - A current Conveyal token (e.g. 'bearer 1234abcd...') saved at `config/.auth`, based on the `idToken` shown at https://analysis.conveyal.com/session (for logged in users).\n", |
14 | | - " - Optionally, a session cookie copied from browser DevTools saved at `config/.cookie`\n", |
15 | 14 | "\n", |
16 | | - "After the setup cell in this notebook, there are cells to: \n", |
17 | | - " - Optionally, fetch the names of regional analyses and destination pointset layers\n", |
18 | | - " - Download all combinations of analyses, cutoffs, destination pointsets, and percentiles" |
| 15 | + "After the setup cell in this notebook, the remaining cell: \n", |
| 16 | + " - Downloads a .zip file containing geotiff files for all combinations of analyses, cutoffs, destination pointsets, and percentiles" |
19 | 17 | ] |
20 | 18 | }, |
21 | 19 | { |
|
27 | 25 | }, |
28 | 26 | { |
29 | 27 | "cell_type": "code", |
30 | | - "execution_count": 1, |
| 28 | + "execution_count": null, |
31 | 29 | "metadata": {}, |
32 | 30 | "outputs": [], |
33 | 31 | "source": [ |
34 | 32 | "import requests\n", |
35 | 33 | "import json\n", |
36 | 34 | "import urllib\n", |
37 | 35 | "import os\n", |
| 36 | + "import time\n", |
38 | 37 | "\n", |
39 | 38 | "config = json.load(open('config/regionalAnalysisParameters.json'))\n", |
40 | 39 | "\n", |
41 | | - "# Authorization header copied from DevTools Network request or https://analysis.conveyal.com/session\n", |
| 40 | + "# Authorization header with idToken copied from https://analysis.conveyal.com/session\n", |
42 | 41 | "token = open('config/.auth').readline().strip()\n", |
43 | 42 | "headers = {\n", |
44 | 43 | " 'Authorization': token\n", |
45 | 44 | "}\n", |
46 | | - "resultUrl = 'https://api.conveyal.com/api/regional/'\n", |
47 | | - "\n", |
48 | | - "namesFetched = False;\n", |
49 | | - "\n", |
50 | | - "# Cookie copied from browser Devtools Network request header\n", |
51 | | - "cookie = open('config/.cookie').readline().strip()\n", |
52 | | - "dbHeaders = {\n", |
53 | | - " 'Cookie': cookie\n", |
54 | | - "}\n", |
55 | | - "dbUrl = 'https://analysis.conveyal.com/api/db/'" |
56 | | - ] |
57 | | - }, |
58 | | - { |
59 | | - "cell_type": "markdown", |
60 | | - "metadata": {}, |
61 | | - "source": [ |
62 | | - "## Fetch names\n", |
63 | | - "Optional, requires saved cookie" |
64 | | - ] |
65 | | - }, |
66 | | - { |
67 | | - "cell_type": "code", |
68 | | - "execution_count": 2, |
69 | | - "metadata": {}, |
70 | | - "outputs": [], |
71 | | - "source": [ |
72 | | - "analysesRequest = requests.get(dbUrl + 'regional-analyses?options=' + urllib.parse.urlencode({\"projection\":{\"request.scenario.modifications\":0}}), headers = dbHeaders)\n", |
73 | | - "analyses = analysesRequest.json()\n", |
74 | | - "\n", |
75 | | - "opportunitiesRequest = requests.get(dbUrl + 'opportunityDatasets?', headers = dbHeaders)\n", |
76 | | - "opportunities = opportunitiesRequest.json()\n", |
77 | | - "destinations = {}\n", |
78 | | - "\n", |
79 | | - "for destinationPointSetId in config['pointSetIds']:\n", |
80 | | - " destinationPointSetName = list(filter(lambda x:x[\"_id\"] == destinationPointSetId, opportunities))[0]['name']\n", |
81 | | - " destinations[destinationPointSetId] = destinationPointSetName\n", |
82 | | - "\n", |
83 | | - "namesFetched = True;" |
| 45 | + "baseUrl = 'https://api.conveyal.com/api/regional/'" |
84 | 46 | ] |
85 | 47 | }, |
86 | 48 | { |
|
100 | 62 | "# Loop over analysis ids\n", |
101 | 63 | "for analysisId in config['analysisIds']:\n", |
102 | 64 | " \n", |
103 | | - " analysisName = analysisId\n", |
104 | | - " if namesFetched:\n", |
105 | | - " analysisProperties = list(filter(lambda x:x['_id']==analysisId, analyses))[0]\n", |
106 | | - " with open('results/' + analysisId + '.json', 'w') as f:\n", |
107 | | - " json.dump(analysisProperties, f)\n", |
108 | | - " analysisName = analysisProperties['name']\n", |
109 | | - " print('Processing ' + analysisName)\n", |
110 | | - " \n", |
111 | | - " # Loop over cutoffs, percentiles, and destination opportunity pointsets\n", |
112 | | - " for cutoff in config['cutoffs']:\n", |
113 | | - " for percentile in config['percentiles']:\n", |
114 | | - " for destinationPointSetId in config['pointSetIds']:\n", |
115 | | - " \n", |
116 | | - " destinationPointSetName = destinationPointSetId\n", |
117 | | - " if namesFetched:\n", |
118 | | - " destinationPointSetName = destinations[destinationPointSetId]\n", |
119 | | - " \n", |
120 | | - " gridQuery = urllib.parse.urlencode({'cutoff': cutoff, 'percentile': percentile, 'destinationPointSetId': destinationPointSetId})\n", |
121 | | - " gridUrl = resultUrl + analysisId + '/grid/geotiff?' + gridQuery\n", |
122 | | - " \n", |
123 | | - " # Request a signed S3 url from the Conveyal API\n", |
124 | | - " r = requests.get(gridUrl, headers = headers, verify = False)\n", |
| 65 | + " print('Processing ' + analysisId)\n", |
| 66 | + " status = 202;\n", |
125 | 67 | " \n", |
126 | | - " if r.status_code == 403:\n", |
127 | | - " print('Unauthorized access. Your authorization token may be invalid or expired.')\n", |
| 68 | + " while (status == 202):\n", |
| 69 | + " resultUrl = baseUrl + analysisId + '/all'\n", |
| 70 | + " # Request a signed S3 url from the Conveyal API\n", |
| 71 | + " r = requests.get(resultUrl, headers = headers, verify = False)\n", |
| 72 | + " if r.status_code == 403:\n", |
| 73 | + " print('Unauthorized access. Your authorization token may be invalid or expired.')\n", |
| 74 | + " \n", |
| 75 | + " elif r.status_code == 404:\n", |
| 76 | + " print('Results not found. Check your analysisId values')\n", |
128 | 77 | " \n", |
129 | | - " elif r.status_code != 200:\n", |
130 | | - " print('Error: ' + r.text)\n", |
| 78 | + " elif r.status_code == 202:\n", |
| 79 | + " print(r.text + ' Retrying in 15 seconds.')\n", |
| 80 | + " time.sleep(15)\n", |
131 | 81 | " \n", |
132 | | - " else:\n", |
133 | | - " # From the signed S3 url, fetch the grid as a geotiff\n", |
134 | | - " grid = requests.get(r.json()['url'], verify = False)\n", |
135 | | - " # Save response from Conveyal Analysis to a local .geotiff file\n", |
136 | | - " with open('results/' + ('-').join((analysisId, destinationPointSetName, str(cutoff) + 'min', str(percentile) + 'pct')) + '.geotiff', 'wb') as f:\n", |
137 | | - " for chunk in grid.iter_content(chunk_size=128):\n", |
138 | | - " f.write(chunk)\n", |
139 | | - " f.close()" |
| 82 | + " elif (r.status_code != 200):\n", |
| 83 | + " print('Error: ' + r.text)\n", |
| 84 | + " \n", |
| 85 | + " status = r.status_code\n", |
| 86 | + " \n", |
| 87 | + " if (status == 200):\n", |
| 88 | + " zipRequest = requests.get(r.json()['url'], verify = False)\n", |
| 89 | + "\n", |
| 90 | + " # Save result to a local .zip file\n", |
| 91 | + " with open('results/' + analysisId + '.zip', 'wb') as f:\n", |
| 92 | + " for chunk in zipRequest.iter_content(chunk_size=128):\n", |
| 93 | + " f.write(chunk)\n", |
| 94 | + " f.close()" |
140 | 95 | ] |
141 | 96 | } |
142 | 97 | ], |
|
0 commit comments