• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

praw-dev / praw / 3768928224

pending completion
3768928224

Pull #1923

github

GitHub
Merge 33b610e6e into ffe9f71d6
Pull Request #1923: Improve tests, clean up test code, and sort test functions/classes

4109 of 4109 relevant lines covered (100.0%)

4.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/praw/models/auth.py
1
"""Provide the Auth class."""
2
from typing import Dict, List, Optional, Set, Union
4✔
3

4
from prawcore import Authorizer, ImplicitAuthorizer, UntrustedAuthenticator, session
4✔
5

6
from ..exceptions import InvalidImplicitAuth, MissingRequiredAttributeException
4✔
7
from ..util import _deprecate_args
4✔
8
from .base import PRAWBase
4✔
9

10

11
class Auth(PRAWBase):
4✔
12
    """Auth provides an interface to Reddit's authorization."""
13

14
    @property
4✔
15
    def limits(self) -> Dict[str, Optional[Union[str, int]]]:
4✔
16
        """Return a dictionary containing the rate limit info.
17

18
        The keys are:
19

20
        :remaining: The number of requests remaining to be made in the current rate
21
            limit window.
22
        :reset_timestamp: A unix timestamp providing an upper bound on when the rate
23
            limit counters will reset.
24
        :used: The number of requests made in the current rate limit window.
25

26
        All values are initially ``None`` as these values are set in response to issued
27
        requests.
28

29
        The ``reset_timestamp`` value is an upper bound as the real timestamp is
30
        computed on Reddit's end in preparation for sending the response. This value may
31
        change slightly within a given window due to slight changes in response times
32
        and rounding.
33

34
        """
35
        data = self._reddit._core._rate_limiter
4✔
36
        return {
4✔
37
            "remaining": data.remaining,
38
            "reset_timestamp": data.reset_timestamp,
39
            "used": data.used,
40
        }
41

42
    def authorize(self, code: str) -> Optional[str]:
4✔
43
        """Complete the web authorization flow and return the refresh token.
44

45
        :param code: The code obtained through the request to the redirect uri.
46

47
        :returns: The obtained refresh token, if available, otherwise ``None``.
48

49
        The session's active authorization will be updated upon success.
50

51
        """
52
        authenticator = self._reddit._read_only_core._authorizer._authenticator
4✔
53
        authorizer = Authorizer(authenticator)
4✔
54
        authorizer.authorize(code)
4✔
55
        authorized_session = session(authorizer)
4✔
56
        self._reddit._core = self._reddit._authorized_core = authorized_session
4✔
57
        return authorizer.refresh_token
4✔
58

59
    @_deprecate_args("access_token", "expires_in", "scope")
4✔
60
    def implicit(self, *, access_token: str, expires_in: int, scope: str) -> None:
4✔
61
        """Set the active authorization to be an implicit authorization.
62

63
        :param access_token: The access_token obtained from Reddit's callback.
64
        :param expires_in: The number of seconds the ``access_token`` is valid for. The
65
            origin of this value was returned from Reddit's callback. You may need to
66
            subtract an offset before passing in this number to account for a delay
67
            between when Reddit prepared the response, and when you make this function
68
            call.
69
        :param scope: A space-delimited string of Reddit OAuth2 scope names as returned
70
            from Reddit's callback.
71

72
        :raises: :class:`.InvalidImplicitAuth` if :class:`.Reddit` was initialized for a
73
            non-installed application type.
74

75
        """
76
        authenticator = self._reddit._read_only_core._authorizer._authenticator
4✔
77
        if not isinstance(authenticator, UntrustedAuthenticator):
4✔
78
            raise InvalidImplicitAuth
4✔
79
        implicit_session = session(
4✔
80
            ImplicitAuthorizer(authenticator, access_token, expires_in, scope)
81
        )
82
        self._reddit._core = self._reddit._authorized_core = implicit_session
4✔
83

84
    def scopes(self) -> Set[str]:
4✔
85
        """Return a set of scopes included in the current authorization.
86

87
        For read-only authorizations this should return ``{"*"}``.
88

89
        """
90
        authorizer = self._reddit._core._authorizer
4✔
91
        if not authorizer.is_valid():
4✔
92
            authorizer.refresh()
4✔
93
        return authorizer.scopes
4✔
94

95
    @_deprecate_args("scopes", "state", "duration", "implicit")
4✔
96
    def url(
4✔
97
        self,
98
        *,
99
        duration: str = "permanent",
100
        implicit: bool = False,
101
        scopes: List[str],
102
        state: str,
103
    ) -> str:
104
        """Return the URL used out-of-band to grant access to your application.
105

106
        :param duration: Either ``"permanent"`` or ``"temporary"`` (default:
107
            ``"permanent"``). ``"temporary"`` authorizations generate access tokens that
108
            last only 1 hour. ``"permanent"`` authorizations additionally generate a
109
            refresh token that expires 1 year after the last use and can be used
110
            indefinitely to generate new hour-long access tokens. This value is ignored
111
            when ``implicit=True``.
112
        :param implicit: For **installed** applications, this value can be set to use
113
            the implicit, rather than the code flow. When ``True``, the ``duration``
114
            argument has no effect as only temporary tokens can be retrieved.
115
        :param scopes: A list of OAuth scopes to request authorization for.
116
        :param state: A string that will be reflected in the callback to
117
            ``redirect_uri``. This value should be temporarily unique to the client for
118
            whom the URL was generated for.
119

120
        """
121
        authenticator = self._reddit._read_only_core._authorizer._authenticator
4✔
122
        if authenticator.redirect_uri is self._reddit.config.CONFIG_NOT_SET:
4✔
123
            raise MissingRequiredAttributeException("redirect_uri must be provided")
4✔
124
        if isinstance(authenticator, UntrustedAuthenticator):
4✔
125
            return authenticator.authorize_url(
4✔
126
                "temporary" if implicit else duration,
127
                scopes,
128
                state,
129
                implicit=implicit,
130
            )
131
        if implicit:
4✔
132
            raise InvalidImplicitAuth
4✔
133
        return authenticator.authorize_url(duration, scopes, state)
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc