What's going wrong when I try to create a review comment through Github's v3 API? - github

I'm trying to create a review commit through Github's v3 API and am not succeeding. Consider this repository. There's a single pull request and for the purposes of this question let's say I want to leave a 'changes requested' review on that PR. Here's the code I've got:
#!/usr/bin/env python3
import requests
import json
TOKEN='YOUR_TOKEN_HERE'
REPO = "blt/experiment-repo"
PR_NUM = 1
COMMIT_SHA_1 = "4160bee478c3c985eaaa35f161cc922fe20b354a"
COMMIT_SHA_2 = "df9d13a2e35f9b6c228e1f30ea30585ed85af26a"
def main():
pr_comment_headers = {
'user-agent': 'benedikt/0.0.1',
'Authorization': 'token %s' % TOKEN,
# Accept header per
# https://developer.github.com/changes/2016-12-16-review-requests-api/
'Accept': 'application/vnd.github.black-cat-preview+json',
}
msg = "BLEEP BLOOP I AM A ROBOT"
payload = { 'commit_id': COMMIT_SHA_2,
'body': msg,
'event': "REQUEST_CHANGES" }
# Per https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
review_url = "https://api.github.com/repos/%s/pulls/%s/reviews" % (REPO, PR_NUM)
res = requests.post(review_url, headers = pr_comment_headers,
json = json.dumps(payload))
print(res)
print(res.text)
if __name__ == '__main__':
main()
I've marked in code comments where I've discovered the API endpoints to hit and with what payloads. Excepting, I must have goofed somewhere because when I run the above program I receive:
<Response [422]>
{"message":"Validation Failed","errors":["Variable commitOID of type GitObjectID was provided invalid value","Variable event of type PullRequestReviewEvent was provided invalid value"],"documentation_url":"https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review"}
I've verified that the commit SHAs are the exact ones that Github shows and REQUEST_CHANGES is the string in the documentation.
What am I missing?

I think you need to let requests encode the request body instead of encoding it yourself with json.dumps(), something like this: requests.post(..., json=payload)

Related

Databricks REST API call for updating branch error : User Settings > Git Integration to set up an Azure DevOps personal access token

I am getting below error for updating the repo to a different branch using databricks rest api as mentioned at https://docs.databricks.com/dev-tools/api/latest/repos.html#operation/update-repo .
I have authenticated using service principal and generated dbrks_bearer_token and dbrks_management_token.
Please find below code for same :-
import requests
import os
import json
TOKEN_REQ_BODY = {
'grant_type': 'client_credentials',
'client_id': 'client_id',
'client_secret': 'client_secret'
}
TOKEN_BASE_URL = 'https://login.microsoftonline.com/' + 'tenant_id' + '/oauth2/token'
TOKEN_REQ_HEADERS = {'Content-Type': 'application/x-www-form-urlencoded'}
def dbrks_management_token():
TOKEN_REQ_BODY['resource'] = 'https://management.core.windows.net/'
response = requests.get(TOKEN_BASE_URL, headers=TOKEN_REQ_HEADERS, data=TOKEN_REQ_BODY)
if response.status_code == 200:
print(response.status_code)
return response.json()['access_token']
else:
raise Exception(response.text)
return response.json()['access_token']
def dbrks_bearer_token():
TOKEN_REQ_BODY['resource'] = '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d'
response = requests.get(TOKEN_BASE_URL, headers=TOKEN_REQ_HEADERS, data=TOKEN_REQ_BODY)
if response.status_code == 200:
print(response.status_code)
else:
raise Exception(response.text)
return response.json()['access_token']
DBRKS_BEARER_TOKEN = dbrks_bearer_token()
DBRKS_MANAGEMENT_TOKEN = dbrks_management_token()
DBRKS_REQ_HEADERS = {
'Authorization': 'Bearer ' + DBRKS_BEARER_TOKEN,
'X-Databricks-Azure-Workspace-Resource-Id':
'/subscriptions/susbcriptionid' +
'/resourceGroups/rg-dev/providers/Microsoft.Databricks/workspaces/dbr-dev',
'X-Databricks-Azure-SP-Management-Token': DBRKS_MANAGEMENT_TOKEN }
DBRKS_CLUSTER_ID = {'cluster_id': 'cluster_id'}
def update_repo():
DBRKS_START_ENDPOINT = 'api/2.0/repos/0328767704612345'
postjson = """{
"branch": "main"
}"""
response = requests.patch("https://adb-1234582271731234.0.azuredatabricks.net/"
+ DBRKS_START_ENDPOINT,
headers=DBRKS_REQ_HEADERS,
json=json.loads(postjson))
print(response.status_code)
if response.status_code != 200:
raise Exception(response.text)
os.environ["DBRKS_CLUSTER_ID"] = response.json()["cluster_id"]
print(response.content)
update_repo()
I am getting below error:-
Traceback (most recent call last):
File "C:/Users/IdeaProjects/DBCluster/DB_rest_api.py", line 109, in <module>
update_repo()
File "C:/Users/IdeaProjects/DBCluster/DB_rest_api.py", line 104, in update_repo
raise Exception(response.text)
Exception: {"error_code":"PERMISSION_DENIED","message":"Missing Git provider credentials. Go to User Settings > Git Integration to add your personal access token."}
403
Can someone please let me know if i need to anything explicitly at azure devops git configuration level as well?
Many thanks..!!
To do any operations with Databricks Repos, you need to set a Git personal access token. Because you're using service principal, you can't set that personal access token via UI, but you can perform setting of that Git token using recently implemented Git Credentials REST API - just do that once for your service principal (or when Git PAT expires), and then Repos operations will work.

Linkedin API request dateRange end today or now

I'm using Python 3 to request share statistics from Linkedin API for the last 14 months.
It works fine, when I hardcoded the epoch values in the request link:
https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn%3Ali%3Aorganization%3AXXXXX&timeIntervals=(timeRange:(start:1596206929000,end:1632938933000),timeGranularityType:DAY)
Obviously I don't want to be changing the end values each time I make a request, so I thought I'd declare a variable:
from datetime import datetime
epochcdt = datetime.now().timestamp()
And then just use it in the link instead of the hardcoded value:
https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn%3Ali%3Aorganization%3AXXXXX&timeIntervals=(timeRange:(start:1596206929000,end:epochcdt),timeGranularityType:DAY)
But, that doesn't work:
{'message': 'Internal Server Error', 'status': 500}
Can you please help me with this hopefully, easy to solve problem?
Whole code:
import requests
import json
from liapiauth import auth, headers
from datetime import datetime
epochcdt = (datetime.now().timestamp())*1000
def organization_info(headers):
response = requests.get('https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn%3Ali%3Aorganization%3AXXXXX&timeIntervals=(timeRange:(start:1596206929000,end:{epochcdt}),timeGranularityType:DAY)', headers = headers)
organization_info = response.json()
return organization_info
if __name__ == '__main__':
credentials = 'credentials.json'
access_token = auth(credentials)
headers = headers(access_token)
organization_info = organization_info(headers)
with open('lishare14m.json', 'w') as outfile:
json.dump(organization_info, outfile)
print(organization_info)

How to in "def request()" return the response directly

like title, I wanna in "def request()" to process data, and return a response directly;
I don't wanna flow through the target server;
this way is feasible? thanks!!!
Here's an example on how to do that:
"""Send a reply from the proxy without sending any data to the remote server."""
from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:
if flow.request.pretty_url == "http://example.com/path":
flow.response = http.Response.make(
200, # (optional) status code
b"Hello World", # (optional) content
{"Content-Type": "text/html"} # (optional) headers
)
Source: https://github.com/mitmproxy/mitmproxy/blob/main/examples/addons/http-reply-from-proxy.py

How to set HTTP password in gerrit while making a REST call using python-requests?

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)

programmatically export grafana dashboard data

I have a visual in grafana. I can manually go to the menu click export and export the time series data in json. This works great. Is there a way I can script that in python?. Is there some api I can hit that will return the json of a visual?
I was googling around and it looks like I can use the api to create dashboards/visuals and administer them but not sure where how to use the api to export the data.
Here's a Python script to export then dashboard json, not the presented data. Tested on Python 2.7:
#!/usr/bin/env python
"""Grafana dashboard exporter"""
import json
import os
import requests
HOST = 'http://localhost:3000'
API_KEY = os.environ["grafana_api_key"]
DIR = 'exported-dashboards/'
def main():
headers = {'Authorization': 'Bearer %s' % (API_KEY,)}
response = requests.get('%s/api/search?query=&' % (HOST,), headers=headers)
response.raise_for_status()
dashboards = response.json()
if not os.path.exists(DIR):
os.makedirs(DIR)
for d in dashboards:
print ("Saving: " + d['title'])
response = requests.get('%s/api/dashboards/%s' % (HOST, d['uri']), headers=headers)
data = response.json()['dashboard']
dash = json.dumps(data, sort_keys=True, indent=4, separators=(',', ': '))
name = data['title'].replace(' ', '_').replace('/', '_').replace(':', '').replace('[', '').replace(']', '')
tmp = open(DIR + name + '.json', 'w')
tmp.write(dash)
tmp.write('\n')
tmp.close()
if __name__ == '__main__':
main()
Usage:
You should first create an API key in Grafana and then run:
grafana_api_key=my-key python export-dash.py
Credit: This is a simplified version of https://github.com/percona/grafana-dashboards/blob/master/misc/export-dash.py
http://docs.grafana.org/http_api/data_source/#data-source-proxy-calls.
Visit your browser console (network tab) and you will see how it works there.
You could also use this Go client https://github.com/netsage-project/grafana-dashboard-manager
Its purpose is not what you are looking for, but it is possible to reuse that code.