Crate osynic_osuapi

Source
Expand description

logo

OsynicOsuapi

High performance, well-structured, extensible Rust osu! API client. Supports both WASM and native environments.


δΈ­ζ–‡η‰ˆζœ¬ | English Version

Β§πŸ“„ OSU!API Official Documentation

§🧻 API Experience Website

OsynicOsuapiEN.png

LeptosOsuapiPlayground is a website quickly built with the leptos framework to demonstrate osynic_osuapi, primarily using V1’s WASM client support (based on gloo-net). However, obviously, due to CORS issues, using the V1 API directly in the browser without a proxy will encounter cross-origin problems (since the WASM part makes requests from the browser frontend). Therefore, a relay server osynic-cors.deno.dev was set up using Deno, working with the WASM client’s proxy_url to implement proxy requests.

The website is currently deployed on osynic-osuapi.deno.dev via Deno. Chinese, Japanese, Korean, German, French, Russian, and English are supported.

Β§πŸ“œ Features

  • Support for both old and new APIs: Supports all V1 endpoints and most V2 endpoints (except for the undocumented modules)
  • WASM Compatibility: Provides WebAssembly support for V1 interfaces, allowing direct access to the OSU API from web applications (though you may encounter CORS issues)
  • Well-structured project: Based on a three-module division of client, interface, and model; the client part aggregates interface interfaces and supports various HTTP clients for easy extension
  • Very complete example support: The examples directory contains very complete example code and return data, see the API Checklist section below for details
  • Learn by example: The best way to learn how to use this library is to directly view the rich example code in examples, or run cargo run --example example_name to see the corresponding return data. Once you get used to the style of the examples, you’ll quickly be able to use it

Β§πŸš€ Quick Start

Β§1. Applying for OSU! API OAuth (V2) or Legacy API (V1)

You can apply for API access through your osu settings page. Simply navigate to either the OAuth (V2) or Legacy API (V1) section to complete your application.

Β§2. Setting Up Environment Variables

Create a .env file in your project’s root directory with the following content:

# V2 API
CLIENT_ID="your_client_id"
CLIENT_SECRET="your_client_secret"
REDIRECT_URI="your_redirect_uri"
CODE="your_code"  # Required for Authorization Code Grant authentication

# V1 API
API_KEY="your_api_key"

After setting up this file, you can use the dotenvy dependency to read these environment variables from the .env file in your project.

Β§3. Installing and Using the Library

First, add the dependency to your Cargo.toml:

[dependencies]
osynic_osuapi = "0.1.0"
# The default features are ["v1", "v2", "not-wasm"]. If you need to use this in a WASM environment, you need to disable the `not-wasm` feature and add the `wasm` feature, for example:
# osynic_osuapi = { version = "0.1.0", default-features = false, features = ["v1", "v2", "wasm"] }

Then you can use it in your code~

Β§Example 1: Complete CCG certification with V2 and obtain Peppy’s user information

The following code is from examples/peppy.rs, you can directly run cargo run --example peppy to see the effect

// Client Credentials Grant and Get Peppy's User Info
use osynic_osuapi::error::Result;
use osynic_osuapi::v2::client::request::client::OsynicOsuApiV2Client;
use osynic_osuapi::v2::interface::oauth::IOauth;
use osynic_osuapi::v2::interface::users::IUsers;

// You can also import all the client and interface modules by prelude
// use osynic_osuapi::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    dotenvy::dotenv().ok();
    let client_id = std::env::var("CLIENT_ID").expect("CLIENT_ID not set");
    let client_secret = std::env::var("CLIENT_SECRET").expect("CLIENT_SECRET not set");
    let client = OsynicOsuApiV2Client::default();
    let token = client
        .oauth
        .get_token_without_code(client_id.parse()?, &client_secret)
        .await?;
    println!("{:?}", token);

    let peppy = client
        .users
        .get_user_by_username("peppy", None, None)
        .await?;
    println!("{:?}", peppy);

    Ok(())
}

Β§Example 2: Check beatmap information with V1

The following code is from examples/gb.rs, you can directly run cargo run --example gb to see the effect

// Get beatmap by hash
use osynic_osuapi::error::Result;
use osynic_osuapi::v1::client::request::client::OsynicOsuApiV1Client;
use osynic_osuapi::v1::interface::beatmap::IBeatmap;
use osynic_osuapi::v1::model::beatmap::GetBeatmapsParams;

// You can also import all the client and interface modules by prelude
// use osynic_osuapi::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    dotenvy::dotenv().ok();
    let api_key = std::env::var("API_KEY").expect("API_KEY is not set.");
    let client = OsynicOsuApiV1Client::new(api_key.clone());
    let params = GetBeatmapsParams::default().hash("69f77b0dfe67d288c1bf748f91ceb133".to_string());

    let beatmaps = client.beatmap.get_beatmaps(params).await?;
    println!("{:?}", beatmaps);

    Ok(())
}

