Skip to content

Commit

Permalink
Merge branch 'main' into feature/agent-rework
Browse files Browse the repository at this point in the history
  • Loading branch information
sugyan committed Jan 4, 2025
2 parents 8810bc7 + 25a8082 commit f00b866
Show file tree
Hide file tree
Showing 21 changed files with 404 additions and 24 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ jobs:

- name: Compile (rust-analyzer)
run: cargo build --verbose

- name: Lint (clippy)
uses: giraffate/clippy-action@v1
with:
reporter: "github-pr-check"
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Format (rustfmt)
if: matrix.rust != 'stable'
run: cargo fmt-no-gen --check
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ members = [
exclude = [
"examples/concurrent",
"examples/firehose",
"examples/video",
]
resolver = "2"

Expand All @@ -26,12 +27,12 @@ keywords = ["atproto", "bluesky"]

[workspace.dependencies]
# Intra-workspace dependencies
atrium-api = { version = "0.24.8", path = "atrium-api" }
atrium-api = { version = "0.24.9", path = "atrium-api", default-features = false }
atrium-common = { version = "0.1.0", path = "atrium-common" }
atrium-identity = { version = "0.1.0", path = "atrium-oauth/identity" }
atrium-xrpc = { version = "0.12.0", path = "atrium-xrpc" }
atrium-xrpc-client = { version = "0.5.10", path = "atrium-xrpc-client" }
bsky-sdk = { version = "0.1.13", path = "bsky-sdk" }
bsky-sdk = { version = "0.1.14", path = "bsky-sdk" }

# DAG-CBOR codec
ipld-core = { version = "0.4.1", default-features = false, features = ["std"] }
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ Below are some related projects that might be of interest:

- `atproto` https://github.com/bluesky-social/atproto
- The leading protocol implementation
- `rsky` https://github.com/blacksky-algorithms/rsky
- An AT Protocol Implementation built in Rust, using atrium.
- `adenosine` https://gitlab.com/bnewbold/adenosine
- `atproto-rs` https://github.com/ngerakines/atproto-rs
- `atproto-rs` https://github.com/Maaarcocr/atproto-rs
Expand Down
10 changes: 10 additions & 0 deletions atrium-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.24.9](https://github.com/sugyan/atrium/compare/atrium-api-v0.24.8...atrium-api-v0.24.9) - 2024-12-10

### Added

- Extend DidDocument with useful methods (#265)

### Other

- Add docs to API

## [0.24.8](https://github.com/sugyan/atrium/compare/atrium-api-v0.24.7...atrium-api-v0.24.8) - 2024-11-19

### Added
Expand Down
2 changes: 1 addition & 1 deletion atrium-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "atrium-api"
version = "0.24.8"
version = "0.24.9"
authors = ["sugyan <[email protected]>"]
edition.workspace = true
rust-version.workspace = true
Expand Down
13 changes: 13 additions & 0 deletions atrium-api/src/did_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ impl DidDocument {
pub fn get_pds_endpoint(&self) -> Option<String> {
self.get_service_endpoint("#atproto_pds", "AtprotoPersonalDataServer")
}
pub fn get_feed_gen_endpoint(&self) -> Option<String> {
self.get_service_endpoint("#bsky_fg", "BskyFeedGenerator")
}
pub fn get_notif_endpoint(&self) -> Option<String> {
self.get_service_endpoint("#bsky_notif", "BskyNotificationService")
}
fn get_service_endpoint(&self, id: &str, r#type: &str) -> Option<String> {
let full_id = self.id.to_string() + id;
if let Some(services) = &self.service {
Expand All @@ -62,4 +68,11 @@ impl DidDocument {
})
.unwrap_or_default()
}
pub fn get_signing_key(&self) -> Option<&VerificationMethod> {
self.verification_method.as_ref().and_then(|methods| {
methods.iter().find(|method| {
method.id == "#atproto" || method.id == format!("{}#atproto", self.id)
})
})
}
}
2 changes: 1 addition & 1 deletion atrium-api/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ pub enum Error {
NotAllowed,
}

/// Type alias to use this library's [`Error`] type in a [`Result`](core::result::Result).
/// Type alias to use this library's [`Error`](enum@crate::error::Error) type in a [`Result`](core::result::Result).
pub type Result<T> = core::result::Result<T, Error>;
21 changes: 21 additions & 0 deletions atrium-api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,27 @@ pub struct UnknownData {
/// Corresponds to [the `unknown` field type].
///
/// [the `unknown` field type]: https://atproto.com/specs/lexicon#unknown
///
/// By using the [`TryFromUnknown`] trait, it is possible to convert to any type
/// that implements [`DeserializeOwned`](serde::de::DeserializeOwned).
///
/// ```
/// use atrium_api::types::{TryFromUnknown, Unknown};
///
/// #[derive(Debug, serde::Deserialize)]
/// struct Foo {
/// bar: i32,
/// }
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let value: Unknown = serde_json::from_str(r#"{"bar": 42}"#)?;
/// println!("{value:?}"); // Object({"bar": DataModel(42)})
///
/// let foo = Foo::try_from_unknown(value)?;
/// println!("{foo:?}"); // Foo { bar: 42 }
/// # Ok(())
/// # }
/// ```
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(untagged)]
pub enum Unknown {
Expand Down
6 changes: 3 additions & 3 deletions atrium-oauth/oauth-client/src/atproto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ pub struct AtprotoLocalhostClientMetadata {
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct AtprotoClientMetadata {
pub client_id: String,
pub client_uri: String,
pub client_uri: Option<String>,
pub redirect_uris: Vec<String>,
pub token_endpoint_auth_method: AuthMethod,
pub grant_types: Vec<GrantType>,
Expand Down Expand Up @@ -209,7 +209,7 @@ impl TryIntoOAuthClientMetadata for AtprotoClientMetadata {
}
Ok(OAuthClientMetadata {
client_id: self.client_id,
client_uri: Some(self.client_uri),
client_uri: self.client_uri,
redirect_uris: self.redirect_uris,
token_endpoint_auth_method: Some(self.token_endpoint_auth_method.into()),
grant_types: Some(self.grant_types.into_iter().map(|v| v.into()).collect()),
Expand Down Expand Up @@ -331,7 +331,7 @@ gbGGr0pN+oSing7cZ0169JaRHTNh+0LNQXrFobInX6cj95FzEdRyT4T3
fn test_client_metadata() {
let metadata = AtprotoClientMetadata {
client_id: String::from("https://example.com/client_metadata.json"),
client_uri: String::from("https://example.com"),
client_uri: Some(String::from("https://example.com")),
redirect_uris: vec![String::from("https://example.com/callback")],
token_endpoint_auth_method: AuthMethod::PrivateKeyJwt,
grant_types: vec![GrantType::AuthorizationCode],
Expand Down
6 changes: 6 additions & 0 deletions bsky-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.1.14](https://github.com/sugyan/atrium/compare/bsky-sdk-v0.1.13...bsky-sdk-v0.1.14) - 2024-12-10

### Other

- updated the following local packages: atrium-api

## [0.1.13](https://github.com/sugyan/atrium/compare/bsky-sdk-v0.1.12...bsky-sdk-v0.1.13) - 2024-11-19

### Other
Expand Down
2 changes: 1 addition & 1 deletion bsky-sdk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bsky-sdk"
version = "0.1.13"
version = "0.1.14"
authors = ["sugyan <[email protected]>"]
edition.workspace = true
rust-version.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions examples/concurrent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
atrium-api = "0.18.1"
atrium-xrpc-client = "0.4.0"
atrium-api = "0.24.8"
atrium-xrpc-client = "0.5.10"
clap = { version = "4.5.1", features = ["derive"] }
futures = "0.3.30"
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] }
11 changes: 7 additions & 4 deletions examples/concurrent/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.app
.bsky
.actor
.get_profile(atrium_api::app::bsky::actor::get_profile::Parameters {
actor: actor.parse().expect("invalid actor"),
})
.get_profile(
atrium_api::app::bsky::actor::get_profile::ParametersData {
actor: actor.parse().expect("invalid actor"),
}
.into(),
)
.await
})
})
.collect::<Vec<_>>();
let results = join_all(handles).await;
println!("{} profiles fetched!", results.len());
for (actor, result) in actors.iter().zip(results) {
println!("{actor}: {:#?}", result?);
println!("{actor}: {:?}", result?);
}
Ok(())
}
8 changes: 6 additions & 2 deletions examples/firehose/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ edition = "2021"

[dependencies]
anyhow = "1.0.80"
atrium-api = { version = "0.18.1", features = ["dag-cbor"] }
atrium-api = { version = "0.24.8" }
chrono = "0.4.34"
cid_old = { package = "cid", version = "0.10.1" }
cid = { package = "cid", version = "0.11.1" }
futures = "0.3.30"
ipld-core = { version = "0.4.0", default-features = false, features = ["std"] }
rs-car = "0.4.1"
serde_ipld_dagcbor = { version = "0.6.0", default-features = false, features = ["std"] }
serde_ipld_dagcbor = { version = "0.6.0", default-features = false, features = [
"std",
] }
tokio = { version = "1.36.0", features = ["full"] }
tokio-tungstenite = { version = "0.21.0", features = ["native-tls"] }
trait-variant = "0.1.1"
24 changes: 24 additions & 0 deletions examples/firehose/src/cid_compat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use cid::{multihash::Multihash, Cid};

pub struct CidOld(cid_old::Cid);

impl From<cid_old::Cid> for CidOld {
fn from(value: cid_old::Cid) -> Self {
Self(value)
}
}
impl TryFrom<CidOld> for Cid {
type Error = cid::Error;
fn try_from(value: CidOld) -> Result<Self, Self::Error> {
let version = match value.0.version() {
cid_old::Version::V0 => cid::Version::V0,
cid_old::Version::V1 => cid::Version::V1,
};

let codec = value.0.codec();
let hash = value.0.hash();
let hash = Multihash::from_bytes(&hash.to_bytes())?;

Self::new(version, codec, hash)
}
}
1 change: 1 addition & 0 deletions examples/firehose/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod cid_compat;
pub mod stream;
pub mod subscription;
13 changes: 8 additions & 5 deletions examples/firehose/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use atrium_api::app::bsky::feed::post::Record;
use atrium_api::com::atproto::sync::subscribe_repos::{Commit, NSID};
use atrium_api::types::{CidLink, Collection};
use chrono::Local;
use firehose::cid_compat::CidOld;
use firehose::stream::frames::Frame;
use firehose::subscription::{CommitHandler, Subscription};
use futures::StreamExt;
Expand Down Expand Up @@ -54,7 +55,12 @@ impl CommitHandler for Firehose {
continue;
}
let (items, _) = rs_car::car_read_all(&mut commit.blocks.as_slice(), true).await?;
if let Some((_, item)) = items.iter().find(|(cid, _)| Some(CidLink(*cid)) == op.cid) {
if let Some((_, item)) = items.iter().find(|(cid, _)| {
//
// convert cid from v0.10.1 to v0.11.1
let cid = CidOld::from(*cid).try_into().expect("couldn't convert old to new cid");
Some(CidLink(cid)) == op.cid
}) {
let record = serde_ipld_dagcbor::from_reader::<Record, _>(&mut item.as_slice())?;
println!(
"{} - {}",
Expand All @@ -78,8 +84,5 @@ impl CommitHandler for Firehose {

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
RepoSubscription::new("bsky.network")
.await?
.run(Firehose)
.await
RepoSubscription::new("bsky.network").await?.run(Firehose).await
}
12 changes: 12 additions & 0 deletions examples/video/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "video"
version = "0.1.0"
edition = "2021"

[dependencies]
atrium-api = { version = "0.24.8", features = ["agent"] }
atrium-xrpc-client.version = "0.5.10"
clap = { version = "4.5.21", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_html_form = { version = "0.2.6", default-features = false }
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] }
14 changes: 14 additions & 0 deletions examples/video/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Example code for uploading a video

1. First, get a token by `com.atproto.server.getServiceAuth`.

2. Call uploadVideo against the video service (`video.bsky.app`) with the token.

3. Call `app.bsky.video.getJobStatus` against the video service as well.

(The same goes for `app.bsky.video.getUploadLimits`, which gets a token and calls the video service with it to get the data, but the process of checking this may be omitted.)

In Atrium:

- Since `AtpAgent` cannot process XRPC requests with the token obtained by `getServiceAuth`, we need to prepare a dedicated Client and create an `AtpServiceClient` that uses it.
- The `app.bsky.video.uploadVideo` endpoint is special (weird?) and requires special hacks such as adding query parameters to the request URL and modifying the response to match the schema.
Loading

0 comments on commit f00b866

Please sign in to comment.