draw 0.8.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 81

DRAW: The Dart Reddit API Wrapper #

Build Status Pub Version Coverage Status Join Gitter Chat Channel -

DRAW, also known as the Dart Reddit API Wrapper, is a Dart package that provides simple access to the Reddit API. DRAW is inspired by PRAW, the Python Reddit API Wrapper, and aims to also maintain a similar interface.

Want to get involved? Check out how to contribute to get started!

Disclaimer: This is not an official Google product.

Installation #

Installing DRAW is simple using Dart's package management system, pub. Instructions on how to import DRAW into your project can be found here. If you would prefer to live on the hemorrhaging-edge, methods to depend on a local copy of DRAW or on the Github repository can be found here.

Getting Started #

Assuming you already have your Reddit OAuth credentials, getting started with DRAW is simple:

import 'dart:async';
import 'package:draw/draw.dart';

Future<void> main() async {
  // Create the `Reddit` instance and authenticated
  Reddit reddit = await Reddit.createScriptInstance(
    clientId: CLIENT_ID,
    clientSecret: SECRET,
    userAgent: AGENT_NAME,
    username: "DRAWApiOfficial",
    password: "hunter12", // Fake
  );

  // Retrieve information for the currently authenticated user
  Redditor currentUser = await reddit.user.me();
  // Outputs: My name is DRAWApiOfficial
  print("My name is ${currentUser.displayName}");
}

This simple example is a great way to confirm that DRAW is working and that your credentials have been configured correctly.

Web Authentication #

To authenticate via the Reddit authentication page, the web authentication flow needs to be used. This requires that a web application is registered with a valid Reddit account, which provides a client-id and a client-secret. As part of this process, a redirect URL is associated with the registered web application. These three values are all that is needed to complete the web authentication flow.

Here is a simple example of how to use web authentication with DRAW:

import 'package:draw/draw.dart';

main() async {
  final userAgent = 'foobar';
  final configUri = Uri.parse('draw.ini');

  // Create a `Reddit` instance using a configuration file in the
  // current directory.
  final reddit = Reddit.createWebFlowInstance(userAgent: userAgent,
                                              configUri: configUri);

  // Build the URL used for authentication. See `WebAuthenticator`
  // documentation for parameters.
  final auth_url = reddit.auth.url(['*'], 'foobar');

  // ...
  // Complete authentication at `auth_url` in the browser and retrieve
  // the `code` query parameter from the redirect URL.
  // ...

  // Assuming the `code` query parameter is stored in a variable
  // `auth_code`, we pass it to the `authorize` method in the
  // `WebAuthenticator`.
  await reddit.auth.authorize(auth_code);

  // If everything worked correctly, we should be able to retrieve
  // information about the authenticated account.
  print(await reddit.user.me());
}

It is also possible to restore cached credentials in order to avoid the need to complete the web authentication flow on each run:

import 'package:draw/draw.dart';

// Provides methods to load and save credentials.
import 'credential_loader.dart';

main() async {
  final userAgent = 'foobar';
  final configUri = Uri.parse('draw.ini');

  // Load cached credentials from disk, if available.
  final credentialsJson = await loadCredentials();

  var reddit;

  if (credentialsJson == null) {
    reddit =
        await Reddit.createWebFlowInstance(userAgent: userAgent,
                                           configUri: configUri);

    // Build the URL used for authentication. See `WebAuthenticator`
    // documentation for parameters.
    final auth_url = reddit.auth.url(['*'], 'foobar');

    // ...
    // Complete authentication at `auth_url` in the browser and retrieve
    // the `code` query parameter from the redirect URL.
    // ...

    // Assuming the `code` query parameter is stored in a variable
    // `auth_code`, we pass it to the `authorize` method in the
    // `WebAuthenticator`.
    await reddit.auth.authorize(auth_code);

    // Write credentials to disk.
    await writeCredentials(reddit.auth.credentials.toJson());
  } else {
    // Create a new Reddit instance using previously cached credentials.
    reddit = Reddit.restoreAuthenticatedInstance(
        userAgent: userAgent,
        configUri: configUri,
        credentialsJson: credentialsJson);
  }

  // If everything worked correctly, we should be able to retrieve
  // information about the authenticated account.
  print(await reddit.user.me());
}

Installed Application Authentication #

For usage in environments where it is impossible to keep a client secret secure, the installed application flow should be used. This requires that an installed application is registered with a valid Reddit account, which provides a client-id. As part of this process, a redirect URL is associated with the registered installed application. These two values are all that is needed to complete the installed application authentication flow.

The installed application authentication flow is almost identical to the web authentication flow described above, and it is also possible to save and restore credentials for installed applications in a similar fashion.

Here is a simple example of how to use the installed application authentication flow with DRAW:

import 'package:draw/draw.dart';