Β§πŸ• API Checklist

Examples can be run using cargo run --example example_name

Β§V1

This section is categorized based on the API classes from the V1 Official Documentation.

Interface modules can be found in src/v1/interface, with corresponding implementations in src/v1/client/request/api or src/v1/client/gloo/api.

APISupportNoteExample NameModule Name
/get_beatmapsβœ…Get beatmapsgbbeatmap
/get_userβœ…Get userguuser
/get_user_bestβœ…Get user’s bestgubuser
/get_user_recentβœ…Get user’s recentguruser
/get_matchβœ…Get matchgmmultiplayer
/get_scoresβœ…Get scoresgssscores
/get_replayβœ…Get replaygrreplay

Β§V2

This section is categorized based on the API classes from the V2 Official Documentation.

Interface modules can be found in src/v2/interface, with corresponding implementations in src/v2/client/request/api.

CategoryTotal APIsSupportedNotesModule Name
Authentication44 βœ…OAuth & Authoauth
Beatmaps1010 βœ…Beatmap APIbeatmaps
Beatmapsets72 ⚠️403 ForbiddenBeatmapset APIbeatmapsets
Changelog33 βœ…Changelog APIchangelog
Chat110 ❌403 ForbiddenChat APIchat
Comments72 ⚠️403 ForbiddenComments APIcomments
Events11 βœ…Events APIevents
Forum84 ⚠️403 ForbiddenForum APIforum
Home11 βœ…Home APIsearch
Matches12 βœ…Matches APImatches
Multiplayer42 ⚠️403 ForbiddenMultiplayer APImultiplayer
News22 βœ…News APInews
Notifications20 ❌403 ForbiddenNotifications APInotifications
Rankings33 βœ…Rankings APIrankings
Scores11 βœ…Scores APIscores
Users77 βœ…Users APIusers
Wiki11 βœ…Wiki APIwiki

Β§Authentication

APISupportNoteExample Name
/get_token_with_codeβœ…Short for Authorization Code Grant. Requires user browser OAuth authorization to get code for token request. No client_secret neededacg
/get_token_without_codeβœ…Short for Client Credentials Grant. Directly requests token without user authorization. client_secret must be set in environment variablesccg
/refresh_tokenβœ…Refresh token using refresh_token obtained with CCG authenticationrefresh
/revoke_current_tokenβœ…Revoke current tokenrevoke

Β§Beatmaps

APISupportNoteExample Name
/get_beatmap_packsβœ…Get beatmap packsbpsg
/get_beatmap_packβœ…Get beatmap packbpg
/lookup_beatmapβœ…Look up beatmapbl
/get_beatmapβœ…Get beatmapbg
/get_beatmap_attributesβœ…Get beatmap attributesbga
/get_beatmapsβœ…Get multiple beatmapsbgs
/get_scoresβœ…Get beatmap scoresbgss
/get_solo_scoresβœ…Get beatmap scores (Legacy)bgssn
/get_user_scoreβœ…Get user scorebgus
/get_user_scoresβœ…Get multiple user scoresbguss

Β§Beatmapsets

APISupportNoteExample Name
/get_beatmapset_discussions_posts🈳(Unstable return)Get beatmapset disscussions postsbsdpg
/get_beatmapset_discussions_votes🈳(Unstable return)Get beatmapset disscussions votesbsdvg
/get_beatmapset_discussions🈳(Unstable return)Get beatmapset disscussionsbsdg
/searchβœ…Search beatmapsetsbss
/lookup🈳(The doc is unclear)Look up beatmapsetbsl
/get_beatmapsetβœ…Get beatmapsetbsg
/download❌Download beatmapset (lazer)bsd

Β§Changelog

APISupportNoteExample Name
/get_changelog_buildβœ…Get changelogcbg
/get_changelog_listingβœ…Get changelog listclg
/lookup_changelog_buildβœ…Look up changelogcbl

Β§Chat

APISupportNoteExample Name
/chat_keepalive❌403 ForbiddenKeep connection alivechk
/create_new_pm❌403 ForbiddenCreate new PMchpc
/get_updates❌403 ForbiddenGet updateschug
/get_channel_messages❌403 ForbiddenGet channel messageschmg
/send_message_to_channel❌403 ForbiddenSend messagechms
/join_channel❌403 ForbiddenJoin channelchj
/leave_channel❌403 ForbiddenLeave channelchl
/mark_channel_as_read❌403 ForbiddenMark channel as readchmr
/get_channel_list❌403 ForbiddenGet channel listchlg
/create_channel❌403 ForbiddenCreate channelchc
/get_channel❌403 ForbiddenGet channelchg

Β§Comments

