{"_id":"5791371e405a842b0081760c","user":"55dcd2338a3dcd2300cc5ecf","version":{"_id":"56439dff9eebf70d00490d57","project":"56439dfe9eebf70d00490d54","__v":26,"createdAt":"2015-11-11T19:58:55.144Z","releaseDate":"2015-11-11T19:58:55.144Z","categories":["56439dff9eebf70d00490d58","56439e17c92c470d002dec71","564ce88e802cd02100444274","564d07ff3657c43500bf1d33","564d0a312da1982d00b19b64","564d2aa92da1982d00b19b8c","564d30a8b88a37210082253e","564d362c2da1982d00b19ba0","569d664371e3650d00acf018","569d7eacec29360d00f667c9","569d8006ec29360d00f667cb","569d855e0306a10d00ce99b9","569d91d571e3650d00acf04c","569d91eeceb7510d00f2a6a3","569e8c262d320817003b806d","569e8f802d320817003b8072","56b038c914dfea0d0007cf05","5717b4f0681bb41900fc575a","5718e0a4cd483219007c2c9a","571924c8e967cb1700d078e9","571e2648edc4a92b00a4cc65","576a677a6f15260e001f899b","576c5eaf5738570e00ff070f","578d127ed9c55c2000d4f213","579f90927ebe9b0e00059c50","582c0af888708a0f00570a69"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":false,"codename":"","version_clean":"1.0.0","version":"1"},"__v":0,"githubsync":"","project":"56439dfe9eebf70d00490d54","category":{"_id":"578d127ed9c55c2000d4f213","__v":0,"project":"56439dfe9eebf70d00490d54","version":"56439dff9eebf70d00490d57","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-07-18T17:31:42.071Z","from_sync":false,"order":20,"slug":"one-roster","title":"One Roster"},"parentDoc":null,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-07-21T20:57:02.669Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"settings":"","results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"This guide can be used as a tutorial for uploading a zip containing OneRoster-standarized CSVs without the aid of the user-interface provided by the Gooru's OneRoster application.\n\nBear in mind that the code we're using to build and make the request is written in Ruby, but it should be easily replicated in another programming language\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"1. Gather the information\"\n}\n[/block]\nWe'll need the following information to build the request\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"Partner\",\n    \"0-1\": \"\",\n    \"1-0\": \"District\",\n    \"1-1\": \"\",\n    \"2-0\": \"CSV File\",\n    \"3-0\": \"User Credentials\",\n    \"3-1\": \"These consist of a *client id* and a *client key*. A client should have them.\",\n    \"h-0\": \"Data\",\n    \"h-1\": \"Description\"\n  },\n  \"cols\": 2,\n  \"rows\": 4\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"2. Make the request\"\n}\n[/block]\nThis is the Ruby code that allows us to make the request that successfully uploads a zip with the csvs and which then proceeds with the migration/exporting of records:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"require 'rest_client'\\n\\npayload = {\\n      zip_upload: {\\n        partner: 'Partner Name',\\n        district: 'District Name',\\n        filename: File.open('path/to/file_containing_csvs.zip', 'r')\\n      }\\n    }\\nRestClient.post 'https://oneroster.gooru.org/zip_uploads',\\n                payload,\\n                {\\n                  content_type: :json,\\n                  accept: :json,\\n                  Authorization: 'Basic ************'\\n                  }\",\n      \"language\": \"ruby\"\n    }\n  ]\n}\n[/block]\nThere are several details that are worth mentioning:\n1. For this code to run, Ruby 2+ is needed. Also, the *rest-client* gem should be installed (https://github.com/rest-client/rest-client).\n2.Three request headers must be specified:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Header\",\n    \"h-1\": \"Value\",\n    \"0-0\": \"Content-type\",\n    \"0-1\": \"application/json\",\n    \"1-0\": \"Accept\",\n    \"1-1\": \"application/json\",\n    \"2-0\": \"Authorization\",\n    \"2-1\": \"`Basic` followed by the base 64 encoded client id and client key. For example, if client id equals `1111` and client key equals `2222`, we'll need to join both values with a `:` in between: `1111:2222`. Then we have to encode them using base 64. This gives `MTExMToyMjIy`. That means that our Authorization header must look like `Basic MTExMToyMjIy`\"\n  },\n  \"cols\": 2,\n  \"rows\": 3\n}\n[/block]\n3. It may not be evident in the code, so here but the names of the keys of the payload must be: `zip_upload[partner]`, `zip_upload[district]`, `zip_upload[filename]`\n4. The request must be sent as **multipart**. In the Ruby example code, the **rest-client** gem recognizes that a file is present in the payload, and sets `multipart true` automatically, but in other languages/tools this might need to be specified.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"Depending on how much your zip file has, and how fast is your Internet connection, this request will take some time to be completed.\",\n  \"title\": \"The request takes too long to complete\"\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"File restriction\",\n  \"body\": \"The limit on the file size is `200 MB`. The file must also be a `zip` file\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"3. Handle the response\"\n}\n[/block]\nThere are several http codes that might be received in the response:\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"500\",\n    \"0-1\": \"An application error has occurred. There's no more the client can do except perhaps warn warn Gooru of this\",\n    \"1-0\": \"404 Not Found\",\n    \"1-1\": \"Check the url in the request: it might have been mistyped. Also, check that the HTTP method used in the request is `POST`. If everything is correctly specified and you're still getting `404`, please contact Gooru\",\n    \"2-0\": \"401 Unauthorized\",\n    \"2-1\": \"Check that you're correctly submitting the `Authorization` header. Check that you are submitting the correct encoded credentials. If you think everything is ok on your end, please contact Gooru\",\n    \"3-0\": \"400 Bad Request\",\n    \"3-1\": \"Check that your request has **ALL** of the fields in the payload, and that they have the specified format (`zip_upload[partner]` and so).\",\n    \"4-0\": \"422 Validation Error\",\n    \"4-1\": \"Check that all of the fields in the request have a value. This differs from `400` because you might have the payload correctly formatted with all the fields, but some field may have no value (For example `zip_upload[district] might be empty and it shouldn't)\",\n    \"5-0\": \"200 OK\",\n    \"5-1\": \"This response is the nice one. It should have a body, in JSON, which looks like this:\\n\\n`{\\\"zip_upload\\\": { \\\"id\\\":96, \\\"uuid\\\": \\\"ff9efe89-9b46-4961-b693-525236578994\\\"}}`.\\n\\nThis is just information regarding the upload you just did. If you want to view the progress on the migration, you could use the received `uuid` like this:\\n\\nhttps://oneroster.gooru.org/zip_uploads/<uuid>\\n\\nWhere `<uuid>` is the uuid of the zip upload you just did. However, you'll need to use the UI and be logged in to enter the link\"\n  },\n  \"cols\": 2,\n  \"rows\": 6\n}\n[/block]","excerpt":"","slug":"upload-zip-with-csvs-without-using-the-oneroster-app-ui","type":"basic","title":"Upload zip with CSVs without using the OneRoster app UI"}

Upload zip with CSVs without using the OneRoster app UI


This guide can be used as a tutorial for uploading a zip containing OneRoster-standarized CSVs without the aid of the user-interface provided by the Gooru's OneRoster application. Bear in mind that the code we're using to build and make the request is written in Ruby, but it should be easily replicated in another programming language [block:api-header] { "type": "basic", "title": "1. Gather the information" } [/block] We'll need the following information to build the request [block:parameters] { "data": { "0-0": "Partner", "0-1": "", "1-0": "District", "1-1": "", "2-0": "CSV File", "3-0": "User Credentials", "3-1": "These consist of a *client id* and a *client key*. A client should have them.", "h-0": "Data", "h-1": "Description" }, "cols": 2, "rows": 4 } [/block] [block:api-header] { "type": "basic", "title": "2. Make the request" } [/block] This is the Ruby code that allows us to make the request that successfully uploads a zip with the csvs and which then proceeds with the migration/exporting of records: [block:code] { "codes": [ { "code": "require 'rest_client'\n\npayload = {\n zip_upload: {\n partner: 'Partner Name',\n district: 'District Name',\n filename: File.open('path/to/file_containing_csvs.zip', 'r')\n }\n }\nRestClient.post 'https://oneroster.gooru.org/zip_uploads',\n payload,\n {\n content_type: :json,\n accept: :json,\n Authorization: 'Basic ************'\n }", "language": "ruby" } ] } [/block] There are several details that are worth mentioning: 1. For this code to run, Ruby 2+ is needed. Also, the *rest-client* gem should be installed (https://github.com/rest-client/rest-client). 2.Three request headers must be specified: [block:parameters] { "data": { "h-0": "Header", "h-1": "Value", "0-0": "Content-type", "0-1": "application/json", "1-0": "Accept", "1-1": "application/json", "2-0": "Authorization", "2-1": "`Basic` followed by the base 64 encoded client id and client key. For example, if client id equals `1111` and client key equals `2222`, we'll need to join both values with a `:` in between: `1111:2222`. Then we have to encode them using base 64. This gives `MTExMToyMjIy`. That means that our Authorization header must look like `Basic MTExMToyMjIy`" }, "cols": 2, "rows": 3 } [/block] 3. It may not be evident in the code, so here but the names of the keys of the payload must be: `zip_upload[partner]`, `zip_upload[district]`, `zip_upload[filename]` 4. The request must be sent as **multipart**. In the Ruby example code, the **rest-client** gem recognizes that a file is present in the payload, and sets `multipart true` automatically, but in other languages/tools this might need to be specified. [block:callout] { "type": "warning", "body": "Depending on how much your zip file has, and how fast is your Internet connection, this request will take some time to be completed.", "title": "The request takes too long to complete" } [/block] [block:callout] { "type": "warning", "title": "File restriction", "body": "The limit on the file size is `200 MB`. The file must also be a `zip` file" } [/block] [block:api-header] { "type": "basic", "title": "3. Handle the response" } [/block] There are several http codes that might be received in the response: [block:parameters] { "data": { "0-0": "500", "0-1": "An application error has occurred. There's no more the client can do except perhaps warn warn Gooru of this", "1-0": "404 Not Found", "1-1": "Check the url in the request: it might have been mistyped. Also, check that the HTTP method used in the request is `POST`. If everything is correctly specified and you're still getting `404`, please contact Gooru", "2-0": "401 Unauthorized", "2-1": "Check that you're correctly submitting the `Authorization` header. Check that you are submitting the correct encoded credentials. If you think everything is ok on your end, please contact Gooru", "3-0": "400 Bad Request", "3-1": "Check that your request has **ALL** of the fields in the payload, and that they have the specified format (`zip_upload[partner]` and so).", "4-0": "422 Validation Error", "4-1": "Check that all of the fields in the request have a value. This differs from `400` because you might have the payload correctly formatted with all the fields, but some field may have no value (For example `zip_upload[district] might be empty and it shouldn't)", "5-0": "200 OK", "5-1": "This response is the nice one. It should have a body, in JSON, which looks like this:\n\n`{\"zip_upload\": { \"id\":96, \"uuid\": \"ff9efe89-9b46-4961-b693-525236578994\"}}`.\n\nThis is just information regarding the upload you just did. If you want to view the progress on the migration, you could use the received `uuid` like this:\n\nhttps://oneroster.gooru.org/zip_uploads/<uuid>\n\nWhere `<uuid>` is the uuid of the zip upload you just did. However, you'll need to use the UI and be logged in to enter the link" }, "cols": 2, "rows": 6 } [/block]