Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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": []
}
```

Expand Down Expand Up @@ -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/`;
Expand All @@ -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

Expand Down
191 changes: 94 additions & 97 deletions examples/create_content.py
Original file line number Diff line number Diff line change
@@ -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}")

###