arroba package
Reference documentation.
did
Utilities to create and resolve did:plcs, did:webs, and handles.
- requests_get(*args, **kwargs)[source]
Used as get_fn below. Wrapped so that we can mock requests.get in tests.
- resolve(did, **kwargs)[source]
Resolves a
did:plcordid:web.- Parameters:
did (str)
kwargs – passed through to
resolve_plc()/resolve_web()
- Returns:
JSON DID document
- Return type:
- Raises:
ValueError – if the input is not a
did:plcordid:webRequestException – if an HTTP request fails
- resolve_plc(did, get_fn=<function requests_get>)[source]
Resolves a
did:plcby fetching its DID document from a PLC directory.The PLC directory hostname is specified in the
PLC_HOSTenvironment variable.did:plcbackground:- Parameters:
did (str)
get_fn (callable) – for making HTTP GET requests
- Returns:
JSON DID document
- Return type:
- Raises:
ValueError – if the input did is not a
did:plcstrRequestException – if the HTTP request fails
- create_plc(handle, **kwargs)[source]
Creates a new
did:plcin a PLC directory.Args are documented in
write_plc().
- update_plc(did, **kwargs)[source]
Updates an existing
did:plcin a PLC directory.Args are documented in
write_plc().
- write_plc(did=None, handle=None, signing_key=None, rotation_key=None, pds_url=None, also_known_as=None, prev=None, get_fn=<function requests_get>, post_fn=<function post>)[source]
Writes a PLC operation to a PLC directory.
Generally used to create a new
did:plcor update an existing one.The PLC directory hostname is specified in the
PLC_HOSTenvironment variable.did:plcbackground:The DID document in the returned value is the new format DID doc, with the fully qualified
verificationMethod.idandMultikeykey encoding, iedid:keywithout the prefix. Details: https://github.com/bluesky-social/atproto/discussions/1510- Parameters:
did (str) – if provided, updates an existing DID, otherwise creates a new one.
handle (str) – domain handle to associate with this DID
signing_key (ec.EllipticCurvePrivateKey) – The curve must be SECP256K1. If omitted, a new keypair will be created.
rotation_key (ec.EllipticCurvePrivateKey) – The curve must be SECP256K1. If omitted, a new keypair will be created.
pds_url (str) – PDS base URL to associate with this DID. If omitted, defaults to
https://[$PDS_HOST]also_known_as (str or sequence of str) – additional URI or URIs to add to
alsoKnownAsprev (str) – if an update, the CID of the previous operation for this DID
get_fn (callable) – for making HTTP GET requests
post_fn (callable) – for making HTTP POST requests
- Returns:
with the newly created
did:plc, keys, and DID document- Return type:
- Raises:
ValueError – if any inputs are invalid
RequestException – if the HTTP request to the PLC directory fails
- encode_did_key(pubkey)[source]
Encodes an
ec.EllipticCurvePublicKeyinto adid:keystring.https://atproto.com/specs/did#public-key-encoding
- Parameters:
pubkey (ec.EllipticCurvePublicKey)
- Returns:
encoded
did:key- Return type:
- decode_did_key(did_key)[source]
Decodes a
did:keystring into anec.EllipticCurvePublicKey.https://atproto.com/specs/did#public-key-encoding
- Parameters:
did_key (str)
- Returns:
ec.EllipticCurvePublicKey
- get_handle(did_doc)[source]
Extracts and returns a DID’s handle.
Doesn’t do bidirectional handle resolution! Just returns the handle in the first
at://URI inalsoKnownAs.
- get_signing_key(did_doc)[source]
Extracts and returns a DID’s signing key.
- Parameters:
did_doc (dict) – DID document
- Returns:
ec.EllipticCurvePublicKey, or None if the DID doc has no ATProto signing key
- plc_operation_to_did_doc(op)[source]
Converts a PLC directory operation to a DID document.
https://github.com/bluesky-social/did-method-plc#presentation-as-did-document
The DID document in the returned value is the new format DID doc, with the fully qualified
verificationMethod.idandMultikeykey encoding, iedid:keywithout the prefix. Details: https://github.com/bluesky-social/atproto/discussions/1510- Parameters:
op – dict, PLC operation, https://github.com/did-method-plc/did-method-plc#operation-serialization-signing-and-validation
- Returns:
DID document, https://www.w3.org/TR/did-core/#data-model
- Return type:
- resolve_web(did, get_fn=<function requests_get>)[source]
Resolves a
did:webby fetching its DID document.did:webspec: https://w3c-ccg.github.io/did-method-web/- Parameters:
did (str)
get_fn (callable) – for making HTTP GET requests
- Returns:
JSON DID document
- Return type:
- Raises:
ValueError – if the input did is not a
did:webstrRequestException – if the HTTP request fails
- resolve_handle(handle, get_fn=<function requests_get>)[source]
Resolves an ATProto handle to a DID.
Supports the DNS TXT record and HTTPS well-known methods.
https://atproto.com/specs/handle#handle-resolution
- Parameters:
handle (str)
get_fn (callable) – for making HTTP GET requests
- Returns:
DID, or None if the handle can’t be resolved
- Return type:
str or None
- Raises:
ValueError – if handle is not a domain
diff
AT Protocol utility for diffing two MSTs.
Heavily based on: https://github.com/bluesky/atproto/blob/main/packages/repo/src/mst/diff.ts
Huge thanks to the Bluesky team for working in the public, in open source, and to Daniel Holmgren and Devin Ivy for this code specifically!
mst
Bluesky / AT Protocol Merkle search tree implementation.
Heavily based on: https://github.com/bluesky-social/atproto/blob/main/packages/repo/src/mst/mst.ts
Huge thanks to the Bluesky team for working in the public, in open source, and to Daniel Holmgren and Devin Ivy for this code specifically!
From that file:
This is an implementation of a Merkle Search Tree (MST) The data structure is described here: https://hal.inria.fr/hal-02303490/document The MST is an ordered, insert-order-independent, deterministic tree. Data keys are laid out in alphabetic order. The key insight of an MST is that each key is hashed and starting 0s are counted to determine which layer it falls on (5 zeros for ~32 fanout). This is a merkle tree, so each subtree is referred to by its hash (CID). When a leaf is changed, ever tree on the path to that leaf is changed as well, thereby updating the root hash.
For atproto, we use SHA-256 as the key hashing algorithm, and ~4 fanout (2-bits of zero per layer).
A couple notes on CBOR encoding:
There are never two neighboring subtrees. Therefore, we can represent a node as an array of leaves & pointers to their right neighbor (possibly null), along with a pointer to the left-most subtree (also possibly null).
Most keys in a subtree will have overlap. We do compression on prefixes by describing keys as: * the length of the prefix that it shares in common with the preceding key * the rest of the string
For example:
If the first leaf in a tree is bsky/posts/abcdefg and the second is
bsky/posts/abcdehi, then the first will be described as prefix: 0, key:
'bsky/posts/abcdefg', and the second will be described as prefix: 16, key:
'hi'.
- class MST(*, storage=None, entries=None, pointer=None, layer=None)[source]
Bases:
objectMerkle search tree class.
- entries
- Type:
sequence of MST and Leaf
- pointer
- Type:
CID
- new_tree(entries)[source]
We never mutate an MST, we just return a new MST with updated values.
- Parameters:
entries (sequence of MST and Leaf)
- Return type:
- get_entries()[source]
We don’t want to load entries of every subtree, just the ones we need.
- Return type:
sequence of MST and Leaf
- get_pointer()[source]
Returns this MST’s root CID pointer. Calculates it if necessary.
We don’t hash the node on every mutation for performance reasons. Instead we keep track of whether the pointer is outdated and only (recursively) calculate when needed.
- Return type:
CID
- get_layer()[source]
Returns this MST’s layer, and sets
self.layer.In most cases, we get the layer of a node from a hint on creation. In the case of the topmost node in the tree, we look for a key in the node & determine the layer. In the case where we don’t find one, we recurse down until we do. If we still can’t find one, then we have an empty tree and the node is layer 0.
- Return type:
- attempt_get_layer()[source]
Returns this MST’s layer, and sets
self.layer.- Return type:
int or None
- get_unstored_blocks()[source]
Return the necessary blocks to persist the MST to repo storage.
- Return type:
(CID root, dict mapping CID to Block) tuple
- add(key, value=None, known_zeros=None)[source]
Adds a new leaf for the given key/value pair.
- Parameters:
- Return type:
- Raises:
ValueError – if a leaf with that key already exists
- delete_recurse(key)[source]
Deletes the value and subtree, if any, at the given key.
- Parameters:
key (str)
- Returns:
MST
- replace_with_split(index, left=None, leaf=None, right=None)[source]
Replaces an entry with [ Maybe(tree), Leaf, Maybe(tree) ].
- trim_top()[source]
Trims the top and return its subtree, if necessary.
Only if the topmost node in the tree only points to another tree. Otherwise, does nothing.
- Return type:
- append_merge(to_merge)[source]
Merges another tree with this one.
The simple merge case where every key in the right tree is greater than every key in the left tree. Used primarily for deletes.
- find_gt_or_equal_leaf_index(key)[source]
Finds the index of the first leaf node greater than or equal to value.
- walk_leaves_from(key)[source]
Walk tree starting at key.
Generator for leaves in the tree, starting at a given key.
- Parameters:
key (str)
- Generates:
Leaf
- list_with_prefix(prefix)[source]
Returns entries with a given key prefix.
- Parameters:
prefix (str) – key prefix
- Returns:
sequence of Leaf
- load_all(start=0)[source]
Generator. Used in
xrpc_sync.get_repo().(The bluesky-social/atproto TS code calls this
writeToCarStream.)- Parameters:
start (int) – optional
subscribeRepossequence number to start from, inclusive. Defaults to 0.- Returns:
generator of (CID, bytes) tuples
- cids_for_path(key)[source]
Returns the CIDs in a given key path.
- Parameters:
key (str)
- Returns:
sequence of
CID
- add_covering_proofs(commit, blocks=None)[source]
Finds and adds blocks needed for covering proofs of a commit’s operations.
- Parameters:
commit (CommitData)
blocks (dict, CID => Block) – optional; if provided, covering proof blocks will be added to this dict, in place.
Returns: sequence of Block: all blocks in covering proofs for this commit. If the
blocksarg was provided, this is it.
- ensure_valid_key(key)[source]
- Parameters:
key (str)
- Raises:
ValueError – if key is not a valid MST key
- class Walker(tree)[source]
Bases:
objectAllows walking an MST manually.
- stack
- Type:
sequence of WalkStatus
- status
current
- Type:
- step_into()[source]
Steps into a subtree.
- Raises:
RuntimeError – if curently on a leaf
repo
Bluesky / AT Protocol repo implementation.
https://atproto.com/guides/data-repos
Heavily based on: https://github.com/bluesky-social/atproto/blob/main/packages/repo/src/repo.ts
Huge thanks to the Bluesky team for working in the public, in open source, and to Daniel Holmgren and Devin Ivy for this code specifically!
- class Repo(*, storage=None, mst=None, head=None, handle=None, status=None, callback=None, signing_key=None, rotation_key=None)[source]
Bases:
objectAT Protocol data repo implementation, storage agnostic.
- callback (callable
(CommitData | dict) => None): called on new commits and other repo events. May be set directly by clients. None means no callback. The parameter will be a
CommitDatafor commits, dict record with$typefor othercom.atproto.sync.subscribeReposmessages.
- get_contents()[source]
- Return type:
dict mapping str collection to dict mapping str rkey to dict record
- classmethod create_from_commit(storage, commit_data, *, signing_key, rotation_key=None, **kwargs)[source]
- Parameters:
storage (Storage)
commit_data (CommitData)
signing_key (ec.EllipticCurvePrivateKey) – passed through to
Storage.create_repo()rotation_key (ec.EllipticCurvePrivateKey) – optional, passed through to
Storage.create_repo()kwargs – passed through to
Repoconstructor
- Return type:
- classmethod create(storage, did, *, signing_key, rotation_key=None, initial_writes=None, **kwargs)[source]
- Parameters:
- Returns:
self
- Return type:
- classmethod format_commit(*, repo=None, storage=None, repo_did=None, signing_key=None, mst=None, cur_head=None, writes=None)[source]
Creates, but does not store, a new commit.
If
repois provided, all other kwargs should be omitted except (optionally)writes. Otherwise,storage,repo_did, andsigning_keyare required.If
repois provided, itsmstattribute is set to the newMSTresulting from applying this commit.- Parameters:
- Return type:
- apply_commit(commit_data)[source]
- Parameters:
commit_data (CommitData)
- Returns:
self
- Return type:
storage
Bluesky repo storage base class and in-memory implementation.
Lightly based on: https://github.com/bluesky-social/atproto/blob/main/packages/repo/src/storage/repo-storage.ts
- class Action(*values)[source]
Bases:
EnumUsed in
Repo.format_commit().TODO: switch to StrEnum once we can require Python 3.11.
- class Block(*, cid=None, decoded=None, encoded=None, seq=None, ops=None, time=None, repo=None)[source]
Bases:
objectAn ATProto block: a record,
MSTentry, commit, or other event.Can start from either encoded bytes or decoded object, with or without
CID. Decodes, encodes, and generatesCIDlazily, on demand, on attribute access.Events should have a fully-qualified
$typefield that’s one of themessagetypes incom.atproto.sync.subscribeRepos, egcom.atproto.sync.subscribeRepos#tombstone.Based on
carbox.car.Block.- cid
lazy-loaded (dynamic property)
- Type:
CID
- time
when this block was first created
- Type:
datetime
- class Storage[source]
Bases:
objectAbstract base class for storing nodes: records, MST entries, commits, etc.
Concrete subclasses should implement this on top of physical storage, eg database, filesystem, in memory.
TODO: batch operations?
- head
- Type:
CID
- create_repo(repo)[source]
Stores a new repo’s metadata in storage.
Only stores the repo’s DID, handle, and head commit
CID, not blocks!If the repo already exists in storage, this should update it instead of failing.
- Parameters:
repo (Repo)
- store_repo(repo)[source]
Writes a repo to storage.
Right now only writes some metadata: * handle * status
- Parameters:
repo (Repo)
- load_repos(after=None, limit=500)[source]
Loads multiple repos from storage.
Repos are returned in lexicographic order of their DIDs, ascending. Tombstoned repos are included.
- deactivate_repo(repo)[source]
Marks a repo as deactivated.
Stores a
com.atproto.sync.subscribeRepos#accountblock with its own sequence number.If
Repo.callbackis populated, calls it with thecom.atproto.sync.subscribeRepos#accountmessage.Calls
Repo._set_status()to mark the repo as deactivated in storage.
After this, any attempt to write to this repo will raise
InactiveRepo.- Parameters:
repo (Repo)
- activate_repo(repo)[source]
Marks a repo as active.
Only needed after deactivating. Does nothing if the repo is tombstoned.
Stores a
com.atproto.sync.subscribeRepos#accountblock with its own sequence number.If
Repo.callbackis populated, calls it with thecom.atproto.sync.subscribeRepos#accountmessage.Calls
Repo._set_status()to mark the repo as active in storage.
- Parameters:
repo (Repo)
- tombstone_repo(repo)[source]
Marks a repo as tombstoned.
Stores a
com.atproto.sync.subscribeRepos#tombstoneblock with its own sequence number.If
Repo.callbackis populated, calls it with thecom.atproto.sync.subscribeRepos#tombstonemessage.Calls
Repo._set_status()to mark the repo as deactivated in storage.
After this, any attempt to write to this repo will raise
InactiveRepo.- Parameters:
repo (Repo)
- read(cid)[source]
Reads a node from storage.
- Parameters:
cid (CID)
- Return type:
Block, or None if not found
- read_blocks_by_seq(start=0, repo=None)[source]
Batch read blocks from storage by
subscribeRepossequence number.
- read_events_by_seq(start=0, repo=None)[source]
Batch read commits and other events by
subscribeRepossequence number.- Parameters:
- Returns:
generator of
CommitDatafor commits and dict messages for other events, starting fromseq, inclusive, in ascendingseqorder- Return type:
generator
- write_blocks(blocks)[source]
Batch write blocks to storage.
Overwrites any existing stored blocks with the same CIDs! Does not allocate sequence numbers!
- Parameters:
blocks (sequence of
Block)
- apply_commit(commit_data)[source]
Writes a commit to storage.
Generates a new sequence number and uses it for all blocks in the commit.
- Parameters:
commit (CommitData)
- Raises:
InactiveError – if the repo is not active
- allocate_seq(nsid)[source]
Generates and returns a sequence number for the given NSID.
Sequence numbers must be monotonically increasing positive integers, per NSID. They may have gaps. Background: https://atproto.com/specs/event-stream#sequence-numbers
datastore_storage
Google Cloud Datastore implementation of repo storage.
- class JsonProperty(*args, **kwargs)[source]
Bases:
TextPropertyFork of ndb’s that subclasses
ndb.TextPropertyinstead ofndb.BlobProperty.This makes values show up as normal, human-readable, serialized JSON in the web console. https://github.com/googleapis/python-ndb/issues/874#issuecomment-1442753255
Duplicated in oauth-dropins/webutil: https://github.com/snarfed/webutil/blob/main/models.py
- class ComputedJsonProperty(*args, **kwargs)[source]
Bases:
JsonProperty,ComputedPropertyCustom
ndb.ComputedPropertyfor JSON values that stores them as strings.…instead of like
ndb.StructuredProperty, with “entity” type, which bloats them unnecessarily in the datastore.
- class CommitOp(**kwargs)[source]
Bases:
ModelRepo operations - creates, updates, deletes - included in a commit.
Used in a
StructuredPropertyinsideAtpBlock; not stored directly in the datastore.https://googleapis.dev/python/python-ndb/latest/model.html#google.cloud.ndb.model.StructuredProperty
- class AtpRepo(**kwargs)[source]
Bases:
ModelAn ATProto repo.
Key name is DID. Only stores the repo’s metadata. Blocks are stored in
AtpBlocks.Attributes: * handles (str): repeated, optional * head (str): CID * signing_key (str) * rotation_key (str) * status (str)
- property signing_key
(ec.EllipticCurvePrivateKey)
- property rotation_key
(ec.EllipticCurvePrivateKey` or None)
- class AtpBlock(**kwargs)[source]
Bases:
ModelA data record, MST node, repo commit, or other event.
Key name is the DAG-CBOR base32 CID of the data.
Events should have a fully-qualified
$typefield that’s one of themessagetypes incom.atproto.sync.subscribeRepos, egcom.atproto.sync.subscribeRepos#tombstone.Properties: * repo (google.cloud.ndb.Key): DID of the first repo that included this block * encoded (bytes): DAG-CBOR encoded value * data (dict): DAG-JSON value, only used for human debugging * seq (int): sequence number for the subscribeRepos event stream
- class AtpSequence(**kwargs)[source]
Bases:
ModelA sequence number for a given event stream NSID.
Sequence numbers are monotonically increasing, without gaps (which ATProto doesn’t require), starting at 1. Background: https://atproto.com/specs/event-stream#sequence-numbers
Key name is XRPC method NSID.
At first, I considered using datastore allocated ids for sequence numbers, but they’re not guaranteed to be monotonically increasing, so I switched to this.
- classmethod allocate(nsid)[source]
Returns the next sequence number for a given NSID.
Creates a new
AtpSequenceentity if one doesn’t already exist for the given NSID.- Parameters:
nsid (str) – the subscription XRPC method for this sequence number
- Returns:
integer, next sequence number for this NSID
- classmethod last(nsid)[source]
Returns the last sequence number for a given NSID.
Creates a new
AtpSequenceentity if one doesn’t already exist for the given NSID.- Parameters:
nsid (str) – the subscription XRPC method for this sequence number
- Returns:
integer, last sequence number for this NSID
- class AtpRemoteBlob(**kwargs)[source]
Bases:
ModelA blob available at a public HTTP URL that we don’t store ourselves.
Key ID is the URL.
TODO: * follow redirects, use final URL as key id * abstract this in
Storage- classmethod get_or_create(*, url=None, get_fn=<function get>, max_size=None, accept_types=None, name='')[source]
Returns a new or existing
AtpRemoteBlobfor a given URL.If there isn’t an existing
AtpRemoteBlob, fetches the URL over the network and creates a new one for it.- Parameters:
url (str)
get_fn (callable) – for making HTTP GET requests
max_size (int, optional) – the
maxSizeparameter for this blob field in its lexicon, if anyaccept_types (sequence of str, optional) – the
acceptparameter for this blob field in its lexicon, if any. The set of allowed MIME types.name (str, optional) – blob field name in lexicon
- Returns:
existing or newly created blob
- Return type:
- Raises:
RequestException – if the HTTP request to fetch the blob failed
lexrpc.ValidationError – if the blob is over
max_size, its type is not inaccept_typesor it is a video with a duration above the 3m limit
- as_object()[source]
Returns an ATProto
blobobject for this blob.https://atproto.com/specs/data-model#blob-type
- Returns:
with
$type: blobandref,mimeType, andsizefields- Return type:
- class DatastoreStorage(*, ndb_client=None, ndb_context_kwargs=None)[source]
Bases:
StorageGoogle Cloud Datastore implementation of
Storage.Sequence numbers in
AtpBlockare allocated per commit; all blocks in a given commit will have the same sequence number. They’re currently sequential counters, starting at 1, stored in anAtpSequenceentity.See
Storagefor method details.
util
Misc AT Protocol utils. TIDs, CIDs, etc.
- exception InactiveRepo(did, status, *args, **kwargs)[source]
Bases:
ValueErrorRaised when loading a repo that’s not active.
- now(tz=datetime.timezone.utc, **kwargs)[source]
Wrapper for
datetime.datetime.now()that lets us mock it out in tests.
- time_ns()[source]
Wrapper for
time.time_ns()that lets us mock it out in tests.
- dag_cbor_cid(obj)[source]
Returns the DAG-CBOR CID for a given object.
- Parameters:
obj – CBOR-compatible native object or value
- Return type:
CID
- s32encode(num)[source]
Base32 encode with encoding variant sort.
Based on https://github.com/bluesky-social/atproto/blob/main/packages/common-web/src/tid.ts
- s32decode(val)[source]
Base32 decode with encoding variant sort.
Based on https://github.com/bluesky-social/atproto/blob/main/packages/common-web/src/tid.ts
- tid_to_datetime(tid)[source]
Converts an TID to a datetime.
https://atproto.com/specs/record-key#record-key-type-tid
- Parameters:
tid (bytes) – base32-encoded TID
- Return type:
- Raises:
ValueError – if tid is not bytes or not 13 characters long
- tid_to_int(tid)[source]
Converts an TID to an integer.
https://atproto.com/specs/record-key#record-key-type-tid
- Parameters:
tid (bytes) – base32-encoded TID
- Return type:
- Raises:
ValueError – if tid is not bytes or not 13 characters long
- next_tid()[source]
Returns the TID corresponding to the current time.
A TID is a base32-sortable-encoded UNIX timestamp (ie time since the epoch) in microseconds. Returned tids are guaranteed to monotonically increase across calls.
https://atproto.com/specs/atp#timestamp-ids-tid https://atproto.com/specs/record-key#record-key-type-tid https://github.com/bluesky-social/atproto/blob/main/packages/common-web/src/tid.ts
- Returns:
TID
- Return type:
- new_key(seed=None)[source]
Generates a new ECC K-256 keypair.
https://atproto.com/specs/cryptography
- Parameters:
seed (int) – optional deterministic value to derive private key from. Don’t use in production!
- Return type:
ec.EllipticCurvePrivateKey
- sign(obj, private_key)[source]
Signs an object, eg a repo commit or DID document.
Adds the signature in the
sigfield.https://atproto.com/specs/cryptography
The signature is ECDSA around SHA-256 of the input, including a custom second pass to enforce that it’s the “low-S” variant: https://atproto.com/specs/cryptography#ecdsa-signature-malleability
- Parameters:
obj (dict)
private_key (EllipticCurvePrivateKey)
- Returns:
objwith newsigfield- Return type:
- apply_low_s_mitigation(signature, curve)[source]
Low-S signature mitigation.
This prevents signature malleability. (It doesn’t guarantee deterministic signatures though!)
https://atproto.com/specs/cryptography#ecdsa-signature-malleability
From picopds. Thank you David! https://github.com/DavidBuchanan314/picopds/blob/main/signing.py
- verify_sig(obj, public_key)[source]
Returns True if obj’s signature is valid, False otherwise.
See
sign()for more background.
- service_jwt(host, repo_did, privkey, expiration=datetime.timedelta(seconds=600), aud=None, **claims)[source]
Generates an inter-service JWT, eg for a relay or AppView.
https://atproto.com/specs/xrpc#inter-service-authentication-temporary-specification
- Parameters:
host (str) – hostname of the service this JWT is for, eg
bsky.networkrepo_did (str) – DID of the repo this JWT is for
privkey (ec.EllipticCurvePrivateKey) – repo’s signing key
expiration (timedelta) – length of time this JWT will be valid, defaults to 10m
aud (str) – JWT audience. Default is
did:web:[host], which works for relays and AppViews, but others (eg mod services) havedid:plcinstead.claims (dict) – additional claims to include in the JWT, eg
lxm
- Returns:
JWT
- Return type:
xrpc_repo
com.atproto.repo.* XRPC methods.
- get_record(input, repo=None, collection=None, rkey=None, cid=None)[source]
Handler for com.atproto.repo.getRecord XRPC method.
- list_records(input, repo=None, collection=None, limit=50, cursor=None, reverse=None, rkeyStart=None, rkeyEnd=None)[source]
Handler for com.atproto.repo.listRecords XRPC method.
KNOWN ISSUE: cursor is interpreted as inclusive, so whenever a cursor is used, the response includes the last record returned in the previous response.
xrpc_server
com.atproto.server.* XRPC methods.
- refresh_session(input, did=None, commit=None)[source]
Handler for
com.atproto.server.refreshSessionXRPC method.
xrpc_sync
com.atproto.sync.* XRPC methods.
- get_checkout(input, did=None)[source]
Handler for
com.atproto.sync.getCheckoutXRPC method.Deprecated! Use
getRepoinstead.Gets a checkout, either head or a specific commit.
- list_repos(input, limit=500, cursor=None)[source]
Handler for
com.atproto.sync.listReposXRPC method.
- subscribe_repos(cursor=None)[source]
Firehose event stream XRPC (ie
type: subscription) for all new commits.Event stream details: https://atproto.com/specs/event-stream#framing
This function serves forever, which ties up a runtime context, so it’s not automatically registered with the XRPC server. Instead, clients should choose how to register and serve it themselves, eg asyncio vs threads vs WSGI workers.
See
firehose.send_events()for an example thread-based callback to register withrepo.Repoto deliver all new commits to subscribers. Here’s how to register that callback and this XRPC method in a threaded context:server.repo.callback = lambda commit_data: firehose.send_events() server.server.register(‘com.atproto.sync.subscribeRepos’, xrpc_sync.subscribe_repos)
- get_head(input, did=None)[source]
Handler for
com.atproto.sync.getHeadXRPC method.Deprecated! Use
getLatestCommitinstead.
- get_latest_commit(input, did=None)[source]
Handler for
com.atproto.sync.getLatestCommitXRPC method.