main() async {
  final userAgent = 'foobar';
  final configUri = Uri.parse('draw.ini');

  // Create a `Reddit` instance using a configuration file in the current
  // directory. Unlike the web authentication example, a client secret does
  // not need to be provided in the configuration file.
  final reddit = Reddit.createInstalledFlowInstance(userAgent: userAgent,
                                                    configUri: configUri);

  // Build the URL used for authentication. See `WebAuthenticator`
  // documentation for parameters.
  final auth_url = reddit.auth.url(['*'], 'foobar');

  // ...
  // Complete authentication at `auth_url` in the browser and retrieve
  // the `code` query parameter from the redirect URL.
  // ...

  // Assuming the `code` query parameter is stored in a variable
  // `auth_code`, we pass it to the `authorize` method in the
  // `WebAuthenticator`.
  await reddit.auth.authorize(auth_code);

  // If everything worked correctly, we should be able to retrieve
  // information about the authenticated account.
  print(await reddit.user.me());
}

DRAW Configuration Files (draw.ini) #

Here's an example draw.ini suitable for web based authentication:

default=default
reddit_url='https://www.reddit.com'
oauth_url=https://oauth.reddit.com
redirect_uri=https://www.google.com
client_id=YOUR_CLIENT_ID_HERE
client_secret=YOUR_SECRET_HERE
userAgent=draw_testing_agent

Here the redirect URI is set to https://www.google.com, but you'll need to replace that with whatever redirect you have registered.

The format of draw.ini configuration files is very similar to that of praw.ini files used by PRAW, although there may be some minor differences due to the .ini parser used by DRAW.

Frequently Asked Questions (FAQ) #

Q: "I'm having trouble authenticating. What's wrong?" #

Assuming the build status of DRAW is passing, there's likely something wrong with your credentials or user-agent. Here's some things to check:

  • Ensure your client ID and client secret match those provided by Reddit, applicable for your use case.
  • Try a new value for userAgent. Reddit rejects requests with commonly used user-agents like "foobar", "testing", or "reddit", so try using a randomly generated user-agent to make sure this isn't the issue you're seeing.

License #

DRAW is provided under a BSD 3-clause license. Copyright (c), 2017, the DRAW Project Authors and Google LLC.

Change Log #

Version 0.8.0 (2019/10/01) #

  • Added support for Dart for Web and Flutter Web.

Version 0.7.1 (2019/08/26) #

  • Added 'best' sorting option to FrontPage.
  • Added Reddit.restoreInstalledAuthenticatedInstance which allows for restoring an OAuth context created for an installed application instance that does not require a client secret.

Version 0.7.0 (2019/07/29) #

Breaking changes: #

  • DRAW now requires a Dart SDK with version 2.2.2 or newer.

Other changes: #

  • Added isContinueThisThread and isLoadMoreComments properties to MoreComments to make it easier to differentiate between different types of MoreComment responses from the Reddit API.
  • Added Subreddits class which contains streams for subreddits and subreddit search functionality.
  • Added over18 getter to Subreddit.
  • Added after parameter to stream generators.
  • Add limit parameters to stream generators to change number of elements returned per request.

Version 0.6.0 (2019/07/08) #

Breaking changes: #

  • Reddit.restoreAuthenticatedInstance now returns Reddit instead of Future<Reddit>.

Other changes: #

  • Reddit.restoreAuthenticatedInstance no longer throws an exception when not provided a clientSecret. A clientSecret is still required for most client types except for installed applications.
  • Updated dependencies.

Version 0.5.2+1 (2019/05/31) #

  • Updated documentation.

Version 0.5.2 (2019/05/31) #

  • Added optional waitForResponse to clearVote, downvote, and upvote, which allows for these calls to complete without waiting for a response from Reddit.
  • Added Reddit.createInstalledFlowInstance to help with authenticating installed applications with no client secret.

Version 0.5.1+1 (2019/05/17) #

  • Fixed analysis issues.

Version 0.5.1 (2019/05/17) #

  • Added basic implementation of SubredditStyleSheet that allows for simple stylesheet management.
  • Added RedditorRef.trophies method for retrieving user trophies.
  • Fixed issue where MoreComments was not being correctly expanded to a subtree of CommentForest
  • Fixed issue where MoreComments was not being removed from a CommentForest after being expanded.
  • Miscellaneous documentation updates.

Version 0.5.0 (2019/01/07) #

Dart SDK 2.1 or newer is now required to use DRAW.

Breaking changes: #

  • All mixin classes have been updated to use the new mixin keyword.
  • Removed the following deprecated fields:
    • likes property in Submission.
    • gilded property in UserContentInitialized.

