ScratchSession¶
ScratchSession(username=None, password=None, session_id=None, token=None)
¶
Returns an object representing the user's current session. If a password is not passed, you could pass a session ID and a token to authenticate yourself.
PARAMETERS
-
username (
str | None
) - The username of the user. -
password (
str | None
) - The password of the user's account - used to log in. -
session_id (
str | None
) - The session ID of the session - used to authenticate many requests. -
token (
str | None
) - The token of the user - used to authenticate many requests.
Properties¶
username : str | None
¶
The username of the logged in user.
Will be None
if the user does not log in.
session_id : str | None
¶
The Scratch session ID of the logged in user's session. Required to authenticate most requests to Scratch's old site (scratchr2).
Will be None
if the user does not log in and no session ID is passed to ScratchSession
.
token : str | None
¶
The token of the logged in user. Required to authenticate most requests to Scratch's new site (scratch-www).
Will be None
if the user does not log in and no token is passed to ScratchSession
.
csrf_token : str | None
¶
The CSRF token of the logged in user's session. Required for most requests that need authentication.
Will be None
if the user does not log in or does not provide a session ID or a token.
logged_in : bool
¶
Whether the user is logged in or not. This is True
if the user logs in or provides a session ID or a token.
user : User
¶
The User object of the logged in user.
Will be None
if the user does not log in or does not provide a session ID or a token.
Example:
session = ScratchSession("griffpatch", "realpassword")
print(session.user.id)
# 1882674
forums : ForumSession
¶
A ForumSession object that allows the user to do things with Scratch's forums.
scraping : ScrapingSession
¶
A ScrapingSession object that allows the user to scrape data off Scratch pages that are from the old site (scratchr2). These pages do not have JSON APIs, so it is necessary to scrape the HTML of the pages.
session = ScratchSession("griffpatch", "realpassword")
print(session.scraping.get_profile_comments("ceebee")[0].content)
# Pls ban @griffpatch he is hacking my account
Methods¶
get_user(user)
¶
Gets the User object of the specified username or user.
PARAMETERS
- user (
str | IncompleteUser | User
) - The username of the user or an IncompleteUser or a User object representing it.
RETURNS - User
Example:
print(session.get_user("griffpatch").scratchteam)
# False
get_project(project)
¶
Gets the Project object for the specified ID or project.
PARAMETERS
- project (
str | int | IncompleteProject | RemixtreeProject | Project
) - The ID of the project (as either a string or an integer) or an IncompleteProject, a RemixtreeProject, or a Project object representing it.
RETURNS - Project
Example:
print(session.get_project(60917032).title)
# Appel v1.4
get_studio(id)
¶
Gets the Studio object for the specified ID or studio.
PARAMETERS
- studio (
str | int | IncompleteStudio | Studio
) - The ID of the studio (as either a string or an integer) or an IncompleteStudio or a Studio object representing it.
RETURNS - Studio
Example:
print(session.get_studio(26135902).owner)
# Za-Chary
get_news(all=False, limit=20, offset=0)
¶
Gets Scratch's news as an array of News objects.
PARAMETERS
- all (
Optional[bool]
) - Whether to retrieve every single news headline or onlylimit
headlines. - limit (
Optional[int]
) - How many news headlines to retrieve ifall
isFalse
. - offset (
Optional[int]
) - The offset of the headlines from the newest ones - i.e. an offset of 20 would give you the next 20 headlines after the first 20.
RETURNS - list[News]
Example:
print(session.get_news()[0].title)
# Wiki Wednesday!
get_messages(all=False, limit=20, offset=0, filter="")
¶
Gets the messages of the logged in user as an array of Message objects.
PARAMETERS
- all (
Optional[bool]
) - Whether to retrieve every single message or onlylimit
message. - limit (
Optional[int]
) - How many news messages to retrieve ifall
isFalse
. - offset (
Optional[int]
) - The offset of the messages from the newest ones - i.e. an offset of 20 would give you the next 20 messages after the first 20. - filter (
Optional[Literal[""] | Literal["comments"] | Literal["projects"] | Literal["studios"] | Literal["forums"]]
) - A filter to apply to the messages. Must be one of the following: an empty string, which does not filter out any messages;"comments"
, which only includes comment activity;"projects"
, which only includes project activity;"studios"
, which only includes studio activity; or"forums"
, which only includes forum activity.
RETURNS - list[Message]
Example:
print(session.get_messages(all=True)[0].actor)
# griffpatch
print(session.get_messages(limit=40, offset=10, filter="comments")[0].comment_fragment)
# thank you my friend
create_cloud_connection(project_id, is_async=False, cloud_host="clouddata.scratch.mit.edu", headers={})
¶
Creates a cloud connection for the specified project ID. Returns a CloudConnection object if is_async
is False
, otherwise it returns an AsyncCloudConnection object.
PARAMETERS
- project_id (
int | string
) - The ID of the project to make a connection to, represented as either a string or an integer. - is_async (
Optional[bool]
) - Whether to return aCloudConnection
or anAsyncCloudConnection
. AsyncCloudConnection supports asyncio, whereas CloudConnection is completely synchronous. - cloud_host (
Optional[str]
) - The hostname of the server where the cloud variables are hosted. By default, this is"clouddata.scratch.mit.edu"
. - headers (
dict
) - Any extra headers to add to the connection's handshake.
RETURNS - CloudConnection | AsyncCloudConnection
Example:
connection = session.create_cloud_connection(104)
print(connection.get_cloud_variable('foo'))
# 1391203129031
explore_projects(mode="trending", query="*", language="en")
¶
Explores Scratch projects with the specified mode
(either "trending"
, "popular"
, or "recent"
), query and language. Returns an array of Project objects.
PARAMETERS
- mode (
Optional[Literal["trending"] | Literal["popular"] | Literal["recent"]]
) - The basis of how the projects are sorted - "trending" projects were popular recently, "popular" projects are popular in general, and "recent" projects are recent in general. - query (
Optional[str]
) - The query used to search for the projects. - language (
Optional[str]
) - The language to search for projects in. Must be an ISO 639-1 code.
RETURNS - list[Project]
Example:
print(session.explore_projects()[0].title)
# Epic 7D platformer 2021
explore_studios(mode="trending", query="*")
¶
Explores Scratch studios with the specified mode
(either "trending"
, "popular"
, or "recent"
) and query. Returns an array of Studio objects.
PARAMETERS
- mode (
Optional[Literal["trending"] | Literal["popular"] | Literal["recent"]]
) - The basis of how the studios are sorted - "trending" studios were popular recently, "popular" studios are popular in general, and "recent" studios are recent in general. - query (
Optional[str]
) - The query used to search for the studios.
RETURNS - list[Studio]
search_projects(mode="popular", query="*", language="en")
¶
Searches Scratch projects with the specified mode
(either "trending"
or "popular"
), query
, and language
. Returns an array of Project objects.
PARAMETERS
- mode (
Optional[Literal["trending"] | Literal["popular"]]
) - The basis of how the projects are sorted - "trending" projects were popular recently and "popular" projects are popular in general. - query (
Optional[str]
) - The query used to search for the projects. - language (
Optional[str]
) - The language to search for projects in. Must be an ISO 639-1 code.
RETURNS - list[Project]
search_studios(mode="popular", query="*")
¶
Searches Scratch studios with the specified mode
and query
. Returns an array of Studio objects.
PARAMETERS
- mode (
Optional[Literal["trending"] | Literal["popular"]])
- The basis of how the studios are sorted - "trending" studios were popular recently and "popular" studios are popular in general. - query (
Optional[str]
) - The query used to search for the studios.
get_front_page()
¶
Gets the data that is used for Scratch's front page. It returns a dictionary containing the following items:
"featured_projects"
- Scratch's featured projects; an array of IncompleteProject objects."featured_studios"
- Scratch's featured studios; an array of IncompleteStudio objects."top_loved"
- the most loved recent projects; an array of IncompleteProject objects."top_remixed"
- the most remixed recent projects; an array of IncompleteProject objects."newest"
- new projects on Scratch; an array of IncompleteProject objects."scratch_design_studio"
- projects in Scratch's Scratch Design Studio that are on the front page; an array of IncompleteProject objects."curated"
- projects chosen by the Front Page Curator to be on the front page; an array of IncompleteProject objects."curator"
- the current Front Page Curator; astr
representing their username."current_sds"
- the current Scratch Design Studio; an IncompleteStudio object.
RETURNS - dict
get_activity(limit=5, offset=0)
¶
Gets your follower's activity (the What's Happening? on the front page). You must be logged in for this to not throw an error. Returns an array of Activity objects.
PARAMETERS
- limit (
Optional[int]
) - How many activities to retrieve. - offset (
Optional[int]
) - The offset of the activities from the newest ones - i.e. an offset of 5 would give you the next 5 activites after the first 5.
RETURNS - list[Activity]
create_project(project)
¶
Creates a project. You must be logged in for this to not throw an error. The project will contain the data in the parameter project
, which should be structured like the project.json
file in ordinary projects. Returns the ID of the project as an int
.
PARAMETERS
- project (
dict
) - The data to be put into the project.
RETURNS - int
Example:
project_json = {"targets":[{"isStage":True,"name":"Stage","variables":{"`jEk@4|i[#Fk?(8x)AV.-my variable":["my variable",0]},"lists":{},"broadcasts":{},"blocks":{},"comments":{},"currentCostume":0,"costumes":[{"name":"backdrop1","dataFormat":"svg","assetId":"cd21514d0531fdffb22204e0ec5ed84a","md5ext":"cd21514d0531fdffb22204e0ec5ed84a.svg","rotationCenterX":240,"rotationCenterY":180}],"sounds":[{"name":"pop","assetId":"83a9787d4cb6f3b7632b4ddfebf74367","dataFormat":"wav","format":"","rate":48000,"sampleCount":1123,"md5ext":"83a9787d4cb6f3b7632b4ddfebf74367.wav"}],"volume":100,"layerOrder":0,"tempo":60,"videoTransparency":50,"videoState":"on","textToSpeechLanguage":None},{"isStage":False,"name":"Sprite1","variables":{},"lists":{},"broadcasts":{},"blocks":{},"comments":{},"currentCostume":0,"costumes":[{"name":"costume1","bitmapResolution":1,"dataFormat":"svg","assetId":"bcf454acf82e4504149f7ffe07081dbc","md5ext":"bcf454acf82e4504149f7ffe07081dbc.svg","rotationCenterX":48,"rotationCenterY":50},{"name":"costume2","bitmapResolution":1,"dataFormat":"svg","assetId":"0fb9be3e8397c983338cb71dc84d0b25","md5ext":"0fb9be3e8397c983338cb71dc84d0b25.svg","rotationCenterX":46,"rotationCenterY":53}],"sounds":[{"name":"Meow","assetId":"83c36d806dc92327b9e7049a565c6bff","dataFormat":"wav","format":"","rate":48000,"sampleCount":40681,"md5ext":"83c36d806dc92327b9e7049a565c6bff.wav"}],"volume":100,"layerOrder":1,"visible":True,"x":0,"y":0,"size":100,"direction":90,"draggable":False,"rotationStyle":"all around"}],"monitors":[],"extensions":[],"meta":{"semver":"3.0.0","vm":"0.2.0-prerelease.20220601111129","agent":"Mozilla/5.0 (X11; CrOS x86_64 14588.123.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.72 Safari/537.36"}}
project_id = session.create_project(project)
session.get_project(project_id).share()
create_studio()
¶
Creates a studio. You must be logged in for this to not throw an error. Returns the ID of the studio as an int
.
RETURNS - int
empty_trash(password)
¶
Empties your trash (your deleted projects). You must be logged in for this to not throw an error.
PARAMETERS
- password (
str
) - The password to your account. It's necessary to authenticate this for obvious reasons.
Example:
session.get_project(104).delete()
session.empty_trash("hunter2")
get_own_projects(all=False, sort="", filter="all", page=1)
¶
Gets your own projects, sorted in descending order. You must be logged in for this to not throw an error. Returns an array of Project objects.
PARAMETERS
- all (
Optiona[boo]l
) - Whether to retrieve a single page of projects or all of them. - sort (
Optional[Literal[""] | Literal["view_count"] | Literal["love_count"] | Literal["remixers_count"] | Literal["title"]]
) - The metric used to sort the projects. Must be one of the following:""
"view_count"
"love_count"
"remixers_count"
"title"
If it is an empty string, it will be sorted by the date the project was modified.
- filter (
Optional[Literal["all"] | Literal["shared"] | Literal["notshared"] | Literal["trashed"]]
) - What the projects are filtered by. Must be one of the following:"all"
"shared"
"notshared"
"trashed"
- page (
Optional[int]
) - The page of the data - page 1 has the projects that would be top, and they descend from there. Each page has 40 projects.
RETURNS - list[Project]
Example:
print(str.format("My most loved deleted project is {}", session.get_own_projects(sort="love_count", filter="trashed")[0].id))
# My most loved deleted project is 104
get_own_studios(all=False, sort="", page=1)
¶
Gets your own studios, sorted in descending order. You must be logged in for this to not throw an error. Returns an array of Studio objects. Note that the Studio
objects that are returned do not have a follower_count
or manager_count
attribute but they do have a curator_count
attribute.
PARAMETERS
- all (
Optional[bool]
) - Whether to retrieve a single page of studios or all of them. - sort (
Optional[Literal[""] | Literal["projecters_count"] | Literal["title"]]
) - The metric used to sort the studios. Must be either""
,"projecters_count"
, or"title"
. If it is an empty string, it will be sorted by the date the studio was modified. - page (
Optional[int]
) - The page of the data - page 1 has the studios that would be top, and they descend from there. Each page has 40 studios.
RETURNS - list[Studio]
upload_asset(asset, file_ext=None)
¶
Uploads an asset to assets.scratch.mit.edu
. You must be logged in for this to not throw an error.
PARAMETERS
- asset (
bytes | str
) - The asset that should be uploaded. If it is an instance ofbytes
, it will be interpreted as binary data, but if it is astr
, it will be intepreted as a path to a file. - file_ext (
Optional[str | None]
) - The file extension of the asset. It is only necessary when theasset
parameter is a file name.
change_country(country)
¶
Changes the logged in user's country. You must be logged in for this to not throw an error.
PARAMETERS
- country (
str
) - The country that your country should be changed to.
Example:
session.change_country("Antarctica")
change_password(old_password, new_password)
¶
Changes the logged in user's account's password. You must be logged in for this to not throw an error.
PARAMETERS
- old_password (
str
) - Your account's current password (for authentication). - new_password (
str
) - The password you want your account's password to be changed to.
change_email(new_email, password)
¶
Changes the logged in user's account's email. You must be logged in for this to not throw an error.
PARAMETERS
- new_emaiil (
str
) - The email you want your account's email to be changed to. - password (
str
) - Your account's password (for authentication).
change_email_subscription(activities=False, teacher_tips=False)
¶
Sets what you will receive emails from Scratch for. You must be logged in for this to not throw an error.
PARAMETERS
- activities (
Optional[bool]
) - Whether you'll receive emails for activity ideas for using Scratch at home. - teacher_tips (
Optional[bool]
) - Whether you'll receive emails about product updates for using Scratch in educational settings.
Example:
session.change_email_subscription(teacher_tips=True)
# Now I will receive emails about product updates for using Scratch in educational settings
get_backpack(all=False, limit=20, offset=0)
¶
Gets the data in your backpack. You must be logged in for thsi to not throw an error. Returns an array of BackpackItem objects.
PARAMETERS
- all (
Optional[bool]
) - Whether to retrieve everything in your backpack or justlimit
items. - limit (
Optional[int]
) - How many items to retrieve ifall
isFalse
. - offset (
Optional[int]
) - The offset of the items from the newest ones - i.e. an offset of 20 would give you the next 20 items after the first 20.
RETURNS - list[BackpackItem]
add_to_backpack(item_type, body, mime_type, name, thumbnail)
¶
Adds an item to your backpack. You must be logged in for this to not throw an error. Returns the item put into the backpack as a BackpackItem object.
PARAMETERS
- item_type (
Literal["script"] | Literal["costume"] | Literal["sound"] | Literal["sprite"]
) - The type of item to be put in the backpack. Must be one of the following:"script"
"costume"
"sound"
"sprite"
- body (
str
) - The base-64-encoded data in the item. If theitem_type
of the item is"script"
the data must be in the format that it is in theproject.json
file in ordinary projects. If theitem_type
is"sprite"
, it must be a zipped version of the data in the format that it is in theproject.json
file in ordinary projects. Otherwise, it just has to be the data in the image of the costume or the sound file. - mime_type (
Literal["application/zip"] | Literal["application/json"] | Literal["audio/x-wav"] | Literal["audio/mp3"] | Literal["image/svg+xml"] | Literal["image/png"]
) - The MIME type of the data. If theitem_type
is"script"
, this must be"application/json"
; if theitem_type
is"sprite"
, this must be"application/zip"
; if theitem_type
is"costume"
, this must be"image/svg+xml"
or"image/png"
; and if theitem_type
is"sound"
, this must be"audio/mp3"
or"audio/x-wav"
. - name (
str
) - The name of the item to be added to the backpack. If theitem_type
is"costume"
,"sound"
, or"sprite"
, this is merely the name of the costume, sound, or sprite. If theitem_type
is"script"
, this must be the string"code"
. - thumbnail (
str
) - The base-64-encoded thumbnail of the item to be put in the backpack.
RETURNS - BackpackItem
Example:
import base64
from PIL import Image
from io import BytesIO
costume_file = open("furry.png", "rb")
body = base64.b64encode(costume_file.read())
image = Image.open("furry.png")
with BytesIO() as f:
image.save(f, format="JPEG")
thumbnail = base64.b64encode(f.getvalue())
session.add_to_backpack("costume", body, "image/png", "furry", thumbnail)
get_statistics()
¶
Gets site statistics for Scratch. Returns a dictionary with the following items:
"overall"
- Overall data for Scratch; a dictionary with the following items:"COMMENT_COUNT"
- The total number of comments on the site."PROFILE_COMMENT_COUNT
" - The total number of profile comments on the site."PROJECT_COMMENT_COUNT"
- The total number of project comments on the site."STUDIO_COMMENT_COUNT"
- The total number of studio comments on the site."USER_COUNT"
- The total number of users on the site."PROJECT_COUNT"
- The total number of projects on the site."STUDIO_COUNT"
- The total number of studios on the site.
"last_month"
- Site data for the past month; a dictionary with the following items:"pageviews"
- The number of page views for Scratch over the past month."visits"
- The number of visits to Scratch's website over the past month."users"
- The number of unique visitors to Scratch over the past month.
-
"over_time"
- Site data for Scratch over time, containing the data used to create graphs; a dictionary with the following items:"activity_data"
- Activity trends for Scratch over time. An array of dictionaries with the items"color"
(a hex code),"key"
(astr
), and"values"
(an array full of dictionaries containing X and Y coordinates)."active_user_data"
- Data on monthly active users on Scratch. An array of dictionaries with the items"color"
(a hex code),"key"
(astr
), and"values"
(an array full of dictionaries containing X and Y coordinates)."age_distribution_data"
- Data on the age distribution of new Scratchers. A dict with the following items:"key"
- Astr
with the value"Registration age of Scratchers"
."values"
- An array full of dictionaries containing X and Y coordinates used to draw a histogram.
-
"country_distribution"
- Data on the distribution of the locations of Scratchers. A dictionary with an item for each country, the value being the number of users from the country. -
Fun Fact
There used to be a bug allowing people to change their country to a two-letter code, and the data for those "countries" is still returned here. It also appears that a similar bug was used for 11 people to change their location to "England". Sadly, this bug does not work anymore.
-
"comment_data"
- Data on distribution of location of comment activity. An array of dictionaries with the items"color"
(a hex code),"key"
(astr
), and"values"
(an array full of dictionaries containing X and Y coordinates). "project_data"
- Data on shared projects, representing the distribution of original projects vs. remixed projects. An array of dictionaries with the items"color"
(a hex code),"key"
(astr
), and"values"
(an array full of dictionaries containing X and Y coordinates).
RETURNS - dict
Example:
print(str.format(
"There have been {} users registered who are from England",
session.get_statistics()["over_time"]["country_distribution"]["England"],
))
# There have been 11 users registered who are from England
is_valid_username(username)
¶
Checks if a username can be registered. Returns a bool
representing whether it can.
PARAMETERS
- username (
str
) - The username to be checked for availability.
RETURNS - bool
check_password(password)
¶
Checks if the password passed is your account's password. You must be logged in for this to not throw an error. Returns a bool
representing whether the password is valid.
PARAMETERS
- password (
str
) - The password to be checked for validity.
RETURNS - bool
logout()
¶
Logs out of Scratch. You must be logged in for this to not throw an error.