Basic Tutorial
This tutorial will create a basic event-based application.
This tutorial assumes you’ve already installed scratchcloud. See Getting Started if you haven’t yet.
Basic Events
To start off, let’s create a basic CloudClient
.
Note
A CloudClient
is an object that represents the connection between scratch and python. One can be created through the following:
First, create a file named main.py
:
from scratchcloud import CloudClient
client = CloudClient(username='yuwe', project_id='622084628')
In this example, the CloudClient
object is imported. Then, a new CloudClient
object is created using using a username and a project ID. The project id 622084628 is a basic test project for this library.
Warning
CloudClient
objects will only connect to projects that have cloud variables. If a project does not have any cloud variables, a MissingCloudVariable
exception will be raised.
The following code shows how to create events. scratchcloud uses python decorators to define all event-based API interactions.
1from scratchcloud import CloudClient, CloudChange
2
3client = CloudClient(username='yuwe', project_id='622084628')
4
5@client.event
6async def on_connect():
7 print('Hello world!')
8
9@client.event
10async def on_disconnect():
11 print('Goodbye world!')
12
13@client.event
14async def on_message(var: CloudChange):
15 print(f'{var.name} changed to {var.value}!')
16
17client.run('Your Password Here!')
The first thing to notice are the decorators, @client.event
. These client event decorators will call their decorated functions depending on the functions’ specific names.
Warning
The keyword async
is used before all functions with the @client.event
decorator. Since this library is asynchronous, all of its API-related methods require the async
keyword.
These function names are:
on_connect
— Called when the client connects to scratchon_disconnect
— Called when the client disconnects from scratchon_message
— Called when any cloud variable changes
Note
The on_message
event has special syntax. It requires one positional argument, which is a CloudChange
object. On line 1, CloudChange
is imported.
Whenever a variable changes, the client will create a CloudChange
object with the changed variable information. Then, the client will call the on_message
function with that CloudChange
object.
CloudChange
objects have several attributes, and this example uses CloudChange.name
and CloudChange.value
.
More attributes for CloudChange objects can be found here: scratchcloud.client.CloudChange
Lastly, on line 17, this example runs the code using client.run()
. The text that states 'Your Password Here!'
should be your actual password. The client.run
method is blocking, and all code after it will not be run until the client is stopped.
Warning
If you plan to publish your project on Github or Repl, make sure that your password is hidden!
If you want to use Repl to host your projects, check out the LoginCookie
documentation here: scratchcloud.client.LoginCookie
After this code is run, going to the project id specified in the client, clicking the cat, and changing some variables will cause the scratchcloud client to print the changes! For example, clicking the cat and entering 100 will make scratchcloud print REQUEST changed to 100!
Note
You can stop a CloudClient
by using Control + C.
Setting Cloud Variables
scratchcloud can also change variables! The CloudClient
object has a method called set_cloud
which can be used to set cloud variables.
Using the previous code, the on_message
event is changed to “respond”:
from scratchcloud import CloudClient, CloudChange
client = CloudClient(username='yuwe', project_id='622084628')
@client.event
async def on_connect():
print('Hello world!')
@client.event
async def on_disconnect():
print('Goodbye world!')
@client.event
async def on_message(var: CloudChange):
print(f'{var.name} changed to {var.value}!')
await client.set_cloud(var.name, '200')
client.run('Your Password Here!')
The client.set_cloud
method requires two parameters: the name of the cloud variable to be set, and the value the variable will be set to. Using var.name
and '200'
, this code “responds” to someone setting a variable by setting it back to 200. Once again, the await
keyword is necesary before setting any variables to ensure asynchronous execution.
If the client is run again, after another variable is sent to the test project, the variable we set will immediately be reset to 200 by the client!
Warning
Spamming client.set_cloud
in a while loop will result in ratelimits and possible account IP bans. The likelyhood of this happening is reduced when using events to “respond” to people “requesting” something!
Using Cloud Events
scratchcloud has a system for monitoring only a specific cloud variable. This system is cloud events. Cloud events allow programmers to use different cloud variables for different things. They also come with simple error handling.
The following will rewrite main.py
with cloud events:
1from scratchcloud import CloudClient, CloudChange
2client = CloudClient(username='yuwe', project_id='622084628')
3
4@client.event
5async def on_connect():
6 print('Hello world!')
7
8@client.event
9async def on_disconnect():
10 print('Goodbye world!')
11
12@client.cloud_event('REQUEST')
13async def on_request(var: CloudChange):
14 print(f'The REQUEST variable was changed to {var.value}!')
15 await client.set_cloud('RESPONSE', '200')
16
17client.run('Your Password Here!')
In this example, a simple cloud event is defined.
First, on line 12, the cloud event decorator is created with a variable name, which, in this case, is
REQUEST
.On line 13, a async function is defined with one argument of type
CloudChange
. This function can have any name, but it is recommended to useon_variablename
syntax.Line 14 prints out the changes to the REQUEST cloud variable.
Line 15 sets a different variable named
RESPONSE
to 200.
This call-and-response method is highly efficient compared to other scratch libraries. There is no polling involved in the internal code, meaning that the client’s response is as fast as the websocket connection can be!
Note
In this example, in scratch, the cloud variables are named ☁️ REQUEST
and ☁️ RESPONSE
.
Make sure that in your own code, for client.cloud_event and client.set_cloud, you use the correct variable names without the cloud emoji!
If your variable was named ☁️ Cloud Data
in scratch, it would be called Cloud Data
in scratchcloud.
Lets say, for some reason, receiving a 0 from a user causes an error in your code.
scratchcloud makes it easy to catch errors in cloud events. In the same program change the cloud_event function to raise an Exception
and add the following @client.cloud_event_error
:
Cloud event error decorators are set up in the similarly to @client.cloud_event
, but they have an extra positional argument for the raised error.
from scratchcloud import CloudClient, CloudChange
client = CloudClient(username='yuwe', project_id='622084628')
@client.event
async def on_connect():
print('Hello world!')
@client.event
async def on_disconnect():
print('Goodbye world!')
@client.cloud_event('REQUEST')
async def on_request(var: CloudChange):
print(f'The REQUEST variable was changed to {var.value}!')
if var.value == '0': # Raise an error whenever we get 0!
raise ValueError('Zeros are bad!')
await client.set_cloud('RESPONSE', '200')
@client.cloud_event_error('REQUEST')
async def on_request_error(var: CloudChange, error: Exception):
if isinstance(error, ValueError):
await client.set_cloud('RESPONSE', '400') # Set the response to 400 if something goes wrong!
else:
raise error
client.run('Your Password Here!')
In this example, whenever we receieve the number 0, an exception is raised. After the exception is raised, it’s caught by the @client.cloud_event_error
function, and handled appropriately through Python’s isinstance
function.