Skip to content

A modern, well-documented osu! API v2 wrapper written in .NET/C#.

License

Notifications You must be signed in to change notification settings

minisbett/osu.NET

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

85 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

osu.NET

License NuGet NuGet API Coverage

A modern and well documented API wrapper for the osu! API v2.
This wrapper currently only supports public scope endpoints.

Installation โ€ข Getting Started โ€ข Contribute โ€ข API Coverage

Made with โค๏ธ by minisbett for the osu! community

โœจ Features

โœ”๏ธ Extensive API documentation โ€“ Detailed documentations, beyond the official API docs
โœ”๏ธ Seamless Integration โ€“ Designed with .NET Generic Host in mind
โœ”๏ธ Easy Error Handling โ€“ Result pattern for API responses with error-handling assistance
โœ”๏ธ Flexible Authentication Flow โ€“ Easy-to-use authorization infrastructure
โœ”๏ธ Actively Maintained โ€“ Contributions welcome!

๐Ÿ“ฆ Installation

osu.NET is available via NuGet:

# via the dotnet CLI
dotnet add package osu.NET

# via the Package Manager CLI
Install-Package osu.NET

๐Ÿš€ Getting Started

This library is primary designed to be integrated with the .NET Generic Host, but can also be used stand-alone.

Every API model and every endpoint is well documented, including:

  • Documentation of API properties and parameters, beyond what the osu! API documentation provides
  • References to the osu! API documentation and osu-web source-code
  • Information about the API errors to expect on each endpoint

For the authorization flow, there are multiple methods to choose from:

Authorization Provider Authorization Flow Usageโ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €โ €
OsuClientAccessTokenProvider Authorization using client ID & secret new(id, secret)
.FromEnvironmentVariables(id, secret)
OsuStaticAccessTokenProvider Authorization using a static access token new(accessToken)
OsuDelegateAccessTokenProvider Authorization using an access token provided via a delegate (eg. for fetching from a database) new(cancellationToken => ...)

Tip

You can also write your own access token provider by inheriting IOsuAccessTokenProvider.

โš™๏ธ Using osu.NET with the .NET Generic Host

The API wrapper provides extension methods for registering the OsuApiClient as a scoped service. The access tokens are provided via an IOsuAccessTokenProvider instance provided on service registration, optionally the API client can be configured too.

Example:

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((context, services) =>
    {
        services.AddHostedService<TestService>();
        services.AddOsuApiClient(
            OsuClientAccessTokenProvider.FromEnvironmentVariables("OSU_ID", "OSU_SECRET"),
            (options, services) =>
            {
                options.EnableLogging = true;
            });
    })
  .Build();

The OsuApiClient can then be consumed via dependency injection:

public class TestService(OsuApiClient client) : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        ApiResult<UserExtended> result = await client.GetUserAsync("mrekk", cancellationToken);
    }
}

๐Ÿ—๏ธ Using osu.NET stand-alone

To use the OsuApiClient without the .NET Generic Host, there are some considerations to be made.

In order to get started, you create an instance of the IOsuAccessTokenProvider providing the desired authorization flow, and using that you create an instance of the OsuApiClient:

OsuClientAccessTokenProvider provider = OsuClientAccessTokenProvider
    .FromEnvironmentVariables("OSU_ID", "OSU_SECRET");

OsuApiClientOptions options = new()
{
    EnableLogging = false // false by default, do *not* set it to true for stand-alone usage
};

OsuApiClient client = new(provider, options, null! /* ILogger, set to null for stand-alone usage*/);

Important

Since the logging is based on the Microsoft.Extensions.Logging.ILogger<T>, a part of the .NET Generic Host, logging needs to be disabled and the logger set to null.

โš ๏ธ Error Handling

The API endpoint methods return an ApiResult<T>, wrapping the data returned from the osu! API (.Value) and alternatively providing the API error if one was returned (.Error).

The error message provided by the API is interpreted into an ApiErrorType for common errors, allowing to handle different errors in individual ways. Furthermore, the ApiResult<T> type provides a Match method, allowing to match the result for the returned value if the request succeeded, or for the ApiError if the requested failed.

Note

The xmldocs for the API endpoint methods always provide the ApiErrorType the endpoints are expected to return, as well as when they do it, so you always know which errors to expect.

Here is an example on how to handle the response of a GetUserBeatmapScoreAsync API request:

ApiResult<UserBeatmapScore> result = await client.GetUserBeatmapScoreAsync(4697929, 7562902);

// You can also return a value inside the result matching lambdas, eg.:
// double? pp = result.Match<double>(value => value?.Score.PP, error => null);
result.Match(
    value => logger.LogInformation("PP: {PP}", value?.Score.PP,
    error => error.Type switch
    {
        ApiErrorType.BeatmapNotFound => logger.LogError("Beatmap not found."),
        ApiErrorType.UserOrScoreNotFound => logger.LogError("User not found or has no score."),
        _ => logger.LogError("{Message}", error.Message)
    })
);

