Architecture¶
aioscaleway and its sibling aioovh follow the same conventions: business areas, collections you iterate, references you await, one method per action, described in Features. This page covers what is specific to Scaleway.
Two layers¶
- Operations (
src/aioscaleway/_operations/<product>/<version>/), private: one typed method per OpenAPI operation, models and enums, generated byscripts/operations.py. It follows the API's layout and versions, and changes whenever Scaleway does. - Objects (
src/aioscaleway/<area>/), public: business areas, collections, references and loaded objects, generated byscripts/objects.pyfrom the operations andmapping.yaml. It changes only when the meaning does.
The hand-written runtime is _client.py (HTTP, authentication, retries),
_objects.py (collections, references, binding), _root.py (Scaleway),
_settings.py, _errors.py, _models.py and _enums.py.
scripts/generate.py runs both generators. CI fails when src/ or docs/
differ from what they produce.
How the objects are derived¶
- Version. For each product API class (
instanceApi,baremetalPrivateNetworkApi...), the latest stable version, else the latest preview.mapping.yamlversionsoverrides it: the Elastic Metal private networks stay in v1 to share the v1 server, and the Instance v2alpha1 volume API stays in the operations layer only. Operations of other versions are listed indocs/coverage.mdas such. - Resources. A path segment followed by a parameter
(
/servers/{server_id}) is a resource. The zone or region segment is a scope, not a resource. - Placement of each operation:
- on the item path:
Get*loads it,PATCHisupdate,PUTisupdateorreplace(Set*),DELETEisdelete, anything else is an action named after the operation without the resource's name (AttachServerVolumeonserversgivesattach_volume); - on the collection path:
List*is the iteration,Create*iscreate, anything else a collection method; - a
List*with no item path becomes an iterable collection without identifiers (scw.billing.consumptions); - a resource whose item path is at the root but whose list is under a
parent (
/pools/{pool_id},/clusters/{cluster_id}/pools) belongs to that parent:scw.kubernetes.clusters(cluster_id).pools; - anything else is a method of the area.
- Actions with an enum. An operation named
*Actionwhose body has an enumactionbecomes one method per value:ServerActiongivespower_on,power_off,reboot,backup,stop_in_place,terminate,enable_routed_ip. - Loaded classes subclass the operations model and the reference
(
class Server(_InstanceServer, ServerRef)). When a listing returns a summary model, a...Summaryclass plays the same role. - Names. Areas come from
mapping.yamlnamespaces. Collections take their path segment;collectionsrenames them, andprefixesputs a business prefix in front of a collection whose name another product of the area also uses.membersrenames actions. The generator stops on any remaining clash, of collections, classes or members, so a name is never chosen silently.
Identifiers¶
A key is a dict of the path parameters a reference needs (server_id,
zone). A loaded object rebuilds its key from its fields (id, zone).
Integer identifiers (Dedibox) are accepted as int | str. An argument naming
another resource (volume_id) accepts a string, a reference or an object.
Generated models¶
- Field defaults follow proto3: an absent scalar is its zero value; a field the spec requires has no default.
- Enumerations are open (
OpenStrEnum); unknown fields are kept. - Dates are
whenever.Instant, parsed by whenever's pydantic integration. google.type.Moneyis the hand-writtenMoney.- Every model is rebuilt at the end of its module, so that the loaded classes in another module inherit resolved fields.
Where the specs come from¶
The developers website lists every OpenAPI file in its Zudoku bundle;
scripts/spec_index.py extracts the list and scripts/fetch_specs.sh
downloads them with curl (the website refuses the default client of Python
HTTP libraries), then regenerates.
Import time¶
import aioscaleway loads the runtime only. Each area is imported the first
time it is used (scw.compute), since an area holds thousands of models.
Retries¶
Idempotent methods are retried on 429, 502, 503, 504 and transport
errors; a POST only on 429, 503 or a connection that never opened.