I'm currently using facebook GraphApi (imported with facepy) to build a crawler that extracts information from a group that is not mine. Since facebook's API v2.5 doesn't support extracting information from a group that is not mine, I'm forced to used an older version. My question is, how can I extend my personal token lifetime, taking into account that I can't create an app because it forces me to use the most recent API version. I'll drop the code below:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import facebook
from facepy import GraphAPI
from facepy import get_extended_access_token
import json
import schedule
import time
group_id = "the group id" #grupo operações stop coimbra https://www.facebook.com/groups/operacaostopcoimbra/
access_token = "access token i took from facebook developers"
class Crawler():
def __init__(self, access_token):
self._access_token = access_token
def crawl(self):
graph = GraphAPI(self._access_token) #aceder à GraphAPI
extended_token = get_extended_access_token(access_token, APP ID, APP SECRET) #PROBLEM IS HERE!
print extended_token
data = graph.get(group_id + "/feed", page=False, retry=3, limit=25)
data = self._parseJson(data)
return data
def _parseJson(self, data):
if data["data"][0]["message"]:
return data["data"][0]["from"]["name"] + " " + data["data"][0]["from"]["id"] + " " + data["data"][0]["message"]
else:
return None
result = Crawler(access_token)
schedule.every(1).minutes.do(result.crawl())
while 1:
schedule.run_pending()
time.sleep(1)
Seems like, no app, no token...
Related
I write code for Replit.com
i make a command /add_administrator that is, Ana must add the user ID of the user I mentioned to the file admins.json but after using the command the bot breaks What I understand the bot sees(/add_administrator)
(#user)ignore or not see
I would like to understand how to get the user id through a #mention
It will be in a different language full code :https://github.com/jonoto2/TeleBotPHP/blob/main/main.py
complete command code:
from webserver import keep_alive
import json
import random
import re
import os
import telebot
from telebot import types
#from telegram.ext import Updater
bot = telebot.TeleBot(os.environ['TOKEN'], parse_mode="HTML")
#bot.message_handler(commands=['add_adm'])
def add_adm(message):
# Check if user is admin
if is_admin(int(message.from_user.id)):
args = get_args(message.text)
# Check for args
if args and args[0].isdigit():
id = int(args[0])
with open('admins.json', "r") as jsonFile:
data = json.load(jsonFile)
if id not in data:
data.append(id)
with open("admins.json", "w") as jsonFile:
json.dump(data, jsonFile)
bot.reply_to(message, f"`{id}` Appointed as admin.")
else:
bot.reply_to(message,
'This user is already an administrator .')
else:
bot.reply_to(message, 'User is not found.')
else:
bot.reply_to(message, 'You are not an administrator .')
I have not tried anything because I do not understand how
I am mounting a Flask app as a sub-application in my root FastAPI app, as explained in the documentation
Now I want to add an authentication layer using HTTPAuthorizationCredentials dependency, as nicely explained in this tutorial
tutorial code
How can I do that?
Preferably, I would like that any type of access attempt to my Flask sub-application goes first through a valid token authentication process implemented in my FastAPI root app. Is that possible?
You can use a custom WSGIMiddleware and authorize the call to flask app inside that like this:
from fastapi import FastAPI, Depends, HTTPException
from fastapi.middleware.wsgi import WSGIMiddleware
from flask import Flask, escape, request
from starlette.routing import Mount
from starlette.types import Scope, Receive, Send
flask_app = Flask(__name__)
def authenticate(authorization: str = Header()):
# Add logic to authorize user
if authorization == "VALID_TOKEN":
return
else:
raise HTTPException(status_code=401, detail="Not Authorized")
class AuthWSGIMiddleware(WSGIMiddleware):
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
_, authorization = next((header for header in scope['headers'] if header[0] == b'authorization'), (b'authorization', "" ))
authenticate(authorization.decode('utf-8'))
await super().__call__(scope, receive, send)
routes = [
Mount("/v1", AuthWSGIMiddleware(flask_app)),
]
# OR Optionally use this as you were doing
# The above one is preferred as per starlette docs
# app.mount("/v1", WSGIMiddleware(flask_app))
#flask_app.route("/")
def flask_main():
name = request.args.get("name", "World")
return f"Hello, {escape(name)} from Flask!"
app = FastAPI(routes=routes, dependencies=[Depends(authenticate)])
#app.get("/v2")
def read_main():
return {"message": "Hello World"}
For the tutorial you are looking at, you can replace the invoking authenticate function in my example inside AuthWSGIMiddleware->__call__() with
AuthHandler().decode_toke(authorization)
I'm trying to create a shiny app which links to my dropbox using the package rdrop2.
I have successfully managed to deploy the app and it runs as planned for around 4 hours. However, I need long lasting offline access. Dropbox help pages say that I'll need a 'refresh token'.
Currently to get my token I am using:
library(rdrop2)
token <- drop_auth() # gets credentials
saveRDS(token, "droptoken.rds") # saves credentials
token<-readRDS("droptoken.rds") # read in credentials
drop_auth(new_user = FALSE,
cache = TRUE,
rdstoken = "droptoken.rds")
ui <- # some UI code
server <- function(input, output,session) {
# some server code
}
shinyApp(ui = ui, server = server)
This creates a token that has a 'sl.' access token (short lived) which expires_in 14400, which is 4 hours. After 4 hours, the app no longer works due to an 'Unathorised HTTP 401' error.
Could anyone provide me help on how to adapt this code to obtain a refresh token?
NB: dropbox no longer allow tokens with no expiry (as of September 2021) so I need to go down the refresh token route.
I don't know if you still need help but I was recently tasked to address this issue in my internship program and managed to find a solution.
Currently, rdrop2's drop_auth() function will generate a token with these credentials: <credentials> access_token, token_type, expires_in, uid, account_id. Since access tokens last only 4 hours now, we will need a refresh token as a part of our credentials so that we may get a new access token every time it expires.
To generate a token object with a refresh token, we will need to modify the authorization endpoint inside the drop_auth() function. This will look something like this:
library(rdrop2)
.dstate <- new.env(parent = emptyenv())
drop_auth_RT <- function (new_user = FALSE, key = "mmhfsybffdom42w", secret = "l8zeqqqgm1ne5z0", cache = TRUE, rdstoken = NA)
{
if (new_user == FALSE & !is.na(rdstoken)) {
if (file.exists(rdstoken)) {
.dstate$token <- readRDS(rdstoken)
}
else {
stop("token file not found")
}
}
else {
if (new_user && file.exists(".httr-oauth")) {
message("Removing old credentials...")
file.remove(".httr-oauth")
}
dropbox <- httr::oauth_endpoint(authorize = "https://www.dropbox.com/oauth2/authorize?token_access_type=offline",
access = "https://api.dropbox.com/oauth2/token")
# added "?token_access_type=offline" to the "authorize" parameter so that it can return an access token as well as a refresh token
dropbox_app <- httr::oauth_app("dropbox", key, secret)
dropbox_token <- httr::oauth2.0_token(dropbox, dropbox_app,
cache = cache)
if (!inherits(dropbox_token, "Token2.0")) {
stop("something went wrong, try again")
}
.dstate$token <- dropbox_token
}
}
refreshable_token <- drop_auth_RT()
This will generate a token with these credentials: <credentials> access_token, token_type, expires_in, refresh_token, uid, account_id. The new token will now have a refresh token that the HTTP API can use to automatically refresh the access token.
It is very important that you specify the new token when calling rdrop2 functions, otherwise it will not work. Example:
> drop_dir()
Error in drop_list_folder(path, recursive, include_media_info, include_deleted, :
Unauthorized (HTTP 401).
> drop_dir(dtoken = refreshable_token)
# A tibble: 4 x 11
.tag name path_lower path_display id client_modified server_modified rev size
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <int>
1 folder Screensh~ /screensh~ /Screenshots id:_~ NA NA NA NA
Hope this helps!
I am facing this issue connecting with Facebook's API using httr package, while testing on 'me' node I came along the following problem.
I was under the impression that me node does not require special permissions.
Testing on the browser with 'https://graph.facebook.com/me' gave the same results, it would be great if some one could provide an explanation.
# Define keys
app_id = 'my_app_id'
app_secret = 'my_app_secret'
# Define the app
fb_app <- oauth_app(appname = "facebook",
key = app_id,
secret = app_secret)
# Get OAuth user access token
fb_token <- oauth2.0_token(oauth_endpoints("facebook"),
fb_app,
scope = 'public_profile',
type = "application/x-www-form-urlencoded",
cache = TRUE)
response <- GET("https://graph.facebook.com",
path = "/me",
config = config(token = fb_token))
# Show content returned
content(response)
$error
$error$message
[1] "An active access token must be used to query information about the current user."
$error$type
[1] "OAuthException"
$error$code
[1] 2500
$error$fbtrace_id
[1] "ARRnb93rZHmWLlXK_MMJlfi"
Noting that I have signed in using the app.
Using requests module want to query Gerrit server and for this need set authentication in below code. And this needs to be done without using any other module like pygerrit2. And if this can be done using HTTP password generated from gerrit. If this is not doable, share an example if auth has to be passed along with Get request.
import requests
import json
import os
GERRIT_SERVER = 'https://gerrit.abc.com'
class GerritServer():
def __init__(self):
self._base_url = GERRIT_SERVER
self._endpoints = {
'CHANGES': 'changes',
}
def _get_endpoint(self, token):
try:
endpoint = self._endpoints[token]
except ValueError:
raise Exception('endpoint not defined for {0}'.format(token))
return '{0}/{1}'.format(self._base_url, endpoint)
def get_endpoint_changes(self):
return self._get_endpoint('CHANGES')
Gerrit's REST API uses digest auth.
username = 'foo'
httpassword = 'bar'
api = 'baz'
auth = requests.auth.HTTPDigestAuth(username, httpassword)
r = requests.get(api, auth=auth)