diff --git a/README.md b/README.md index 373a040..4f24a82 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Stepik.org has REST API in JSON format. API endpoints are listed on https://stepik.org/api/docs, and you can also make API call there (but this page is limited to `GET` requests). -Stepik.org use the same API for its web front-end (JS app) and its iOS/Android applications. Therefore, almost all the platform features are supported in this API. +Stepik.org uses the same API for its web front-end (JS app) and its iOS/Android applications. Therefore, almost all the platform features are supported in this API. All API examples are up to date and working if the build status is `passing`: [![Build Status](https://travis-ci.org/StepicOrg/Stepik-API.svg?branch=master)](https://travis-ci.org/StepicOrg/Stepik-API) @@ -19,12 +19,12 @@ For example: `https://stepik.org/api/courses/1` returns not a single course, but All responses to `GET` requests are paginated. They contain extra `meta` object with the information about pagination. It may look like this: ``` { - meta: { - page: 1, - has_next: true, - has_previous: false + "meta": { + "page": 1, + "has_next": true, + "has_previous": false }, - requested_objects: [...] + "requested_objects": [] } ``` @@ -69,8 +69,8 @@ Response: #### Authorization code flow -- Set `grant type = autorization_code` and set `redirect_uri` in your application; -- Redirect user to `https://stepik.org/oauth2/authorize/?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI`; +- Set `grant type = authorization_code` and set `redirect_uri` in your application; +- Redirect the user to `https://stepik.org/oauth2/authorize/?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI`; - User should authenticate or register, and grant permissions to application; - It redirects to `redirect_uri` and receives the `CODE`; - Application asks for `ACCESS_TOKEN`: `curl -X POST -d "grant_type=authorization_code&code=CODE&redirect_uri=REDIRECT_URI" -u"CLIENT_ID:SECRET_ID" https://stepik.org/oauth2/token/`; @@ -81,11 +81,11 @@ Response: You can request multiple objects using the single API call by using `?ids[]=2&ids[]=3...`. -For example: to get courses with IDs = `2`, `67`, `76` and `70`; you can to call `https://stepik.org/api/courses?ids[]=2&ids[]=67&ids[]=76&ids[]=70`. +For example: to get courses with IDs = `2`, `67`, `76` and `70`; you can call `https://stepik.org/api/courses?ids[]=2&ids[]=67&ids[]=76&ids[]=70`. This syntax is supported by all API endpoints. -Don’t make calls with large size of `ids[]`. Such calls may be rejected by the server because of a large HTTP header. +Don’t make calls with a large number of `ids[]`. Such calls may be rejected by the server because of a large HTTP header. ## Examples diff --git a/examples/create_content.py b/examples/create_content.py index 6bcd373..aa7c03d 100644 --- a/examples/create_content.py +++ b/examples/create_content.py @@ -1,151 +1,148 @@ +"""Example script demonstrating usage of the Stepik API.""" + # Run with Python 3 import json + import requests # 1. Get your keys at https://stepik.org/oauth2/applications/ (client type = confidential, authorization grant type = client credentials) -client_id = '...' -client_secret = '...' + +client_id = "..." +client_secret = "..." # 2. Get a token auth = requests.auth.HTTPBasicAuth(client_id, client_secret) -resp = requests.post('https://stepik.org/oauth2/token/', data={'grant_type': 'client_credentials'}, auth=auth) -token = json.loads(resp.text)['access_token'] +resp = requests.post( + "https://stepik.org/oauth2/token/", + data={"grant_type": "client_credentials"}, + auth=auth, +) +token = json.loads(resp.text)["access_token"] # 3. Call API (https://stepik.org/api/docs/) using this token. # Example: # 3.1. Create a new lesson -api_url = 'https://stepik.org/api/lessons' -data = { - 'lesson': { - 'title': 'My Lesson' - } -} +api_url = "https://stepik.org/api/lessons" +data: dict[str, object] = {"lesson": {"title": "My Lesson"}} # Use POST to create new objects -r = requests.post(api_url, headers={'Authorization': 'Bearer '+ token}, json=data) -lesson_id = r.json()['lessons'][0]['id'] -print('Lesson ID:', lesson_id) +response = requests.post( + api_url, headers={"Authorization": "Bearer " + token}, json=data +) +lesson_id = response.json()["lessons"][0]["id"] +print("Lesson ID:", lesson_id) + # You can also debug using: -# print(r.status_code) – should be 201 (HTTP Created) -# print(r.text) – should print the lesson's json (with lots of properties) +# print(response.status_code) – should be 201 (HTTP Created) +# print(response.text) – should print the lesson's json (with lots of properties) # 3.2. Add new theory step to this lesson -api_url = 'https://stepik.org/api/step-sources' +api_url = "https://stepik.org/api/step-sources" data = { - 'stepSource': { - 'block': { - 'name': 'text', - 'text': 'Hello World!' - }, - 'lesson': lesson_id, - 'position': 1 - } + "stepSource": { + "block": {"name": "text", "text": "Hello World!"}, + "lesson": lesson_id, + "position": 1, + } } -r = requests.post(api_url, headers={'Authorization': 'Bearer '+ token}, json=data) -step_id = r.json()['step-sources'][0]['id'] -print('Step ID:', step_id) +response = requests.post( + api_url, headers={"Authorization": "Bearer " + token}, json=data +) +step_id = response.json()["step-sources"][0]["id"] +print("Step ID:", step_id) # 3.3. Update existing theory step -api_url = 'https://stepik.org/api/step-sources/{}'.format(step_id) +api_url = f"https://stepik.org/api/step-sources/{step_id}" data = { - 'stepSource': { - 'block': { - 'name': 'text', - 'text': 'Hi World!' # <-- changed here :) - }, - 'lesson': lesson_id, - 'position': 1 - } + "stepSource": { + "block": {"name": "text", "text": "Hi World!"}, # <-- changed here :) + "lesson": lesson_id, + "position": 1, + } } # Use PUT to update existing objects -r = requests.put(api_url, headers={'Authorization': 'Bearer '+ token}, json=data) -step_id = r.json()['step-sources'][0]['id'] -print('Step ID (update):', step_id) +response = requests.put( + api_url, headers={"Authorization": "Bearer " + token}, json=data +) +step_id = response.json()["step-sources"][0]["id"] +print("Step ID (update):", step_id) # 3.4. Add new multiple (single) choice step to this lesson -api_url = 'https://stepik.org/api/step-sources' +api_url = "https://stepik.org/api/step-sources" data = { - 'stepSource': { - 'block': { - 'name': 'choice', - 'text': 'Pick one!', - 'source': { - 'options': [ - {'is_correct': False, 'text': '2+2=3', 'feedback': ''}, - {'is_correct': True, 'text': '2+2=4', 'feedback': ''}, - {'is_correct': False, 'text': '2+2=5', 'feedback': ''}, - ], - 'is_always_correct': False, - 'is_html_enabled': True, - 'sample_size': 3, - 'is_multiple_choice': False, - 'preserve_order': False, - 'is_options_feedback': False - } - }, - 'lesson': lesson_id, - 'position': 2 - } + "stepSource": { + "block": { + "name": "choice", + "text": "Pick one!", + "source": { + "options": [ + {"is_correct": False, "text": "2+2=3", "feedback": ""}, + {"is_correct": True, "text": "2+2=4", "feedback": ""}, + {"is_correct": False, "text": "2+2=5", "feedback": ""}, + ], + "is_always_correct": False, + "is_html_enabled": True, + "sample_size": 3, + "is_multiple_choice": False, + "preserve_order": False, + "is_options_feedback": False, + }, + }, + "lesson": lesson_id, + "position": 2, + } } -r = requests.post(api_url, headers={'Authorization': 'Bearer '+ token}, json=data) -step_id = r.json()['step-sources'][0]['id'] -print('Step ID:', step_id) +response = requests.post( + api_url, headers={"Authorization": "Bearer " + token}, json=data +) +step_id = response.json()["step-sources"][0]["id"] +print("Step ID:", step_id) ### # Your lesson is ready! -print('--> Check https://stepik.org/lesson/{}'.format(lesson_id)) +print(f"--> Check https://stepik.org/lesson/{lesson_id}") ### # 3.4. Create a new course -api_url = 'https://stepik.org/api/courses' -data = { - 'course': { - 'title': 'My Course' - } -} -r = requests.post(api_url, headers={'Authorization': 'Bearer '+ token}, json=data) -course_id = r.json()['courses'][0]['id'] -print('Course ID:', course_id) +api_url = "https://stepik.org/api/courses" +data = {"course": {"title": "My Course"}} +response = requests.post( + api_url, headers={"Authorization": "Bearer " + token}, json=data +) +course_id = response.json()["courses"][0]["id"] +print("Course ID:", course_id) # 3.5. Add new module (section) to this course -api_url = 'https://stepik.org/api/sections' -data = { - 'section': { - 'title': 'My Section', - 'course': course_id, - 'position': 1 - } -} -r = requests.post(api_url, headers={'Authorization': 'Bearer '+ token}, json=data) -section_id = r.json()['sections'][0]['id'] -print('Section ID:', section_id) +api_url = "https://stepik.org/api/sections" +data = {"section": {"title": "My Section", "course": course_id, "position": 1}} +response = requests.post( + api_url, headers={"Authorization": "Bearer " + token}, json=data +) +section_id = response.json()["sections"][0]["id"] +print("Section ID:", section_id) # 3.6. Add your existing lesson to this section (it is called unit) -api_url = 'https://stepik.org/api/units' -data = { - 'unit': { - 'section': section_id, - 'lesson': lesson_id, - 'position': 1 - } -} -r = requests.post(api_url, headers={'Authorization': 'Bearer '+ token}, json=data) -unit_id = r.json()['units'][0]['id'] -print('Unit ID:', unit_id) +api_url = "https://stepik.org/api/units" +data = {"unit": {"section": section_id, "lesson": lesson_id, "position": 1}} +response = requests.post( + api_url, headers={"Authorization": "Bearer " + token}, json=data +) +unit_id = response.json()["units"][0]["id"] +print("Unit ID:", unit_id) ### # Your course is ready -print('--> Check https://stepik.org/course/{}'.format(course_id)) +print(f"--> Check https://stepik.org/course/{course_id}") ###