Code Monkey home page Code Monkey logo

starlette-discord's Introduction

Starlette-Discord

"Login with Discord" support for Starlette and FastAPI

starlette-discord is a Discord OAuth2 module intended for use with Starlette and FastAPI.

Installing

starlette-discord can be installed with the command

# Linux
python3 -m pip install -U starlette-discord

# Windows
python -m pip install -U starlette-discord

To install the development version of the library directly from source:

$ git clone https://github.com/nwunderly/starlette-discord
$ cd starlette-discord
$ python3 -m pip install -U .

Quickstart

Below is an example FastAPI app implementing Discord's OAuth flow to identify the user.

import uvicorn
from fastapi import FastAPI
from starlette_discord import DiscordOAuthClient

client_id = "YOUR APP'S CLIENT ID HERE"
client_secret = "YOUR APP'S CLIENT SECRET HERE"
redirect_uri = "http://localhost:8000/callback"

app = FastAPI()
discord_client = DiscordOAuthClient(client_id, client_secret, redirect_uri)

@app.get('/login')
async def start_login():
    return discord_client.redirect()

@app.get('/callback')
async def finish_login(code: str):
    user = await discord_client.login(code)
    print(user)
    return user

uvicorn.run(app)

To begin the OAuth authorization flow with this app, visit http://localhost:8000/login.

starlette-discord's People

Contributors

barealek avatar beemoe5 avatar chrisdewa avatar nwunderly avatar vichannnnn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

starlette-discord's Issues

Package dependencies not configured on setup.py

This issue causes that installing the package from pip ( pip install -U starlette-discord) wont install the requirements as well, meaning you need to manually install discord.py, oauthlib and starlette.

Proposed fix: add the dependencies to the setup file.

Improvements to oauth.py

oauth.py is a bit of a mess at the moment. It's meant to be an internal class, and it's essentially just a port of a requests-based implementation that I pulled from a Gist a while ago. It's in desperate need of some love.

Any improvements to the file are welcome, and will be accepted as PRs. This issue will remain open until the file is fully improved.

Some ideas:

  • rewrite internal functions that aren't used by starlette-discord to fix bugs we've missed
  • reformat or rewrite documentation for the class and its methods (see #20)
  • general QOL changes to the class or its attributes/methods (breaking API changes will need to be justified and documented)

This is a bit of a more complicated task. It's likely something I'll revisit in the coming months, and (if necessary) just rewrite from scratch myself. That said, any improvements to library internals are always welcome.

Happy Hacktoberfest!! ๐Ÿ˜„

DiscordOAuthSession Lost access token should be preserved considering its longevity.

When the DiscordOAuthSession instance fetches the access_token on callback, the information contained in the token is this:

{'access_token': '...', 'expires_in': 604800, 'refresh_token': '...', 'scope': ['identify', 'guilds'], 'token_type': 'Bearer', 'expires_at': 1621962039.1969795}.

(tokens removed for obvious reasons).

This information is lost in the examples supplied but can be preserved in this way:

client = DiscordOAuthClient(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)
....

@app.get('/callback')
async def callback(code: str):    
    async with client.session(code) as session:
        token = session._discord_token  # notice protected attribute access

The expires_in field gives the amount of seconds that the token should last before it expires, in this case its 604800 which amounts to one week.

As follows, its unreasonable that the same token information cannot be used in following requests.

The DiscordOAuthSession instance must be able to be constructed from a valid token instead of only with the code

# following the client's construction
client = DiscordOAuthClient(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)

# sessions should be able to be constructed from the exchanged code on login redirect
session = client.session(code='dhjaksdhjadskhdaskjda')
# or with a stored, valid token
session = client.session(token='dsjkdsaljdaskldas')

Aditionally, it would also be useful if there was a token_updater method that would make use of the supplied refresh_token.

[Bug Report] TypeError: argument of type 'int' is not iterable

Code:

Traceback (most recent call last):
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 375, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\uvicorn\middleware\debug.py", line 96, in __call__
    raise exc from None
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\uvicorn\middleware\debug.py", line 93, in __call__
    await self.app(scope, receive, inner_send)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\fastapi\applications.py", line 208, in __call__
    await super().__call__(scope, receive, send)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette\applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
    raise exc
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette\exceptions.py", line 82, in __call__
    raise exc
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette\exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette\routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette\routing.py", line 259, in handle
    await self.app(scope, receive, send)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette\routing.py", line 61, in app
    response = await func(request)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\fastapi\routing.py", line 226, in app
    raw_response = await run_endpoint_function(
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\fastapi\routing.py", line 159, in run_endpoint_function
    return await dependant.call(**values)
  File "C:\Users\Dante\Documents\Mai\website\backend\main.py", line 104, in redirect
    user = await discord.login(code)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette_discord\client.py", line 292, in login
    user = await session.identify()
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette_discord\client.py", line 126, in identify
    data_user = await self._discord_request('/users/@me')
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette_discord\client.py", line 103, in _discord_request
    self._discord_token = await self.fetch_token(
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\starlette_discord\oauth.py", line 318, in fetch_token
    auth = aiohttp.BasicAuth(login=client_id, password=client_secret)
  File "C:\Users\Dante\AppData\Local\pypoetry\Cache\virtualenvs\mai-backend-h2M1C5Y5-py3.10\lib\site-packages\aiohttp\helpers.py", line 142, in __new__
    if ":" in login:
TypeError: argument of type 'int' is not iterable

Migrate data classes to Pydantic-based models

We want to make our data classes in models.py compatible with Pydantic in order to facilitate better interoperability with API and database use cases.

What would need to be done:

  • Add pydantic as a dependency
  • Make DiscordObject a subclass of pydantic's BaseModel class
  • Implement pydantic-compatible type hints in all data classes
  • Ensure that all data classes in that file are compliant with pydantic's type checking
  • No breaking changes to the actual library should be necessary for this

Happy Hacktoberfest! ๐Ÿ˜„

Cannot retrieve all data from guild

Hi, I'm currently trying to get all guild data that a user is a part of using

async with client.session(code) as session: user = await session.identify() guilds = await session.guilds() connections = await session.connections() print(guilds)

while following the examples to get an understanding of how to build my API, but I'm only getting the ID of the guild and the name are this a known issue or am I missing some steps

Fix inconsistent docstrings

Some documentation in oauth.py and client.py is documented using the wrong docstring style (generic RST format, we want NumPy style).

Need documentation for these methods reformatted. Bonus points for any additional improvements to documentation, like rewording or fixing formatting mistakes elsewhere.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.