Version 0.4.6 (2019/11/02) #

  • Added support for handling wiki pages:
    • Added SubredditWiki, which provides a set of wiki related functions to SubredditRef and Subreddit.
    • Added WikiPageRef and WikiPage which represent and allow for modification of wiki pages.
    • Added WikiEdit, a class which represents edits made to a wiki page.
    • Added WikiPermissionLevel enum, which describes all valid permissions available to control editing and viewing of wiki pages.
    • Added WikiPageSettings, a representation of all settings for a wiki page.
    • Added WikiPageModeration, a helper class for updating settings for a wiki page.
  • Added support for new Reddit Silver, Gold, and Platinum.

Deprecation Notice (Removal in 0.5.0) #

  • Marked gilded property of UserContentInitialized as deprecated.

Version 0.4.5 (2019/10/20) #

  • Added ModeratorRelationship, a class that allows for management of moderators for a subreddit.
  • Added moderator parameter to Subreddit that returns an instance of ModeratorRelationship for the given subreddit.
  • Added sort parameter to Submission.refreshComments to allow for different comment sorting methods.

Version 0.4.4 (2019/10/06) #

  • Added Modmail, ModmailConversation, ModmailMessage, ModmailAction and ModmailActionType, which can be used to perform mod-mail actions.
  • Added vote getter to Submission to be consistent with Comment.

Deprecation Notice (Removal in 0.5.0) #

  • Marked likes getter in Submission as deprecated.

Version 0.4.3 (2019/09/23) #

  • Added nsfw and spoiler parameters to Subreddit.submit (Thanks @LucasCLuk!)
  • Fixed issue where exceptions generated during client authentication could not be caught.

Version 0.4.2 (2018/09/10) #

  • Added support for flair. See documentation for SubredditFlair and SubmissionFlair for details.
  • Updated dependency versions for Dart 2.0.