APISupportNoteExample Name
/get_commentsβœ…Get commentscsg
/post_comment❌403 ForbiddenPost commentcp
/get_commentβœ…Get commentcg
/edit_comment❌403 ForbiddenEdit commentce
/delete_comment❌403 ForbiddenDelete commentcd
/add_comment_vote❌403 ForbiddenAdd votecva
/remove_comment_vote❌403 ForbiddenRemove votecvr

Β§Events

APISupportNoteExample Name
/get_eventsβœ…Get eventsevents

Β§Forum

APISupportNoteExample Name
/reply_topic❌401 UnauthorizedReply to topicftr
/get_topics_listingβœ…Get topics listftlg
/create_topic❌401 UnauthorizedCreate topicftc
/get_topic_and_postsβœ…Get topic and postsftpg
/edit_topic❌403 ForbiddenEdit topicfte
/edit_post❌403 ForbiddenEdit postfpe
/get_forum_listingβœ…Get forum listflg
/get_forum_and_topicβœ…Get forum and topicftg

Β§Home

APISupportNoteExample Name
/searchβœ…Get homesearch

Β§Matches

APISupportNoteExample Name
/get_matches_listingβœ…Get match listmlg
/get_matchβœ…Get matchmg

Β§Multiplayer

APISupportNoteExample Name
/get_user_high_score❌403 ForbiddenGet user high scoremuhsg
/get_scoresβœ…Get multiple scoresmssg
/get_score❌403 ForbiddenGet scoremsg
/get_multiplayer_roomsβœ…Get roomsmrg

Β§News

APISupportNoteExample Name
/get_news_listingβœ…Get news listnlg
/get_news_postβœ…Get newsnpg

Β§Notifications

APISupportNoteExample Name
/get_notifications❌403 ForbiddenGet notificationsng
/mark_notifications_as_read❌403 ForbiddenMark as readnm

Β§Rankings

APISupportNoteExample Name
/get_rankingβœ…Get rankingrg
/get_kudosu_rankingβœ…Get Kudosu rankingrkg
/get_spotlightsβœ…Get spotlightsrsg

Β§Scores

APISupportNoteExample Name
/get_scoresβœ…Get up to 1000 scoresscores

Β§Users

APISupportNoteExample Name
/get_own_dataβœ…Get own user info (CCG)me
/get_user_kudosuβœ…Get user Kudosuukg
/get_user_scoresβœ…Get user scoresussg
/get_user_beatmaps, /get_user_beatmaps_most_playedβœ…Get user beatmap infoubsg
/get_user_recent_activityβœ…Get user recent activityurag
/get_user, /get_user_by_usernameβœ…Get user infoug
/get_usersβœ…Get multiple users infousg

Β§Wiki

APISupportNoteExample Name
/get_wiki_pageβœ…Get Wiki pagewiki

§❀️ Acknowledgements

Originally, this project was intended to directly use the rosu-v2 library, but at that time, I noticed that rosu-v2 hadn’t been updated for several months, and I wasn’t very comfortable with its project organization and usage patterns (possibly because rosu-v2 has a four-year history, with many early Rust code patterns in the library that aren’t very convenient to modify directly), so I decided to start from scratch and write my own;

During the development of osynic_osuapi, I still referenced the interface design of rosu-v2 (though not adopted) and some type choices (such as the selection between u64 and u32). Thanks to the authors of rosu-v2!

The rosu-v2 project is based on the MIT License, with the project license located in licenses/LICENSE-rosu-v2

§⚠️ Special Attention!!!

When using this library, the most common issues stem from changes in the official osu!API entity structure:

  • Entity structure changes: The structure of osu!API may change at any time, but the official documentation may not be updated promptly
  • Return field changes: The return fields of some interfaces may change, especially for less frequently used endpoints
  • Unexpected null values: Some fields may return null under certain conditions, but are not marked as optional in the documentation

The main reason for these issues is that the official osu!API documentation doesn’t provide comprehensive descriptions of entity properties. If you encounter parsing errors or type mismatches during use, please don’t hesitate to submit an Issue with the following information:

  1. The API endpoint used
  2. Request parameters
  3. Error message or exception stack trace

I will handle and update the library as quickly as possible to adapt to API changes. Most models in this library are built based on actual request response results, but there may still be omissions or errors. Your feedback is crucial for improving this library!

§🀝 Contribution Guidelines

This library is basically a module developed for the Osynic application, but it is also a complete Rust encapsulation of the osu!api.

Currently, the V1 API is fully supported, and the V2 API is almost complete(except for the undocumented modules).

The library is still in the early stages of development, and there may be some bugs or missing features.

So, if there is any problem with the code, or if you have any suggestions, please submit a PR or Issue, and I will deal with it as soon as possible~

If you want to contribute code, please follow these rules:

  • Follow the official Rust coding specifications
  • New features must be accompanied by test cases
  • Run cargo fmt and cargo clippy before submitting

Β§πŸ“œ License

This project is open source based on the MIT License, please respect the original author’s copyright.

ModulesΒ§

error
prelude
utils
v1
v2