Tip

osu.NET provides a roslyn code analyzer for assisting with result-matching. If you match a result with the exact syntax above, matching the error directly with a error.Type switch {...}, the code analyzer will warn you if you have an unhandled ApiErrorType possibly returned by the API endpoint called.

This feature is experimental and the warning can be disabled via #pragma warning disable OSU001, or as suggested by your IDE.

๐ŸŒฑ Contribute

This library is continuously maintained, and contributions are always welcome. Whether it's improving documentation, adding new features, or updating existing code, every contribution helps keep the project up-to-date and easy-to-use.

๐Ÿ“ Improve Documentation
Some parts of the documentation are still missing. If you encounter some, and you can provide information about it, any contributions filling the gaps are much appreciated!

๐Ÿ”ง Add or Update API Endpoints
Not all endpoints the API provides are implemented. If you require a missing endpoint, feel free to propose it using a GitHub issue or implement it via a pull request. Similarily, feel free to contribute if you notice an outdated endpoint, as the osu! API evolves over time.

๐Ÿ†™ Update API Models
If any API models are outdated due to changes in the osu! API, feel free to report it via a GitHub issue or update them via a pull request.

๐Ÿ—ฃ๏ธ Report Issues
If something isn't working as expected, open an issue with a detailed description so the problem can be addressed promptly.

๐Ÿ“œ API Coverage

Below is a list of all planned and implemented osu! API endpoints. If you'd like to suggest a missing endpoint or add one yourself, feel free to create an issue or pull request.

โœ… = Implemented | โŒ = Not Implemented | ๐Ÿ”Ž = Undocumented in official docs

Beatmap Packs ๐ŸŽต

  • โœ… /beatmaps/packs
  • โœ… /beatmaps/packs/{tag}

Beatmaps ๐ŸŽผ

  • โœ… /beatmaps?id[]
  • โœ… /beatmaps/lookup?checksum
  • โœ… /beatmaps/lookup?filename
  • โœ… /beatmaps/{beatmap}
  • โœ… /beatmaps/{beatmap}/attributes
  • โœ… /beatmaps/{beatmap}/scores
  • โœ… /beatmaps/{beatmap}/scores/users/{user}
  • โœ… /beatmaps/{beatmap}/scores/users/{user}/all

Discussions ๐Ÿ—จ๏ธ

  • โŒ /beatmapsets/discussions/posts
  • โŒ /beatmapsets/discussions/votes
  • โŒ /beatmapsets/discussions

Beatmap Sets ๐Ÿ“ฆ

  • โŒ /beatmapsets/search
  • โœ… /beatmapsets/lookup
  • โœ… /beatmapsets/{beatmapset}
  • โŒ /beatmapsets/events๐Ÿ”Ž

Changelogs ๐Ÿ“œ

  • โœ… /changelog
  • โœ… /changelog/{buildOrStream}
  • โœ… /changelog/{stream}/{build}

Comments ๐Ÿ’ฌ

  • โœ… /comments
  • โœ… /comments/{comment}

Events ๐Ÿ“…

  • โœ… /events

Forums ๐Ÿ“

  • โŒ /forums/topics
  • โŒ /forums/topics/{topic}
  • โœ… /forums
  • โœ… /forums/{forum}

Home ๐Ÿ 

  • โŒ /search

Matches ๐ŸŽฎ

  • โœ… /matches
  • โœ… /matches/{match}

Multiplayer ๐ŸŒ

  • โŒ /rooms/{room}/playlist/{playlist}/scores
  • โŒ /rooms/{room}๐Ÿ”Ž

News ๐Ÿ“ฐ

  • โœ… /news
  • โœ… /news/{news}
  • โœ… /news/{news}?id

Rankings ๐Ÿ†

  • โœ… /rankings/kudosu
  • โŒ /rankings/{mode}/{type}
  • โœ… /spotlights

Scores ๐Ÿ“Š

  • โœ… /scores
  • โœ… /scores/{ruleset}/{score}๐Ÿ”Ž
  • โœ… /scores/{score}๐Ÿ”Ž
  • โœ… /scores/{score}/download๐Ÿ”Ž

Users ๐Ÿ‘ค

  • โœ… /users/{user}/kudosu
  • โœ… /users/{user}/scores/{type}
  • โœ… /users/{user}/beatmapsets/{type}
  • โœ… /users/{user}/recent_activity
  • โœ… /users/{user}/{mode?}
  • โœ… /users?id[]
  • โœ… /users/lookup๐Ÿ”Ž

Wiki ๐Ÿ“–

  • โœ… /wiki/{locale}/{path}

Other โญ

  • โœ… /seasonal-backgrounds๐Ÿ”Ž
  • โœ… /tags๐Ÿ”Ž

About

A modern, well-documented osu! API v2 wrapper written in .NET/C#.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages