I am trying to fetch the number of watches over time using Python, I have tried "https://api.github.com/repos/octocat/hello-world/subscription" that is listed on the Github API webpage, but seems no longer work, I am a bit confused. I am just trying to get "created_at" under subscription. Any suggestions? Thank you.
EDIT - as per your first comment and extra requirements: Unfortunately I do not think it is possible to get watchers over time, you can however get the stargazers over time, an example using GitHub's GraphQL API is below. To do so you can use the following:
import requests
MY_TOKEN = my_token
REPO_NAME = repo_name
REPO_OWNER = repo_owner
query = f'''{{
repository(name: "{REPO_NAME}", owner: "{REPO_OWNER}") {{
watchers {{
totalCount
}}
stargazers(first: 100) {{
totalCount
edges {{
starredAt
}}
}}
}}
}}
'''
headers = {"Authorization": f"token {MY_TOKEN}"}
request = requests.post("https://api.github.com/graphql", json={"query": query}, headers=headers)
print(request.json())
Which will output a result like the following:
{
"data": {
"repository": {
"watchers": {
"totalCount": 1594
},
"stargazers": {
"totalCount": 53952,
"edges": [
{
"starredAt": "2016-08-15T18:39:55Z"
},
{
"starredAt": "2016-08-15T19:14:32Z"
}
]
}
}
}
}
You can easily try out GitHub's GraphQL API in the explorer they provide (one click to run a query). Just use the following query as an example (and replace the repo name and owner as you wish):
{
repository(name: "repo_name", owner: "repo_owner") {
watchers {
totalCount
}
stargazers(first:100) {
totalCount
edges {
starredAt
}
}
}
}
Note you should now be careful for pagination (see first:... parameter).
I guess for privacy reasons the date when a user added a repository to watch is not public. The only way that I have found to get that date is using the user scope instead of repo scope, using the following call:
https://api.github.com/users/your_username/subscriptions
Remember you have to be authenticated using a private token
To get the number of watchers you can do this:
#get number of watchers
url = f"https://api.github.com/repos/{git_owner_repository}/{git_repository_name}"
response = requests.get(url, auth=(username, GITHUB_TOKEN))
response.raise_for_status()
response_dict = response.json()
watchers = response_dict['watchers_count']
#get all the watchers:
url = f"https://api.github.com/repos/octocat/hello-world/subscribers?simple=yes&per_page={watchers}"
response_watcher = requests.get(url, auth=(username, GITHUB_TOKEN))
response_watcher.raise_for_status()
response_watcher = response.json()
for watcher in response_watcher:
user_url = watcher['url']
watcher_name = watcher['login']
response_user = requests.get(user_url, auth=(username, GITHUB_TOKEN))
response_user.raise_for_status()
response_dict_user = response.json()
created_at= response_dict_user['created_at']
print(f"watcher name: {watcher_name}, created_at: {created_at}")
Related
Is there a way to manually create a docId when inserting a document into Firestore?
The following Python3 code will insert a new document in Firestore with an auto-generated docId.
import requests
import json
project_id = 'MY_PROJECT_NAME'
web_api_key = 'MY_WEB_API_KEY'
collection_name = 'MY_COLLECTION_NAME'
url = f'https://firestore.googleapis.com/v1/projects/{project_id}/databases/(default)/documents/{collection_name}/?key={web_api_key}'
payload = {
'fields': {
'title': { 'stringValue': 'myTitle' },
'category': { 'stringValue': 'myCat' },
'temperature': { 'doubleValue': 75 }
}
}
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
response = requests.post(url, data=json.dumps(payload), headers=headers)
response_dict = json.loads(response.content)
for i in response_dict:
print(f'{i}: {response_dict[i]}')
In case anyone else wants to use this code in the future, to get a Web API key, go to Google Cloud Platform > APIs & Services > Credentials > Create Credentials > API key, then copy the value it generates here.
Thanks,
Ryan
answered in Google Cloud Firestore REST API createDocument auto genarates ID documentId should be added as a query parameter when document is created
So for the code in the question, just url should be changed with the same body:
url = f'https://firestore.googleapis.com/v1/projects/{project_id}/databases/(default)/documents/{collection_name}?documentId={your_custom_doc_id}&key={web_api_key}'
To set a custom document ID, you only need to append the name to the URL path after the respective collection. This is similar to how the document reference works where the path must point to the desired location.
From the documentation:
https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/cities/LA
i am trying to send POST request to login to this URL
, i first checked the network tab and found out the the post request is being sent to this
url : https://api-my.te.eg/api/user/login?channelId=WEB_APP
and the request payload is:
{
"header":{
"timstamp":0,
"customerId":null,
"msisdn":null,
"messageCode":null,
"responseCode":"1200",
"responseMessage":"Your Session has been expired, please sign in to continue",
"locale":null,
"referenceId":null,
"channelId":null,
"responeAdditionalParameters":null
},
"body":null
}
Here is the code :
import requests
import calendar
import time
#Here i tried to send a generated timestamp, idk if this is needed or not
ts = calendar.timegm(time.gmtime())
loginUrl = 'https://api-my.te.eg/api/user/login?channelId=WEB_APP'
values = {
"msisdn": MobileNumberID,
"timestamp": str(ts),
"locale": "Ar"
}
data = {
"password": PasswordID
}
url = requests.post(loginUrl , data=data , headers=values)
print(url.text)
I looked at the site and in the body they are also passing a header property in the data
So you should use
data = {
"header": {
"msisdn": "024568478",
"timestamp": "1592337873",
"locale": "Ar"
},
"body": {
"password": "PJGkRJte5ntnKt9TQ8XM3Q=="
}
}
and in headers you should pass the native headers probably something like:
headers={'Content-Type': 'application/json', }
but i also see by when you log into this site they pass a jwt argument in the headers. Looks like its some sort of built in security. So it looks like you can not use this API. Its only for the backend of this site.
Did you search the site to see if they have API documentation, maybe their is written how you can calculate the value for jwt?
EDIT:
When you get the login working this is. How to use sessions in python requests:
s = requests.Session()
data = {"login":"my_login", "password":"my_password"}
url = "http://example.net/login"
r = s.post(url, data=data)
If you do not get arround the jwt. You can uses Selenium in python. It works by automating a webbrowser. So you can open chrome tell it wich page to load, fill in your login form and read the html of elements in the browser. This will work on 95% of the websites. Some even have protections against it. Some sites use cloudflare, they are protected from selenium automation.
I am sending an API request, and I receive the following response:
{
'response':{
'Container List':[
{
'Driver ID':'038107264',
'Status':True,
'Truck':'4314008'
}
]
}
}
What I want to do is to print only the value in Truck, meaning I want to be able to print the value 4314008.
I'm assuming you are using requests to get this resonse
response = requests.get("whateverurl").json()
print(response["response"]["Container List"][0]["Truck"])
I'm trying to use the batch functionality for the Mailchimp API. My current set up is like this
operations = []
for idx, row in users_df.iterows():
payload = {
'email': row['email'],
'last_updated': row['new_time'],
'custom_value': row['new_value']
}
operation_item = {
"method": "POST", # I changed this to PUT
"path": '/lists/members/12345',
"body": json.dumps(payload),
}
operations.append(operation_item)
client = mc.MailChimp(MAILCHIMP_TOKEN, MAILCHIMP_USER)
batch = client.batches.create(data={"operations": operations})
Whenever I use the POST method I get this error: old_user#gmail.com is already a list member. Use PUT to insert or update list members.
But whenever I change my method to PUT, I get this other error: The requested method and resource are not compatible. See the Allow header for this resource's available methods.
Is there a way to overcome this? I have already looked at this and this is a similar problem in Ruby.
you can't do PUT to the list resource "/lists/members/12345", you need to change path to be "/lists/members/12345/{email}"
this code works for us:
def add_users_to_mailchimp_list(list_id, users):
operations = []
client = get_mailchimp_client()
for user in users:
member = {
'email_address': user.email,
'status_if_new': 'subscribed',
'merge_fields': {
'FNAME': user.first_name or '',
'LNAME': user.last_name or '',
},
}
operation_item = {
"method": "PUT",
"path": client.lists.members._build_path(list_id, 'members', user.email),
"body": json.dumps(member),
}
operations.append(operation_item)
return client.batches.create(data={"operations": operations})
using protected method client.lists.members._build_path is a bit hacky I guess, if you like you can build the url manually, it will be f'lists/{list_id}/members/{user.email}'
My first attempt at setting up the Google apiclient for YouTube and by following the docs I made this as a test (didn't find a specific example for the YouTube API):
import json
from apiclient.discovery import build
service = build('youtube', 'v3', developerKey = 'tralalala')
videos = service.videos()
request = videos.list(part = '7lCDEYXw3mM') # some video id
response = request.execute()
json.dumps(response, sort_keys = True, indent = 4)
I get this
{
"error": {
"errors": [
{
"domain": "youtube.parameter",
"reason": "missingRequiredParameter",
"message": "No filter selected.",
"locationType": "parameter",
"location": ""
}
],
"code": 400,
"message": "No filter selected."
}
}
Obviously I'm missing this filter, but I can't seem to find it anywhere in the docs google-api-client-libraries.appspot.com. My intent is to fetch a videos details by providing its id.
You need at least one selector to list. 'id' is one of them. You can always check YouTube API Samples project for reference.
Here's a Python list usage in one of examples.
Following #pypat's suggestion, I changed the attributes for my list() method
videos = service.videos()
request = videos.list(part = 'id', id = '7lCDEYXw3mM')
response = request.execute()
With both part and id being required to produce a result.
In order to get the full list or properties for a given video, the attribute part has to include a list of property groups
request = videos.list(part = 'id, snippet, contentDetails, statistics, status, topicDetails',
id = '7lCDEYXw3mM')