shadertoy

Build Status Pub Package Coverage Status Package Documentation Github Stars GitHub License

Overview

The shadertoy library provides the support to interact with the Shadertoy site and REST API's defining the data model and contracts to query and store the shaders, comments, users, playlists and website media.

Features

  • :pushpin: REST API - Supports all the Shadertoy REST APIs (as defined here)
  • :globe_with_meridians: Site API - Supports scrapping of data directly from the Shadertoy site allowing the retrieval of users query comments, users, playlists and website media.
  • :link: Hybrid API - Respects public+api privacy settings of the shaders while providing support for additional operations, namely the retrieval of shader comments, user, playlists and website media
  • :loop: Extensible - Plug novel storage and client implementations reusing the APIs and entities defined on the shadertoy package

Client Implementations

The following client implementations are available

PackagePubDescription
shadertoy_clientPubHTTP client to the Shadertoy REST and Site API using the dio package

Storage Implementations

The following storage implementations are available

PackagePubDescription
shadertoy_sqlitePubA Sqlite storage implementation using the moor package

Getting Started

Select one of the client or storage implementations (or both) and add the package to your pubspec.yaml replacing x.x.x with the latest version of the implementation. The example below uses the shadertoy_client package which implements the shadertoy REST and site APIs:

dependencies:
    shadertoy_client: ^x.x.x

Run the following command to install dependencies:

dart pub get

Finally, to start developing import the library:

import 'package:shadertoy_client/shadertoy_client.dart';

Usage

Instantiate a ShadertoyClient implementation, for example the one provided by the package shadertoy_client to access the client API:

// Created a client to the REST API using the API key `apiKey`
final client = newShadertoyWSClient(apiKey);

and execute one of the methods provided, for example to obtain a shader by id execute the findShaderById method providing the id of the shader as parameter:

// Execute the call to the REST API
final result = await client.findShaderById('Mt3XW8');
// Check if there's errors
if (result.ok) {
    // Print the shader name if not
    print(fsr?.shader.name);
} else {
    // Prints the error message otherwise
    print('Error: ${result.error.message}')
}

In alternative instantiate a ShadertoyExtendedClient implementation, for example the one provided by the package shadertoy_client, to access the site API:

final client = newShadertoySiteClient();

and execute one of the methods provided, for example to obtain the shader comments by shader id execute the findCommentsByShaderId method providing the id of the shader as parameter:

// Execute the call to the site API
final result = await client.findCommentsByShaderId('MdX3Rr');
// Check if there's errors
if (result.ok) {
    // Prints the shader comments
  print(jsonEncode(result.comments));
} else {
    // Prints the error message otherwise
    print('Error: ${fsr.error.message}')
}

As mentioned in the feature list, to (optionally) respect the shader privacy constraints but still benefit from a larger set of operations (some of them available only through the site API), the hybrid API can be used. Start by instancianting a suitable hybrid API implementation, for example the one provided by the shadertoy_client package:

// Creates a hybrid client using the REST API key `apiKey`
// This effectivly filters the shaders and provides only the ones respecting the shader 
// `public+api` privacy settings
final client = newShadertoyHybridClient(apiKey: apiKey);

and execute one of the methods provided, for example to obtain a shader by id execute findShaderById providing the id of the shader as parameter:

// Execute the call to the hybrid API
final result = await client.findShaderById('3lsSzf');
// Check if there's errors
if (result.ok) {
    // Prints the shader id
    print(result.shader?.info.id);
} else {
    // Prints the error message otherwise
    print('Error: ${result.error.message}')
}

To create a database providing the same set of read operations as the previous APIs but also the ability to save shaders as well as other entities a ShadertoyStore contract is also provided. To make use of the ShadertoyStore a suitable implementation should be provided, for example, the one available on shadertoy_sqlite:

// Creates a new store with an in-memory executor
final store = newShadertoySqliteStore(memoryExecutor());

and execute one of the operations, for example storing a user:

// Create a user
final user = User(id: 'UzZ0Z1', about: 'About user 1', memberSince: DateTime.now());
// Save the user
final result = await store.saveUser(user);
// Check if there's errors
if (result.ok) {
    // Prints a success message
    print('Shader stored');
} else {
    // Prints the error message otherwise
    print('Error: ${response.error.message}')
}