Bug fixes:

  • PreviewImage now automatically replaces $amp; with $ (Issue #104).
  • Cleaned up various analyzer failures.

Version 0.4.0 (2018/09/01) #

Major breaking changes: #

Reddit.createInstance has been removed. Please use one of the following static methods instead:

  • createReadOnlyInstance
  • createScriptInstance
  • createUntrustedReadOnlyInstance
  • createWebFlowInstance
  • restoreAuthenticatedInstance

Other changes: #

  • Bumped SDK constraints to reflect official Dart 2.0 release.
  • Added SubmissionPreview and PreviewImage which represent preview images for a Submission.
  • Added preview to Submission, which returns a List<SubmissionPreview>.
  • Fixed various bugs discovered while improving code coverage.

Version 0.3.4 (2018/06/12) #

Deprecation Notice: #

Reddit.createInstance has been deprecated and will be removed in the 0.4.0 release. Please use one of the following static methods instead:

  • createReadOnlyInstance
  • createScriptInstance
  • createUntrustedReadOnlyInstance
  • createWebFlowInstance
  • restoreAuthenticatedInstance

Other changes: #

  • Added the following static methods to Reddit:
    • createWebFlowInstance
  • Added live tests to exercise the web implicit grant flow authentication mode.

Version 0.3.3 (2018/06/08) #

  • Added the following static methods to Reddit:

    • createReadOnlyInstance
    • createScriptInstance
    • createUntrustedReadOnlyInstance

    This should make creating Reddit instances simpler and easier to debug.

  • Added live tests to exercise the read-only and script authentication modes.

Version 0.3.2 (2018/05/07) #

Bug fixes:

  • Fixed additional Dart 2 runtime type errors.

Version 0.3.1 (2018/05/06) #

Bug fixes:

  • Fixed exception thrown from WebAuthenticator when running in Dart 2.

Version 0.3.0 (2018/05/05) #

Major breaking changes: #

Dropped support for Dart 1.x. Flutter has moved to enable Dart 2 by default which required some changes in DRAW that are not compatible with Dart 1.x. Some of these changes required some method signatures to be modified, but this shouldn't require any changes for users.

If running in a command-line script, that script must be run using a dev SDK while passing the --preview-dart-2 flag.

If used in a Flutter application, --preview-dart-2 is enabled by default as of the Flutter Beta 2 release.

Functionality: #

  • Basic Multireddit functionality:
    • Added Multireddit.parse(reddit, data) constructor that will create an instance of a Multireddit, given the correct Map of data.
    • Added add(subreddit) method to add the corresponding subreddit to the instance of Multireddit. subreddit can be of type Subreddit or String.
    • Added delete() method to delete the multireddit.
    • Added copy() and copy(multiName), this will create a copy of the Multireddit for for the currently authenticated user and return an instance of the new Multireddit encapsulated as a Future. When multiName is provided it will set the display name of the new Multireddit to multiName.
    • Added getters for the following properties: keyColor, iconName, subreddits, author displayName, visibility, weightingScheme, canEdit, over18.
  • Comment and Submission moderation.
  • Miscellaneous bug fixes.

Version 0.2.1 (2018/04/17) #

  • Added Reddit.comment, which allows for the creation of CommentRef objects from a comment ID or url.
  • Added CommentRef.populate and Comment.refresh.
  • Added likes getter to Submission.
  • Miscellaneous fixes for minor bugs related to CommentForest.

Version 0.2.0 (2018/04/13) #

Breaking changes:

  • Subreddit.submissions has been removed as the Reddit API endpoint no longer exists. See this post for context.

Miscellaneous:

  • Added initial support for Fuchsia. draw.ini configurations are not yet supported on this platform.
  • Loosened some version restrictions for pub packages.

Version 0.1.6 (2018/04/08) #

  • Added the property Reddit.front, which exposes methods to retrieve content from the Reddit front page.

Version 0.1.5 (2018/04/03) #

  • Added Reddit.restoreAuthenticatedInstance, which can be used to create a Reddit instance from previously cached credentials.
  • Documentation improvements.
  • Various bug fixes.

Version 0.1.4 (2018/03/31) #

  • Added SubredditModeration, a class which implements moderator functionality for Subreddits.
  • Fixed issue #46 which was causing WebAuthenticator.url to hit an assertion when compactLogin was set to true.

Version 0.1.3 (2018/03/22) #

  • Added additional convenience accessors to various classes, including Comment, Redditor, Submission, and Subreddit.
  • Added classes SubredditFilters and SubredditQuarantine.

Version 0.1.2 (2018/03/04) #

Breaking changes:

  • Removed property method. Properties of initialized objects that do not yet have convenience accessors can be accessed through the data property
  • Removed fullname, id, and data fields from lazily initialized objects
  • Removed refresh() from lazily initialized objects

Miscellaneous:

  • Improved documentation
  • Various internal refactoring

Version 0.1.1 (2018/03/03) #

Minor bug fix:

  • Fixed issue where DRAWConfigContext would throw an exception on Android and iOS.

Version 0.1.0 (2018/03/03) #

Breaking changes:

  • Created separate classes for lazily initialized and initialized instances
  • Deprecated the property method. Will be completely removed in the near future

Major changes and bug fixes:

  • Added Inbox and Message functionality
  • Added convenience accessors for common properties. Properties without an accessor can be accessed through the data map in each object
  • Additional fixes to DRAWConfigContext
  • Rolled package:quiver forward to version 0.28.0 to match that used by flutter_test

Version 0.0.3 (2018/01/22) #

Minor changes and bug fixes:

  • Fixed bug that caused authentication to fail when using draw.ini with the ScriptAuthenticator
  • Refactored DRAWConfigContext

Version 0.0.2 (2017/12/15) #

Minor updates:

  • Added CHANGELOG.md
  • Formatted sample code in README.md
  • Renamed .analysis_options to analysis_options.yaml
  • Documentation added for classes and methods that had none
  • Commented out currently unimplemented functionality to clean up generated documents

Version 0.0.1 (2017/12/08) #

Initial release with basic functionality, including:

  • OAuth2 support for login
  • Comment, Redditor, and Subreddit interfaces

example/example.dart

// Copyright (c) 2018, the Dart Reddit API Wrapper project authors.
// Please see the AUTHORS file for details. All rights reserved.
// Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

import 'dart:async';
import 'package:draw/draw.dart';

String kClientId;
String kSecret;
String kAgentName;

Future<void> main() async {
  // Create the `Reddit` instance and authenticate
  final Reddit reddit = await Reddit.createScriptInstance(
    clientId: kClientId,
    clientSecret: kSecret,
    userAgent: kAgentName,
    username: "DRAWApiOfficial",
    password: "hunter12", // Fake
  );

  // Retrieve information for the currently authenticated user
  final Redditor currentUser = await reddit.user.me();
  // Outputs: My name is DRAWApiOfficial
  print("My name is ${currentUser.displayName}");
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  draw: ^0.8.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:draw/draw.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
61
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
81
Learn more about scoring.

We analyzed this package on Oct 21, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.1
  • pana: 0.12.21

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:draw/draw.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.2 <3.0.0
collection ^1.14.3 1.14.12
color ^2.1.1 2.1.1
http ^0.12.0 0.12.0+2
ini ^2.0.0 2.0.1
logging ^0.11.3+1 0.11.3+2
oauth2 ^1.1.0 1.4.0
path ^1.4.2 1.6.4
quiver >=2.0.0 <3.0.0 2.0.5
Transitive dependencies
async 2.4.0
charcode 1.1.2
http_parser 3.1.3
matcher 0.12.6
meta 1.1.7
source_span 1.5.5
stack_trace 1.9.3
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
Dev dependencies
mockito ^3.0.0
pedantic 1.7.0 1.8.0+1
reply ^0.1.2-dev
test ^1.3.0