# scratchcommunication
A python module for communicating with scratch projects
# Installation
Run this in your commandline
```
pip install scratchcommunication
```
OR
Add this at the top of your python script
```python
import subprocess
subprocess.run("pip install --upgrade scratchcommunication", shell=True, capture_output=True)
```
# Creating a session
You can use the `scratchcommunication.session.Session` class to log into your account.
For this, you either need a session id or a password.
## Login using session id
```python
import scratchcommunication
session = scratchcommunication.Session("YOUR_USERNAME", session_id="YOUR_SESSIONID")
# You can also supply your XToken if it cannot be found using xtoken="YOUR_XTOKEN
```
If you log in using your session id, you may not need your to supply your username.
## Login using password
```python
import scratchcommunication
session = scratchcommunication.Session.login("YOUR_USERNAME", "YOUR_PASSWORD")
```
I recommend using your session id instead of your password.
## Login from browser
This will login using cookies from your browser. It only works if you have that browser installed and if you are logged in.
```python
import scratchcommunication
session = scratchcommunication.Session.from_browser(scratchcommunication.ANY)
```
You can choose from these browsers:
`FIREFOX`
`CHROME`
`EDGE`
`SAFARI`
`CHROMIUM`
`EDGE_DEV`
`VIVALDI`
`ANY`
## Access account data
Once you have logged into your account, you can access your account data.
```python
your_session_id = session.session_id
your_username = session.username
email = session.email
user_id = session.id
banned = session.banned
new_scratcher = session.new_scratcher
mute_status = session.mute_status
```
# Cloud Variables
## Connecting to Scratch Cloud Variables
You can connect to a scratch projects cloud variables using your `scratchcommunication.session.Session`
```python
cloud = session.create_cloudconnection(
project_id = "Your project id here",
quickaccess = False, # (Optional) Allows you to use the cloud connection as a Mapping for the cloud variables.
reconnect = True, # (Optional) Allows the cloud connection to reconnect if it disconnects.
receive_from_websocket = True, # (Optional) Creates a thread which receives cloud updates and allows for events.
warning_type = ErrorInEventHandler, # (Optional) Determines what type of Warning will be used if there is an error in the event handler.
daemon_thread = False # (Optional) Determines if the thread used for events will be daemon
)
```
OR
```python
cloud = scratchcommunication.CloudConnection(
project_id = "Your project id here",
session = session,
**kwargs
)
```
## Connecting to Turbowarp Cloud Variables
To connect to Turbowarps Cloud Variables you can use the `scratchcommunication.cloud.TwCloudConnection` class
```python
tw_cloud = scratchcommunication.TwCloudConnection(
contact_info = "Your contact info", # Specify some contact info. Turbowarp will block your connection otherwise.
project_id = "Your project id here",
username = "player1000", # (Optional)
quickaccess = False,
reconnect = True,
receive_from_websocket = True,
warning_type = ErrorInEventHandler,
cloud_host = "wss://clouddata.turbowarp.org/", # (Optional) Changes the host used for cloud variables.
accept_strs = False, # (Optional) Allows you to set cloud variables to strings. Only works if cloud host allows it.
keep_all_events = False # (Optional) Allows you to disable automatic garbage disposal of events. Events can still be manually disposed of. Unrecommended because it will slowly but surely fill up a lot of memory if events aren't disposed of.
)
```
Or you could connect from your session
```python
tw_cloud = session.create_turbowarp_cloudconnection( # You can replace "turbowarp" with "tw" to shorten your code if you like
contact_info = "Your contact info",
project_id = "Your project id here",
username = None, # (Optional) Will default to your username
quickaccess = False,
reconnect = True,
receive_from_websocket = True,
warning_type = ErrorInEventHandler,
cloud_host = "wss://clouddata.turbowarp.org/",
accept_strs = False,
keep_all_events = False,
allow_no_certificate = False # (Optional) Put to True if the SSL Certificate fails.
)
```
**Warning: You need to add sufficient contact_info for your turbowarp connection or it might not work!**
To shorten it a bit you can also use `scratchcommunication.session.Session.create_tw_cloudconnection` instead of `scratchcommunication.session.Session.create_turbowarp_cloudconnection`.
## Multiple cloud connections in one
To combine multiple cloud connections into a single one (e.g. for cloud requests on turbowarp and scratch or multiple project ids) you can use a **"Sky"** (`scratchcommunication.cloud.Sky`).
Example code:
```python
cloud_1 = session.create_cloudconnection(project_id="Main project id")
cloud_2 = session.create_tw_cloudconnection(project_id="Main project id")
cloud_3 = session.create_cloudconnection(project_id="Test project id")
cloudy_sky = scratchcommunication.Sky(cloud_1, cloud_2, cloud_3)
```
## Working with cloud variables
To set or get cloud variables you can use `scratchcommunication.cloud.CloudConnection.set_variable` and `scratchcommunication.cloud.CloudConnection.get_variable`.
```python
cloud.set_variable(
name = "HIGHSCORE", # A cloud symbol will be added automatically if there isn't one
value = 1000,
name_literal = False # (Optional) Allows for setting a variable with a name without a cloud symbol
)
value = cloud.get_variable(
name = "HIGHSCORE",
name_literal = False
)
```
Or if you enabled quickaccess you can use the object like a Mapping.
```python
cloud["HIGHSCORE"] = 1000
value = cloud["HIGHSCORE"]
```
For cloud events you can use the decorator `scratchcommunication.cloud.CloudConnection.on`
```python
@cloud.on("set") # Can be "set", "create", "delete", "connect" or "any"
def on_set(event):
print(
event.project_id,
event.name, # Variable name without cloud symbol
event.var, # Variable name
event.value,
event.type, # Event type
event.project, # Cloud connection
event.user,
event.timestamp
)
```
And if you want, you can also emit events yourself. (Those events will not be broadcast.)
```python
cloud.emit_event(event="custom_event_1", **entries)
# Or
cloud.emit_event(event=scratchcommunication.Event(type="custom_event_1", **entries))
```
And if you want to enable or disable quickaccess after you already created the connection, you can use `scratchcommunication.cloud.CloudConnection.enable_quickaccess` and `scratchcommunication.cloud.CloudConnection.disable_quickaccess`
```python
cloud.enable_quickaccess()
cloud.disable_quickaccess()
```
If you want to stop the background thread used for events and variable updates, you can use `scratchcommunication.cloud.CloudConnection.stop_thread`
```python
cloud.stop_thread()
```
You can also manually dispose of events (which normally happens automatically).
```python
cloud.garbage_disposal_of_events(
force_disposal = False # (Optional) Is needed to be True if automatic garbage disposal is disabled.
)
```
If you set `daemon_thread` to `True` when creating the object, the background thread will terminate when your process ends.
# Cloud requests
Cloud requests are based on [cloud sockets](#cloud-sockets) and allow you to have your project send requests to your server which it automatically responds to. You'll need to put the first sprite from this [project](https://scratch.mit.edu/projects/884190099/) in your project for cloud requests to work.
## Creating a cloud requests handler
To use cloud requests, you first need to create a [cloud socket](#cloud-sockets) to your project and then a cloud requests handler which uses it to communicate to your Scratch project.
```python
cloud_requests = scratchcommunication.RequestHandler(
cloud_socket = cloud_socket, # The cloud socket to communicate with the project
uses_thread = False # (Optional) Determines if the cloud requests handler uses a thread for execution normally.
)
```
## Create requests
You can use the method `add_request` to add a request or the `request` wrapper.
```python
cloud_requests.add_request(
your_function, # Replace this with the function you want to use.
name = None, # (Optional) Change the name of the function.
auto_convert = False, # (Optional) Whether to automatically convert all arguments and return values related to the request based on its type annotations
allow_python_syntax = True, # (Optional) Whether to allow the frontend requests in python syntax (e.g. func(arg1, arg2, kwarg1=val1, kwarg2=val2, ...)). This has no backsides.
thread = False # (Optional) Determines if the request's function and response should be in a different thread. This might cost a lot of processing power.
)
# OR
@cloud_requests.request
def func(arg1, arg2):
pass # Write your own function
# OR
@cloud_requests.request(name=None, auto_convert=False, allow_python_syntax=True, thread=False)
def func(arg1, arg2):
pass # Write your own function
```
## Starting the cloud requests handler
Start the cloud requests handler using the `start` method.
```python
cloud_requests.start(
thread = None, # (Optional) Whether to use a thread; If None then it defaults to the used_thread value used at creation of the cloud requests handler
daemon_thread = False, # (Optional) Whether the thread is daemon
duration = None # (Optional) How long to run the cloud requests
)
```
## Stopping the cloud requests handler
Stop the cloud requests handler using the `stop` method. (Only if the cloud requests handler is running in a thread)
```python
cloud_requests.stop()
```
## Encrypted data transmission
For making the data transmission in your cloud request handler secret, you need to make the underlying cloud socket secure.
See [Cloud Socket Security](#cloud-socket-security) for this.
## Client side
If you haven't already, you'll need to put the first sprite from this [project](https://scratch.mit.edu/projects/884190099/) in your project for cloud requests to work.
You'll always first need to connect on your client side for your messages to work. This is done using the "[cloud socket] connect securely" or "[cloud socket] connect insecurely" blocks.
When you are connected, you can use the block "[cloud requests] initiate new request (%s)" to initiate a new request with its name. The name must not contain spaces. When you have initiated a new request, you can add arguments to the request by using the "[cloud requests] add argument (%s)" block. When you are done creating the request, you can use the block "[cloud requests] send iniated request" to send it and wait for the response.
The received data will be in the variable "[cloud] reception". You can change the timeout using the "# TIMEOUT" variable (If you don't need a timeout, just let it stay). You can also change the packet size using the "# PACKET SIZE" variable, but I would advise against this if you are not using turbowarp.
# Cloud sockets
Cloud sockets (inspired by sockets) are connections from a scratch project to a python program where both sides can send data to one another and there is even the possibility to add security to the connection using RSA.
Warning: Cloud sockets are low level. They allow you to do more but are more difficult to use. You shouldn't use them directly. You might want to use them in [cloud requests](#cloud-requests) instead.
## Creating a cloud socket
To create a cloud socket you can use `scratchcommunication.session.Session.create_cloud_socket`.
```python
cloud_socket = session.create_cloud_socket(
project_id = "Your project id here",
packet_size = "AUTO", # (Optional) I recommend leaving this value be if you only use Scratch and Turbowarp.
cloudconnection_kwargs = None, # (Optional) Allows for adding keyword arguments for the Cloud Connection used in the cloud socket. Look at the documentation for Cloud Connection if you do not know which keyword arguments there are
security = None, # (Optional) Allows for a secure connection. Recommended. Look at Cloud Socket Security for more info.
allow_no_certificate = False # (Optional) Put to True if the SSL Certificate fails.
)
```
You can also use Turbowarp for cloud sockets.
```python
cloud_socket = session.create_turbowarp_cloud_socket( # session.create_tw_cloud_socket also works here
contact_info = "Your contact info",
project_id = "Your project id here",
packet_size = "AUTO", # (Optional) I recommend leaving this value be if you only use Scratch and Turbowarp.
cloudconnection_kwargs = None, # (Optional) Allows for adding keyword arguments for the Cloud Connection used in the cloud socket. Look at the documentation for Cloud Connection if you do not know which keyword arguments there are
security = None, # (Optional) Allows for a secure connection. Recommended. Look at Cloud Socket Security for more info.
allow_no_certificate = False
)
```
You can also create a cloud socket from any cloud connection. This is useful if you want to use a [Sky](#multiple-cloud-connections-in-one) for your cloud socket.
```python
cloud_connection = ... # Your code to create your cloud connection here
cloud_socket = scratchcommunication.CloudSocket(cloud=cloud_connection)
```
[Cloud Socket Security](#cloud-socket-security)
In order for the cloud socket to work, you'll need to add the sprite from this [project](https://scratch.mit.edu/projects/884190099/) to yours. Be sure to check that all the variables starting with the cloud symbol are cloud variables and that their names stay as they are.
## Using a cloud socket
Once you have created a cloud socket you have to start it using `scratchcommunication.cloud_socket.CloudSocket.listen` and you can also put it in a with statement, which makes the cloud socket shut down automatically when the code is done executing.
```python
cloud_socket.listen()
# OR
with cloud_socket.listen():
... # Your code here
```
After you start the cloud socket you can wait for a new user using `scratchcommunication.cloud_socket.CloudSocket.accept`
```python
client, client_username = cloud_socket.accept(
timeout = 10 # (Optional)
)
```
When you have a client, you can send messages to them and receive messages.
```python
msg = client.recv(
timeout = 10 # (Optional)
)
client.send("Hello!")
```
**Your messages will be public and easy to fake in both direction unless you activate [security](#cloud-socket-security).**
In order to stop the cloud socket from running anymore you can use `scratchcommunication.cloud_socket.CloudSocket.stop`
```python
cloud_socket.stop()
```
## Client side
If you haven't already, you'll need to put the first sprite from this [project](https://scratch.mit.edu/projects/884190099/) in your project for cloud socket to work.
You'll always first need to connect on your client side for your messages to work. This is done using the "[cloud socket] connect securely" or "[cloud socket] connect insecurely" blocks.
Afterwards, you can use the "[cloud socket] send (%s)" block and the "[cloud socket] recv" block.
The received data will be in the variable "[cloud] reception". You can change the timeout using the "# TIMEOUT" variable (If you don't need a timeout, just let it stay). You can also change the packet size using the "# PACKET SIZE" variable, but I would advise against this if you are not using turbowarp.
## Cloud Socket Security
You might want to be able to send private data that only the designated recipient can read, but that is impossible unless you use asymmetric encryption or something similar. Fortunately for you, the hard work has already been done.
You will need to generate a Security object for this. In order to do that, you can just use `scratchcommunication.security.Security.generate`.
```python
security = scratchcommunication.security.Security.generate()
```
After you have generated your keys, you will want to store and load them. For storing your keys, you need to use `scratchcommunication.security.Security.to_string` to find the data to store.
```python
string_representation_of_security = security.to_string()
print(string_representation_of_security)
```
When you have stored the string displayed, you just need to load it whenever you start your cloud socket using some code similar to this:
```python
security = scratchcommunication.security.Security.from_string(string_representation_of_security)
```
Next, you need to look at `security.public_data`.
```python
print(security.public_data)
```
It will be a dictionary with the keys being variable names and the values being the value you need to set them to in your project.
To use the security object in your cloud socket, you just need to pass it in as `security`.
```python
secure_cloud_socket = session.create_cloud_socket(
project_id = "Your project id here",
security = security
)
```
### Important security notice
**NEVER** make the string representation of the security or any other data relating to the security public except for the aforementioned public data, because making any of the secret data public will make all transmission insecure again.
# Contact
If you have questions, want to propose new features or have found a bug, contact me [here](https://github.com/thecommcraft/scratchcommunication/issues)
# Credits
A lot of frontend cryptography by @Retr0id on Scratch (https://scratch.mit.edu/users/Retr0id)
Inspiration and possibly (I'm not sure) a few code snippets by @TimMcCool
Everything else by me (I think)
# More coming soon
Raw data
{
"_id": null,
"home_page": "https://github.com/thecommcraft/scratchcommunication",
"name": "scratchcommunication",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "scratch, api",
"author": "Simon Gilde",
"author_email": "simon.c.gilde@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/d5/7b/bae45e35aedb272eb4addc6851b2d14824f3e361b01e53a697c6a6a1dbfb/scratchcommunication-2.15.2.tar.gz",
"platform": null,
"description": "# scratchcommunication\nA python module for communicating with scratch projects\n\n# Installation\n\nRun this in your commandline\n\n```\npip install scratchcommunication\n```\n\nOR\n\nAdd this at the top of your python script\n\n```python\nimport subprocess\nsubprocess.run(\"pip install --upgrade scratchcommunication\", shell=True, capture_output=True)\n```\n\n# Creating a session\n\nYou can use the `scratchcommunication.session.Session` class to log into your account.\n\nFor this, you either need a session id or a password.\n\n## Login using session id\n\n```python\nimport scratchcommunication\nsession = scratchcommunication.Session(\"YOUR_USERNAME\", session_id=\"YOUR_SESSIONID\")\n# You can also supply your XToken if it cannot be found using xtoken=\"YOUR_XTOKEN\n```\n\nIf you log in using your session id, you may not need your to supply your username.\n\n## Login using password\n\n```python\nimport scratchcommunication\nsession = scratchcommunication.Session.login(\"YOUR_USERNAME\", \"YOUR_PASSWORD\")\n```\n\nI recommend using your session id instead of your password. \n\n## Login from browser\n\nThis will login using cookies from your browser. It only works if you have that browser installed and if you are logged in.\n\n```python\nimport scratchcommunication\nsession = scratchcommunication.Session.from_browser(scratchcommunication.ANY)\n```\n\nYou can choose from these browsers:\n\n`FIREFOX`\n`CHROME`\n`EDGE`\n`SAFARI`\n`CHROMIUM`\n`EDGE_DEV`\n`VIVALDI`\n`ANY`\n\n## Access account data\n\nOnce you have logged into your account, you can access your account data.\n\n```python\nyour_session_id = session.session_id\nyour_username = session.username\nemail = session.email\nuser_id = session.id\nbanned = session.banned\nnew_scratcher = session.new_scratcher\nmute_status = session.mute_status\n```\n\n# Cloud Variables\n\n## Connecting to Scratch Cloud Variables\n\nYou can connect to a scratch projects cloud variables using your `scratchcommunication.session.Session`\n\n```python\ncloud = session.create_cloudconnection(\n project_id = \"Your project id here\",\n quickaccess = False, # (Optional) Allows you to use the cloud connection as a Mapping for the cloud variables.\n reconnect = True, # (Optional) Allows the cloud connection to reconnect if it disconnects.\n receive_from_websocket = True, # (Optional) Creates a thread which receives cloud updates and allows for events.\n warning_type = ErrorInEventHandler, # (Optional) Determines what type of Warning will be used if there is an error in the event handler.\n daemon_thread = False # (Optional) Determines if the thread used for events will be daemon\n)\n```\n\nOR\n\n```python\ncloud = scratchcommunication.CloudConnection(\n project_id = \"Your project id here\",\n session = session,\n **kwargs\n)\n```\n\n## Connecting to Turbowarp Cloud Variables\n\nTo connect to Turbowarps Cloud Variables you can use the `scratchcommunication.cloud.TwCloudConnection` class\n\n```python\ntw_cloud = scratchcommunication.TwCloudConnection(\n contact_info = \"Your contact info\", # Specify some contact info. Turbowarp will block your connection otherwise.\n project_id = \"Your project id here\", \n username = \"player1000\", # (Optional)\n quickaccess = False, \n reconnect = True, \n receive_from_websocket = True, \n warning_type = ErrorInEventHandler, \n cloud_host = \"wss://clouddata.turbowarp.org/\", # (Optional) Changes the host used for cloud variables.\n accept_strs = False, # (Optional) Allows you to set cloud variables to strings. Only works if cloud host allows it.\n keep_all_events = False # (Optional) Allows you to disable automatic garbage disposal of events. Events can still be manually disposed of. Unrecommended because it will slowly but surely fill up a lot of memory if events aren't disposed of.\n)\n```\n\nOr you could connect from your session\n\n```python\ntw_cloud = session.create_turbowarp_cloudconnection( # You can replace \"turbowarp\" with \"tw\" to shorten your code if you like\n contact_info = \"Your contact info\",\n project_id = \"Your project id here\",\n username = None, # (Optional) Will default to your username\n quickaccess = False, \n reconnect = True, \n receive_from_websocket = True, \n warning_type = ErrorInEventHandler, \n cloud_host = \"wss://clouddata.turbowarp.org/\", \n accept_strs = False,\n keep_all_events = False,\n allow_no_certificate = False # (Optional) Put to True if the SSL Certificate fails.\n)\n```\n\n**Warning: You need to add sufficient contact_info for your turbowarp connection or it might not work!**\n\nTo shorten it a bit you can also use `scratchcommunication.session.Session.create_tw_cloudconnection` instead of `scratchcommunication.session.Session.create_turbowarp_cloudconnection`.\n\n## Multiple cloud connections in one\n\nTo combine multiple cloud connections into a single one (e.g. for cloud requests on turbowarp and scratch or multiple project ids) you can use a **\"Sky\"** (`scratchcommunication.cloud.Sky`).\n\nExample code:\n\n```python\ncloud_1 = session.create_cloudconnection(project_id=\"Main project id\")\ncloud_2 = session.create_tw_cloudconnection(project_id=\"Main project id\")\ncloud_3 = session.create_cloudconnection(project_id=\"Test project id\")\ncloudy_sky = scratchcommunication.Sky(cloud_1, cloud_2, cloud_3)\n```\n\n## Working with cloud variables\n\nTo set or get cloud variables you can use `scratchcommunication.cloud.CloudConnection.set_variable` and `scratchcommunication.cloud.CloudConnection.get_variable`.\n\n```python\ncloud.set_variable(\n name = \"HIGHSCORE\", # A cloud symbol will be added automatically if there isn't one\n value = 1000,\n name_literal = False # (Optional) Allows for setting a variable with a name without a cloud symbol\n)\nvalue = cloud.get_variable(\n name = \"HIGHSCORE\", \n name_literal = False\n)\n```\n\nOr if you enabled quickaccess you can use the object like a Mapping.\n\n```python\ncloud[\"HIGHSCORE\"] = 1000\n\nvalue = cloud[\"HIGHSCORE\"]\n```\n\nFor cloud events you can use the decorator `scratchcommunication.cloud.CloudConnection.on`\n\n```python\n@cloud.on(\"set\") # Can be \"set\", \"create\", \"delete\", \"connect\" or \"any\"\ndef on_set(event):\n print(\n event.project_id, \n event.name, # Variable name without cloud symbol\n event.var, # Variable name\n event.value, \n event.type, # Event type\n event.project, # Cloud connection\n event.user,\n event.timestamp\n )\n```\n\nAnd if you want, you can also emit events yourself. (Those events will not be broadcast.)\n\n```python\ncloud.emit_event(event=\"custom_event_1\", **entries)\n# Or\ncloud.emit_event(event=scratchcommunication.Event(type=\"custom_event_1\", **entries))\n```\n\nAnd if you want to enable or disable quickaccess after you already created the connection, you can use `scratchcommunication.cloud.CloudConnection.enable_quickaccess` and `scratchcommunication.cloud.CloudConnection.disable_quickaccess`\n\n```python\ncloud.enable_quickaccess()\ncloud.disable_quickaccess()\n```\n\nIf you want to stop the background thread used for events and variable updates, you can use `scratchcommunication.cloud.CloudConnection.stop_thread`\n\n```python\ncloud.stop_thread()\n```\n\nYou can also manually dispose of events (which normally happens automatically).\n\n```python\ncloud.garbage_disposal_of_events(\n force_disposal = False # (Optional) Is needed to be True if automatic garbage disposal is disabled.\n)\n```\n\nIf you set `daemon_thread` to `True` when creating the object, the background thread will terminate when your process ends.\n\n# Cloud requests\n\nCloud requests are based on [cloud sockets](#cloud-sockets) and allow you to have your project send requests to your server which it automatically responds to. You'll need to put the first sprite from this [project](https://scratch.mit.edu/projects/884190099/) in your project for cloud requests to work.\n\n## Creating a cloud requests handler\n\nTo use cloud requests, you first need to create a [cloud socket](#cloud-sockets) to your project and then a cloud requests handler which uses it to communicate to your Scratch project.\n\n```python\ncloud_requests = scratchcommunication.RequestHandler(\n cloud_socket = cloud_socket, # The cloud socket to communicate with the project\n uses_thread = False # (Optional) Determines if the cloud requests handler uses a thread for execution normally.\n)\n```\n\n## Create requests\n\nYou can use the method `add_request` to add a request or the `request` wrapper.\n\n```python\ncloud_requests.add_request(\n your_function, # Replace this with the function you want to use.\n name = None, # (Optional) Change the name of the function.\n auto_convert = False, # (Optional) Whether to automatically convert all arguments and return values related to the request based on its type annotations\n allow_python_syntax = True, # (Optional) Whether to allow the frontend requests in python syntax (e.g. func(arg1, arg2, kwarg1=val1, kwarg2=val2, ...)). This has no backsides.\n thread = False # (Optional) Determines if the request's function and response should be in a different thread. This might cost a lot of processing power. \n)\n\n# OR\n\n@cloud_requests.request\ndef func(arg1, arg2):\n pass # Write your own function\n\n# OR\n\n@cloud_requests.request(name=None, auto_convert=False, allow_python_syntax=True, thread=False)\ndef func(arg1, arg2):\n pass # Write your own function\n```\n\n## Starting the cloud requests handler\n\nStart the cloud requests handler using the `start` method.\n\n```python\ncloud_requests.start(\n thread = None, # (Optional) Whether to use a thread; If None then it defaults to the used_thread value used at creation of the cloud requests handler\n daemon_thread = False, # (Optional) Whether the thread is daemon\n duration = None # (Optional) How long to run the cloud requests\n)\n```\n\n## Stopping the cloud requests handler\n\nStop the cloud requests handler using the `stop` method. (Only if the cloud requests handler is running in a thread)\n\n```python\ncloud_requests.stop()\n```\n\n## Encrypted data transmission\n\nFor making the data transmission in your cloud request handler secret, you need to make the underlying cloud socket secure.\n\nSee [Cloud Socket Security](#cloud-socket-security) for this.\n\n## Client side\n\nIf you haven't already, you'll need to put the first sprite from this [project](https://scratch.mit.edu/projects/884190099/) in your project for cloud requests to work.\n\nYou'll always first need to connect on your client side for your messages to work. This is done using the \"[cloud socket] connect securely\" or \"[cloud socket] connect insecurely\" blocks. \n\nWhen you are connected, you can use the block \"[cloud requests] initiate new request (%s)\" to initiate a new request with its name. The name must not contain spaces. When you have initiated a new request, you can add arguments to the request by using the \"[cloud requests] add argument (%s)\" block. When you are done creating the request, you can use the block \"[cloud requests] send iniated request\" to send it and wait for the response.\n\nThe received data will be in the variable \"[cloud] reception\". You can change the timeout using the \"# TIMEOUT\" variable (If you don't need a timeout, just let it stay). You can also change the packet size using the \"# PACKET SIZE\" variable, but I would advise against this if you are not using turbowarp.\n\n# Cloud sockets\n\nCloud sockets (inspired by sockets) are connections from a scratch project to a python program where both sides can send data to one another and there is even the possibility to add security to the connection using RSA.\n\nWarning: Cloud sockets are low level. They allow you to do more but are more difficult to use. You shouldn't use them directly. You might want to use them in [cloud requests](#cloud-requests) instead.\n\n## Creating a cloud socket\n\nTo create a cloud socket you can use `scratchcommunication.session.Session.create_cloud_socket`.\n\n```python\ncloud_socket = session.create_cloud_socket(\n project_id = \"Your project id here\",\n packet_size = \"AUTO\", # (Optional) I recommend leaving this value be if you only use Scratch and Turbowarp.\n cloudconnection_kwargs = None, # (Optional) Allows for adding keyword arguments for the Cloud Connection used in the cloud socket. Look at the documentation for Cloud Connection if you do not know which keyword arguments there are\n security = None, # (Optional) Allows for a secure connection. Recommended. Look at Cloud Socket Security for more info.\n allow_no_certificate = False # (Optional) Put to True if the SSL Certificate fails.\n)\n```\n\nYou can also use Turbowarp for cloud sockets.\n\n```python\ncloud_socket = session.create_turbowarp_cloud_socket( # session.create_tw_cloud_socket also works here\n contact_info = \"Your contact info\",\n project_id = \"Your project id here\",\n packet_size = \"AUTO\", # (Optional) I recommend leaving this value be if you only use Scratch and Turbowarp.\n cloudconnection_kwargs = None, # (Optional) Allows for adding keyword arguments for the Cloud Connection used in the cloud socket. Look at the documentation for Cloud Connection if you do not know which keyword arguments there are\n security = None, # (Optional) Allows for a secure connection. Recommended. Look at Cloud Socket Security for more info.\n allow_no_certificate = False\n)\n```\n\nYou can also create a cloud socket from any cloud connection. This is useful if you want to use a [Sky](#multiple-cloud-connections-in-one) for your cloud socket.\n\n```python\ncloud_connection = ... # Your code to create your cloud connection here\ncloud_socket = scratchcommunication.CloudSocket(cloud=cloud_connection)\n```\n\n[Cloud Socket Security](#cloud-socket-security)\n\nIn order for the cloud socket to work, you'll need to add the sprite from this [project](https://scratch.mit.edu/projects/884190099/) to yours. Be sure to check that all the variables starting with the cloud symbol are cloud variables and that their names stay as they are.\n\n## Using a cloud socket\n\nOnce you have created a cloud socket you have to start it using `scratchcommunication.cloud_socket.CloudSocket.listen` and you can also put it in a with statement, which makes the cloud socket shut down automatically when the code is done executing.\n\n```python\ncloud_socket.listen()\n\n# OR\n\nwith cloud_socket.listen():\n ... # Your code here\n```\n\n\n\nAfter you start the cloud socket you can wait for a new user using `scratchcommunication.cloud_socket.CloudSocket.accept`\n\n```python\nclient, client_username = cloud_socket.accept(\n timeout = 10 # (Optional) \n)\n```\n\nWhen you have a client, you can send messages to them and receive messages.\n\n```python\nmsg = client.recv(\n timeout = 10 # (Optional)\n)\nclient.send(\"Hello!\")\n```\n\n**Your messages will be public and easy to fake in both direction unless you activate [security](#cloud-socket-security).**\n\nIn order to stop the cloud socket from running anymore you can use `scratchcommunication.cloud_socket.CloudSocket.stop`\n\n```python\ncloud_socket.stop()\n```\n\n## Client side\n\nIf you haven't already, you'll need to put the first sprite from this [project](https://scratch.mit.edu/projects/884190099/) in your project for cloud socket to work.\n\nYou'll always first need to connect on your client side for your messages to work. This is done using the \"[cloud socket] connect securely\" or \"[cloud socket] connect insecurely\" blocks. \n\nAfterwards, you can use the \"[cloud socket] send (%s)\" block and the \"[cloud socket] recv\" block. \n\nThe received data will be in the variable \"[cloud] reception\". You can change the timeout using the \"# TIMEOUT\" variable (If you don't need a timeout, just let it stay). You can also change the packet size using the \"# PACKET SIZE\" variable, but I would advise against this if you are not using turbowarp.\n\n## Cloud Socket Security\n\nYou might want to be able to send private data that only the designated recipient can read, but that is impossible unless you use asymmetric encryption or something similar. Fortunately for you, the hard work has already been done.\n\nYou will need to generate a Security object for this. In order to do that, you can just use `scratchcommunication.security.Security.generate`.\n\n```python\nsecurity = scratchcommunication.security.Security.generate()\n```\n\nAfter you have generated your keys, you will want to store and load them. For storing your keys, you need to use `scratchcommunication.security.Security.to_string` to find the data to store.\n\n```python\nstring_representation_of_security = security.to_string()\nprint(string_representation_of_security)\n```\n\nWhen you have stored the string displayed, you just need to load it whenever you start your cloud socket using some code similar to this:\n\n```python\nsecurity = scratchcommunication.security.Security.from_string(string_representation_of_security)\n```\n\nNext, you need to look at `security.public_data`. \n\n```python\nprint(security.public_data)\n```\n\nIt will be a dictionary with the keys being variable names and the values being the value you need to set them to in your project.\n\nTo use the security object in your cloud socket, you just need to pass it in as `security`.\n\n```python\nsecure_cloud_socket = session.create_cloud_socket(\n project_id = \"Your project id here\", \n security = security\n)\n```\n\n### Important security notice\n\n**NEVER** make the string representation of the security or any other data relating to the security public except for the aforementioned public data, because making any of the secret data public will make all transmission insecure again.\n\n# Contact\n\nIf you have questions, want to propose new features or have found a bug, contact me [here](https://github.com/thecommcraft/scratchcommunication/issues)\n\n# Credits\n\nA lot of frontend cryptography by @Retr0id on Scratch (https://scratch.mit.edu/users/Retr0id)\n\nInspiration and possibly (I'm not sure) a few code snippets by @TimMcCool\n\nEverything else by me (I think)\n\n# More coming soon\n",
"bugtrack_url": null,
"license": null,
"summary": "A python module for communicating with scratch projects",
"version": "2.15.2",
"project_urls": {
"Homepage": "https://github.com/thecommcraft/scratchcommunication"
},
"split_keywords": [
"scratch",
" api"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6e294d72daba84bc025d35e5abe90de90f8a0b91b445701e34756d718510e838",
"md5": "72bad48e2ce3784b79e00d42e7b3c9a0",
"sha256": "bd618a27aee167281578e28c925b7d16f5113cf693d6c89f735a95732cfa376d"
},
"downloads": -1,
"filename": "scratchcommunication-2.15.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "72bad48e2ce3784b79e00d42e7b3c9a0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 30151,
"upload_time": "2024-10-28T18:37:00",
"upload_time_iso_8601": "2024-10-28T18:37:00.750468Z",
"url": "https://files.pythonhosted.org/packages/6e/29/4d72daba84bc025d35e5abe90de90f8a0b91b445701e34756d718510e838/scratchcommunication-2.15.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d57bbae45e35aedb272eb4addc6851b2d14824f3e361b01e53a697c6a6a1dbfb",
"md5": "e2e5f9099747d558c2f0d1068a5df70b",
"sha256": "7d42ece65946a977846f59518709d23a98da05973d0557d3a6123be5c0440616"
},
"downloads": -1,
"filename": "scratchcommunication-2.15.2.tar.gz",
"has_sig": false,
"md5_digest": "e2e5f9099747d558c2f0d1068a5df70b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 32011,
"upload_time": "2024-10-28T18:37:02",
"upload_time_iso_8601": "2024-10-28T18:37:02.281430Z",
"url": "https://files.pythonhosted.org/packages/d5/7b/bae45e35aedb272eb4addc6851b2d14824f3e361b01e53a697c6a6a1dbfb/scratchcommunication-2.15.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-28 18:37:02",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "thecommcraft",
"github_project": "scratchcommunication",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "scratchcommunication"
}