Loading¶
How Loadables act before and after being loaded is not immediately obvious.
This section explains in greater detail how loading works.
Additional Loading Methods¶
cg.load() will load a given Loadable. This happens naturally when you
call cg.run(), but it is possible to need to have a loaded Loadable before
you call cg.run(), for various reasons.
cg = Circleguard("key")
r = ReplayMap(221777, 2757689)
print(r.loaded)
cg.load(r)
print(r.loaded)
cg.load_info() will load the info of a given ReplayContainer. See
Replay Containers for exactly what that means. Like cg.load(), this happens
naturally during cg.run(), but you may need an info loaded ReplayContainer
before you call cg.run().
cg = Circleguard("key")
m = Map(221777, span="1")
print(m.info_loaded, m.loaded)
cg.load_info(m)
print(m.info_loaded, m.loaded)
cg.load(m)
print(m.info_loaded, m.loaded)
Stages¶
Different Loadables have different stages, where varying amounts of
information is available to you. Each stage requires loading more information
from the api, which can be an expensive operation. This is why we defer loading
until necessary.
Replays¶
A Replay has two stages. Upon instantiation it is unloaded, and when
either cg.run() or cg.load() is called on it, it becomes loaded.
When unloaded, a Replay has only the attributes you passed to it—path
for ReplayPath and user_id and map_id for ReplayMap, alongside any
optional arguments such as mods. Technically, a
Replay has a few more attributes than this (such as RatelimitWeight), but
they are beyond the scope of this discussion.
This means that trying to access, say, the replay_data or replay_id of
an unloaded Replay will result in an error. This is usually not a problem,
since the replays are loaded through cg.run() and you can access
replay_data etc. from the yielded Result. However, if you need to know
further information about the replay before you call cg.run(), use cg.load().
After loading a Replay, you can then acess its other attributes without
issue.
Replay Containers¶
A ReplayContainer is slightly more complicated, and has three stages. It
starts unloaded, becomes info loaded when cg.load_info() is called on it,
and becomes loaded when cg.load() is called on it.
When unloaded, a ReplayContainer only has the attributes you passed to it—
user_id for User and map_id for Map, alongside any optional
arguments such as mods. This means you can’t actually access any of the
Replays in the container—it hasn’t loaded anything from the api, so it
only knows what you gave it.
When info loaded, a ReplayContainer contains unloaded Replays. This means
that their user_id, map_id, and mods are available, but not
replay_data. You can iterate over its Replay list if the data
in unloaded Replays is useful to you.
When loaded, a ReplayContainer contains loaded Replays.
Of course, calling cg.load() on an unloaded ReplayContainer will “skip”
(from your perspective) the info loaded stage and make it loaded. It is not
required to call cg.load_info() before cg.load() on a ReplayContainer.
Iterating¶
A ReplayContainer can be iterated over or indexed to access its Replays.
This will of course only work in its info loaded and loaded stages, with
different amounts of information available from the Replays for each stage.
cg = Circleguard("key")
m = Map(221777, span="1")
for r in m:
print("this will never be printed")
cg.load_info(m)
for r in m:
print("this will be followed by False")
print(r.loaded)
cg.load(m)
for r in m:
print("this will be followed by True")
print(r.loaded)
This example works identically for a User, just with the Replays
representing their top plays instead of the leaderboards of a map.