32 个版本 (14 个重大更新)

0.15.1 2024年6月21日
0.14.2 2024年4月3日
0.14.0 2024年3月26日
0.9.0 2023年12月16日
0.5.9 2023年5月10日

#275网页编程

Download history 149/week @ 2024-05-01 240/week @ 2024-05-08 202/week @ 2024-05-15 381/week @ 2024-05-22 294/week @ 2024-05-29 1103/week @ 2024-06-05 2033/week @ 2024-06-12 2942/week @ 2024-06-19 3701/week @ 2024-06-26 2995/week @ 2024-07-03 2087/week @ 2024-07-10 606/week @ 2024-07-17 264/week @ 2024-07-24 389/week @ 2024-07-31 324/week @ 2024-08-07 681/week @ 2024-08-14

每月下载量 1,677

MIT 许可

605KB
18K SLoC

twapi-v2-rs

Twitter API v2 库。

文档

  • 请求构建器
  • 检索响应头
  • 便利的设置参数方法
  • Bearer 身份验证(OAuth 2.0 授权码流与 PKCE)
  • OAuth1.0a 身份验证(OAuth 1.0a 用户上下文)
  • 上传 Media upload.twitter.com API
  • 可选的重试、超时和日志记录
  • 可选的 OAuth 与网页示例
  • 可选的 v1 到 v2 解析器
  • 流式示例
  • 支持的模拟。例如,mockito。
  • 类型支持。

特性

默认

  • reqwest/default-tls

rustls-tls

  • reqwest/rustls-tls

重试

  • 可重试
  • 超时
  • 日志记录

oauth

  • Twitter OAuth

oauth10a

  • 使用 OAuth1.0a 通过 API

模型

  • 从 v1 到 v2

上传

  • 上传媒体

变更

CHANGELOG.md

测试状态

TEST.md

示例

API(Bearer)

use twapi_v2::api::{get_2_tweets_id, BearerAuthentication};

#[tokio::main]
async fn main() {
    let bearer_code = std::env::var("BEARER_CODE").unwrap();
    let auth = BearerAuthentication::new(bearer_code);
    let tweet_id = std::env::var("TWEET_ID").unwrap();
    let res = get_2_tweets_id::Api::open(&tweet_id)
        .execute(&auth)
        .await;
    if let Some((val, headers)) = res {
        println!("{:?}", val);
        println!("{}", headers);
    }
}

API(OAuth1.0a)

use twapi_v2::api::{get_2_tweets_id, BearerAuthentication};
use twapi_v2::oauth10a::OAuthAuthentication;

#[tokio::main]
async fn main() {
    let auth = OAuthAuthentication::new(
        std::env::var("CONSUMER_KEY").unwrap_or_default(),
        std::env::var("CONSUMER_SECRET").unwrap_or_default(),
        std::env::var("ACCESS_KEY").unwrap_or_default(),
        std::env::var("ACCESS_SECRET").unwrap_or_default(),
    );
    let tweet_id = std::env::var("TWEET_ID").unwrap();
    let res = get_2_tweets_id::Api::open(&tweet_id)
        .execute(&auth)
        .await;
    if let Some((val, headers)) = res {
        println!("{:?}", val);
        println!("{}", headers);
    }
}

V1 解析

use std::{fs::File, io::{Read, Write}};
use twapi_v2::models::TweetModel;

#[tokio::main]
async fn main() {
    let mut file = File::open("samples/v1_tweet.json").unwrap();
    let mut data = String::new();
    file.read_to_string(&mut data).unwrap();
    let src = serde_json::from_str::<serde_json::Value>(&data).unwrap();
    let res = TweetModel::from_v1(&src);
    let mut file = File::create("result.json").unwrap();
    write!(file, "{}", serde_json::to_string_pretty(&res).unwrap()).unwrap();
    file.flush().unwrap();
}

上传媒体

cd examples/post-media
CONSUMER_KEY=xxx \
CONSUMER_SECRET=xxx \
ACCESS_KEY=xxx \
ACCESS_SECRET=xxx \
cargo run

Twitter OAuth Web

cd examples/oauth-web
API_KEY_CODE=XXXX API_SECRET_CODE=XXXX CALLBACK_URL=https://127.0.0.1:3000/oauth cargo run

https://127.0.0.1:3000/

流式传输

cd examples/streaming
BEARER_CODE=XXXXX cargo run

模拟(使用 mockito)

#[tokio::test]
async fn test_mock_get_2_tweets_search_recent_oauth() -> Result<()> {
    // Setup mock server
    let mut server = Server::new_async().await;
    let mock = server
        .mock("GET", "/2/tweets/search/recent")
        .match_query(mockito::Matcher::Any)
        .with_status(200)
        .with_header("content-type", "application/json")
        .with_body("{ \"origin\": \"0.0.0.0\" }")
        .create_async()
        .await;

    // Setup OAuth
    let auth = OAuthAuthentication::new(
        std::env::var("CONSUMER_KEY").unwrap_or_default(),
        std::env::var("CONSUMER_SECRET").unwrap_or_default(),
        std::env::var("ACCESS_KEY").unwrap_or_default(),
        std::env::var("ACCESS_SECRET").unwrap_or_default(),
    );

    // Setup prefix all APIs
    api::setup_prefix_url(&server.url());
    let builder = get_2_tweets_search_recent::Api::open("東京")
        .max_results(10)
        .build(&auth);
    let (res, _headers) = execute_twitter::<get_2_tweets_search_recent::Response>(builder).await?;
    assert_eq!(res.extra.get("origin"), Some(&json!("0.0.0.0")));
    mock.assert();

    // Clear prefix url
    api::clear_prefix_url();
    // Override prefix url
    let twapi_options = TwapiOptions {
        prefix_url: Some(server.url().clone())
    };
    let builder = get_2_tweets_search_recent::Api::open("東京")
        .max_results(10)
        .twapi_options(Some(twapi_options))
        .build(&auth);
    let (res, _headers) = execute_twitter::<get_2_tweets_search_recent::Response>(builder).await?;
    assert_eq!(res.extra.get("origin"), Some(&json!("0.0.0.0")));

    Ok(())
}

依赖关系

~5–20MB
~324K SLoC