Discuss Scratch

ajsya
Scratcher
1000+ posts

scratchcloud ☁️ async python library for cloud variables

So I'm getting an error when starting my program if I don't change the cloud variable in the first few seconds of the program starting up even though the project does have cloud data.

My program:
from scratchcloud import CloudClient, CloudChange
import os, time, json
from mcstatus import JavaServer
from dotenv import load_dotenv
from random import randint
#get .env passcodes
load_dotenv()
username = os.environ['USERNAME']
password = os.environ['PASSWORD']
client = CloudClient(username=username, project_id='684696037')
@client.event
async def on_connect():
  print('Project connected.')
@client.event
async def on_disconnect():
  print('Project disconnected!')
@client.cloud_event('request')
async def on_request(var: CloudChange):
  print(f'The request variable was changed to {var.value}!')
client.run(password)

the error:
Traceback (most recent call last):
File "/home/ubuntu/Coding Files/Python Files/ScratchMCServerDirectory/main2-scratchcloud.py", line 29, in <module>
client.run(password)
File "/home/ubuntu/Coding Files/Python Files/ScratchMCServerDirectory/env/lib/python3.8/site-packages/scratchcloud/client.py", line 211, in run
raise e
File "/home/ubuntu/Coding Files/Python Files/ScratchMCServerDirectory/env/lib/python3.8/site-packages/scratchcloud/client.py", line 175, in run
loop.run_until_complete(self.start(token))
File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
return future.result()
File "/home/ubuntu/Coding Files/Python Files/ScratchMCServerDirectory/env/lib/python3.8/site-packages/scratchcloud/client.py", line 232, in start
await self.ws_handshake()
File "/home/ubuntu/Coding Files/Python Files/ScratchMCServerDirectory/env/lib/python3.8/site-packages/scratchcloud/client.py", line 343, in ws_handshake
raise MissingCloudVariable('No Cloud Variables Found!')
scratchcloud.errors.MissingCloudVariable: No Cloud Variables Found!

Hi, I'm ajsya!

Owner of several dead shops, Notable Chair, Scratch Wiki Editor, Developer, and Gamer.

| Roblox | GitHub | Wiki | My Posts | Scratch Empires | Scratch Weather App | Minecraft Server Pinger |

Before creating a new topic on the forums search Ocular to see if one already exists!

SansStudios
Scratcher
500+ posts

scratchcloud ☁️ async python library for cloud variables

ajsya wrote:

So I'm getting an error when starting my program if I don't change the cloud variable in the first few seconds of the program starting up even though the project does have cloud data.

[code / errors hidden]

Thanks for trying out my library! Your project is super interesting, and I think that it reflects a bug in scratch's servers that scratchcloud currently can't handle (i'll add a workaround very soon ). Whenever you connect to any scratch project, you have to send a “handshake” to let it know that you want to connect and that you have a scratch account. Scratch, in turn, sends it's own data to you, letting you know what variables are in the project you're connecting to. The data looks something like this:

{"method":"handshake","user":"SansStudios","project_id":"622084628"}
What you send to scratch

{"method":"set","project_id":"622084628","name":"☁ REQUEST","value":"11182912241823"}
{"method":"set","project_id":"622084628","name":"☁ RESPONSE","value":"111829122418234612242829284660384140394055"}

What scratch is supposed to send back (Project from this example)

However, for whatever reason, some projects don't send back this response, yours being one of them. These projects have “phantom” cloud variables, and sometimes, even the scratch web client doesn't recognize them. Since scratchcloud is built to raise errors when it connects to a project without cloud variables, it does not take projects with “phantom” cloud variables into account.

I'll add a way to bypass missing cloud variables on my side, but if you really really want to use scratchcloud now, you can delete all of your cloud variables and recreate them. This almost always solves the problem.

Last edited by SansStudios (May 15, 2022 02:42:27)


scratchcloud
Click above to check it out! I've worked on it for over a year!























Just like sudden sadness comes hangin' on the breeze
SansStudios
Scratcher
500+ posts

scratchcloud ☁️ async python library for cloud variables

I released 1.2.0 yesterday. Lots of internals were changed, so if anyone is running the manually client without `CloudClient.run()`, you're going to have to change that. However, for almost all users, this shouldn't be an issue. Also, I finally added rate limiting woohoo and each time a cloud variable is set, it will be internally queued.

You can now connect to projects that don't return a proper handshake, although this may cause bugs in the library:

client = CloudClient(username='user', project_id='123', ignore_missing_variables=True)

Here is the change log from gh:

Breaking Changes

Changed CloudClient.connected to CloudClient.client_setup
Changed method CloudClient.start() to CloudClient.setup()
CloudClient.setup() no longer starts the cloud client's main loop.
CloudClient.setup() returns a task that starts the main loop instead of starting the main loop.
SegmentDump.dump() now has a default delay of 0 seconds due to rate limiting handling (see below)

Features

CloudClient.set_cloud() is now rate limited to 0.1 requests per second. Requests will be queued and fulfilled in the order they were sent.
CloudClient objects can now be stopped with the CloudClient.stop() method.
MissingCloudVariable exceptions can be ignored through the CloudClient via the argument ignore_missing_variables=True

Fixes

Some docs fixes

Last edited by SansStudios (May 15, 2022 18:50:45)


scratchcloud
Click above to check it out! I've worked on it for over a year!























Just like sudden sadness comes hangin' on the breeze
ajsya
Scratcher
1000+ posts

scratchcloud ☁️ async python library for cloud variables

can you encode lists?

Hi, I'm ajsya!

Owner of several dead shops, Notable Chair, Scratch Wiki Editor, Developer, and Gamer.

| Roblox | GitHub | Wiki | My Posts | Scratch Empires | Scratch Weather App | Minecraft Server Pinger |

Before creating a new topic on the forums search Ocular to see if one already exists!

SansStudios
Scratcher
500+ posts

scratchcloud ☁️ async python library for cloud variables

ajsya wrote:

can you encode lists?

Yep! All you have to do it build your own codec, or use someone elses. There isn't any “official” scratchcloud project for this though.

The CloudClient object has optional “encoder” and “decoder” arguments. These arguments take functions that encode and decode data.

docs wrote:

encoder (Callable[, str], optional) – a callable function that is used to encode all sent cloud data. The function must return a string of digits and take 1 argument.

decoder (Callable[, str], optional) – a callable function that is used to decode all received cloud data. The function must take 1 argument.

scratchcloud's default codec is called BaseCodec, and it can be imported via `scratchcloud.ext`. I'd highly recommend reading the docs on BaseCodec if you haven't already.

You can use BaseCodec to create your own codec class. For instance, say you wanted a client to send a csv list to a scratch project, and you wanted the client to read csv lists that you get from scratch. You could make your own codec that decodes csv data into a list, and encodes python lists into csv data. (csv = comma separated values. Basically a list that looks like this: hello,goodbye,hi,hey)

Codec Example:

from scratchcloud.ext import BaseCodec
class ListCodec():
    def __init__(self, base: BaseCodec = BaseCodec(), separator: str = ','):
        self.separator = separator
        self.base = base
    # Decode method that takes data, decodes it using base codec, and splits the result into a list
    def decode(self, data):
        return self.base.decode(data).split(self.separator)
    # Encode method that takes data, and if it is a list, turns the list into a string with commas seperating.
    def encode(self, data: list | str):
        if isinstance(data, list):
            data = self.separator.join(data)
        return self.base.encode(data)

You can then use this in your CloudClient object:

from scratchcloud import CloudClient, CloudChange
# make a new list codec to use in client
codec = ListCodec()
# add the ListCodec.encode and ListCodec.decode methods to the client
client = CloudClient('username', '622084628', encoder=codec.encode, decoder=codec.decode)
@client.event
async def on_message(c: CloudChange):
    print(f'{c.name} changed to {c.value}')
    # set the value of the RESPONSE variable to a list
    await client.set_cloud('RESPONSE', ['send', 'this', 'list!'])

The above example is linked to the scratchcloud Test Interface. Make sure to turn on the BaseCodec sliders if you're testing

If you have more questions, feel free to ask!

scratchcloud
Click above to check it out! I've worked on it for over a year!























Just like sudden sadness comes hangin' on the breeze
coolcoder1213
Scratcher
100+ posts

scratchcloud ☁️ async python library for cloud variables

coolcoder1213 wrote:

SansStudios wrote:

coolcoder1213 wrote:

Cool. I mostly use s2py though.

Well, if you ever decide you wanna try async python, this is the library for that!

I also use scratchconnect but maybe I will use this. I am also developing my own package like scratchcloud and s2py.


Actually, scratchattach is THE BEST!!! But I will use this too sometimes.

So, this is just a signature.

Scratchleton - Hamilton Mod

Cloud Stats Projects

My Profile:
coolcoder1213

I am great at cloud variables and Python.
ISTILLMAKESTUFF
Scratcher
100+ posts

scratchcloud ☁️ async python library for cloud variables

coolcoder1213 wrote:

coolcoder1213 wrote:

SansStudios wrote:

coolcoder1213 wrote:

Cool. I mostly use s2py though.

Well, if you ever decide you wanna try async python, this is the library for that!

I also use scratchconnect but maybe I will use this. I am also developing my own package like scratchcloud and s2py.


Actually, scratchattach is THE BEST!!! But I will use this too sometimes.
Why is scratchattach the best, because it is made b a famous scratcher named timmccool?

Periscope Search
A Scratch User Stat Website that only uses api.scratch.mit.edu!
SansStudios
Scratcher
500+ posts

scratchcloud ☁️ async python library for cloud variables

coolcoder1213 wrote:

Actually, scratchattach is THE BEST!!! But I will use this too sometimes.

All libraries have their ups and downs

scratchattach is really good if you don't want to handle scratch overhead yourself. this can save hours of scratch coding time, and the python syntax is pythonic and understandable. But there are drawbacks to using it, such as cloud API spam, forced and fixed forced encoding / decoding. For example, in scratchattch, you can't control what cloud variables are used if you decide to use `CloudRequests`. You can't use `CloudEvents` to set cloud variables. All of your Scratch and Python code MUST be blocking.

scratchcloud was built for a more advanced python users (asynchronous), and therefore it focuses heavily on cloud data and cloud data transmission. It doesn't have any of the cloud problems that scratchattach does, and instead excels in those areas, but that comes at a price. scratchcloud has almost no accompanying pre-built scratch backends. You can't get backpack, email, or many more pieces of info via scratchcloud. And you will never be able to set your bio, project name, or anything other than cloud variables through base scratchcloud.

You can always find faults and benefits of any library, but libraries can only be the “best” for specific situations. Maybe you don't want to write a scratch cloud data handler yourself—great—use scratchattach! Maybe you need asynchronous coding—awesome—use scratchcloud. Maybe you want a super stable library that's been tried and tested months on end and will likely never bug out: scratchconnect and scratch2py are your best options. But it's very hard to choose one “best” library, as they all bring different things to the table.

scratchcloud
Click above to check it out! I've worked on it for over a year!























Just like sudden sadness comes hangin' on the breeze
coolcoder1213
Scratcher
100+ posts

scratchcloud ☁️ async python library for cloud variables

ISTILLMAKESTUFF wrote:

coolcoder1213 wrote:

coolcoder1213 wrote:

SansStudios wrote:

coolcoder1213 wrote:

Cool. I mostly use s2py though.

Well, if you ever decide you wanna try async python, this is the library for that!

I also use scratchconnect but maybe I will use this. I am also developing my own package like scratchcloud and s2py.


Actually, scratchattach is THE BEST!!! But I will use this too sometimes.
Why is scratchattach the best, because it is made b a famous scratcher named timmccool?


No, because of Cloud Requests.

So, this is just a signature.

Scratchleton - Hamilton Mod

Cloud Stats Projects

My Profile:
coolcoder1213

I am great at cloud variables and Python.
NFlex23
Scratcher
1000+ posts

scratchcloud ☁️ async python library for cloud variables

Bump. I kind of wish this worked with Python 3.8 since that's what Replit uses, but I understand your decision to use 3.10.
SansStudios
Scratcher
500+ posts

scratchcloud ☁️ async python library for cloud variables

NFlex23 wrote:

Bump. I kind of wish this worked with Python 3.8 since that's what Replit uses, but I understand your decision to use 3.10.

Thanks for the bump!

Unfortunately all of my typing relies on | union typing, and the API extension uses Dataclasses, both which are 3.10 features. It's kind of messed up that repl doesn't support 3.10

I could make a 3.8 version without API interaction if that would be useful

Last edited by SansStudios (June 11, 2022 20:12:18)


scratchcloud
Click above to check it out! I've worked on it for over a year!























Just like sudden sadness comes hangin' on the breeze
NFlex23
Scratcher
1000+ posts

scratchcloud ☁️ async python library for cloud variables

SansStudios wrote:

(#31)

NFlex23 wrote:

Bump. I kind of wish this worked with Python 3.8 since that's what Replit uses, but I understand your decision to use 3.10.

Thanks for the bump!

Unfortunately all of my typing relies on | union typing, and the API extension uses Dataclasses, both which are 3.10 features. It's kind of messed up that repl doesn't support 3.10

I could make a 3.8 version without API interaction if that would be useful
Yeah, that's what I thought — I love union typing and dataclasses as well. As for making a 3.8 version, I don't think that's really necessary. Replit should bump its Python version anyway; it's long overdue.
dinonil
Scratcher
78 posts

scratchcloud ☁️ async python library for cloud variables

NFlex23 wrote:

Bump. I kind of wish this worked with Python 3.8 since that's what Replit uses, but I understand your decision to use 3.10.
You can just use the Nix or Blank Repl template and then install the latest version of Python manually.

Powered by DjangoBB

Standard | Mobile