APIs

  • The client API targetting the REST interfaces defined in the Shadertoy howto which allow the user to browse shaders available with public+api privacy settings. Note that the number of operations available with this API are limited albeit enough for simple browsing usage. To start using an API key needs to be obtained through a properly registered user on the apps page of the user section on the Shadertoy website.
  • The extended client API provides access to the same methods as the previous API but adds features that are only available on the site API, namely, the support to fetch users, playlists, shader comments and website media. Note that the shaders returned by this API are not constrained by the public+api privacy settings.
  • The hybrid API complements the basic client API allowing the base REST API client to benefit from the additional features os the extended client API still (optionally) respecting the public+api constrains imposed by the shader creators. In a nutshell it allows the REST API users to access user, shader comments and website media of the public+api shaders if configured with an API key
  • The store API, defines contracts supporting the creation of data stores thus providing a way to work offline with the downloaded shaders instead of relying on the Shadertoy APIs. It supports all the methods as the previous API plus the storage primitives.

Client API

OperationDescription
findShaderByIdFinds a shader by id
findShadersByIdSetFinds shaders by a set of ids
findShadersQueries shaders by term, tags and sort them by name, likes, views, newness and by hotness (proportional to popularity and inversely proportional to lifetime). All the query results are paginated through the from and num parameters
findAllShaderIdsFetches all the shader ids
findShaderIdsQueries shader ids by term, tags and sort them by name, likes, views, newness and by hotness (proportional to popularity and inversely proportional to lifetime). All the query results are paginated through the from and num parameters

Extended Client API

All the client API features plus the following:

OperationDescription
findUserByIdFinds a Shadertoy user by id
findShadersByUserIdQueries shaders by user id, tags and allows sorting by name, likes, views, newness and hotness (proportional to popularity and inversely proportional to lifetime). All the query results are paginated and the pages fetched with the from and num parameters
findShaderIdsByUserIdQueries shader ids by user id, tags and allows sorting by name, likes, views, newness and hotness (proportional to popularity and inversely proportional to lifetime). All the query results are paginated and the pages fetched with the from and num parameters
findAllShaderIdsByUserIdFetches all the shader ids by user id
findCommentsByShaderIdFetches the comments of a shader id
findPlaylistByIdFetches a playlist by id
findShadersByPlaylistIdFetches the shaders of a playlist id. All the query results are paginated through the from and num parameters
findShaderIdsByPlaylistIdFetches the shader ids of a playlist id. All the query results are paginated through the from and num parameters
findShaderIdsByPlaylistIdFetches all the shader ids of a playlist id

Hybrid Client

All the client and extendec client features but optionally constraining the requests to shaders with public+api privacy settings.

Store API

All the base and extended client API features plus the following:

OperationDescription
findAllUserIdsReturns all the stored user ids
findAllUsersReturns all the stored users
saveUserSaves a user
saveUsersSaves a list of users
deleteUserByIdDeletes a user by id
findAllShadersFetches all the shaders
saveShaderSaves a shader
saveShadersSaves a list of shaders
deleteShaderByIdDeletes a shader by id
findCommentByIdFetches a comment by id
findAllCommentIdsReturns all the comment ids
findAllCommentsReturns all the comments
saveShaderCommentsSaves a list of shader comments
deleteCommentByIdDeletes a comment by id
savePlaylistSaves a playlist
savePlaylistShadersAssociates a list of shader ids to a playlist
deletePlaylistByIdDeletes a playlist by id
findAllPlaylistIdsReturns all the playlist ids
findAllPlaylistsReturns all the playlists

Model

Shadertoy Model

Contributing

This is a unofficial Shadertoy client API. It is developed by best effort, in the motto of "Scratch your own itch!", meaning APIs that are meaningful for the author use cases.

If you would like to contribute with other parts of the API, feel free to make a Github pull request as I'm always looking for contributions for:

  • Tests
  • Documentation
  • New APIs

See CONTRIBUTING.md for ways to get started.

Features and Bugs

Please file feature requests and bugs at the issue tracker.

License

This project is licensed under the MIT License - see the LICENSE file for details

Libraries

shadertoy
A library defining the contracts and entities used to create clients and persistent stores based on the Shadertoy data model
shadertoy_util
A library defining a number of utilities to use with the shadertoy data model