Jasper server rest_v2 api using requests in python - python

I m using jasperserver rest_v2 web service. I am using requests module in python to hit the api. The report which is on jasper server is executing and
report url is following:
http://localhost:8080/jasperserver/rest_v2/reportExecutions
and I m gettng a json response like that:
{
"status": "ready",
"totalPages": 0,
"requestId": "d0ae905c-1538-4e40-b5ad-c145f521707c",
"reportURI": "/reports/Invoices/COD",
"exports": [
{
"id": "49f47112-4698-4398-9ed8-a62d552a7aa5",
"status": "ready",
"outputResource": {
"contentType": "application/pdf",
"fileName": "COD.pdf",
"outputFinal": true
}
}
]
}
It means my report was executed.
Then I hit the following url to download the report output.
http://localhost:8080/jasperserver/rest_v2/reportExecutions/d0ae90c-1538-4e40-b5ad-c145f521707c/exports/49f47112-4698-4398-9ed8-a62d552a7aa5/outputResource
It gives me the following response with 404 status code:
{
"message": "Resource d0ae95c-1538-4e40-b5ad-c145f521707c not found.",
"errorCode": "resource.not.found",
"parameters": [
"d0ae95c-1538-4e40-b5ad-c145f521707c"
]
}
then I checked my report status using the following url:
http://localhost:8080/jasperserver/rest_v2/reportExecutions/d0ae905c-1538-4e40-b5ad-c145f521707c
I m getting a response 404 and following json:
{
"message": "Resource d0ae905c-1538-4e40-b5ad-c145f521707c not found.",
"errorCode": "resource.not.found",
"parameters": [
"d0ae905c-1538-4e40-b5ad-c145f521707c"
]
}
And the exact same thing is working fine using Postman.
NOTE: I m passing the valid credentials and appropriate headers.
Below is my django view for this:
class JasperView(View):
template = "report.html"
def get_token(self):
username = "zeeshan"
password = "zeeshan"
token = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
return token
def get(self, request, *args, **kwargs):
return render(request, self.template)
def post(self, request, *args, **kwargs):
token = self.get_token()
data = """
<reportExecutionRequest>
<reportUnitUri>/reports/Invoices/COD</reportUnitUri>
<async>false</async>
<freshData>false</freshData>
<saveDataSnapshot>false</saveDataSnapshot>
<outputFormat>pdf</outputFormat>
<interactive>true</interactive>
<ignorePagination>false</ignorePagination>
<parameters>
<reportParameter name="StartDate">
<value>2016-06-08 00:00:00</value>
</reportParameter>
<reportParameter name="EndDate">
<value>2016-07-01 00:00:00</value>
</reportParameter>
<reportParameter name="ReportID">
<value>COD2345</value>
</reportParameter>
<reportParameter name="client">
<value>Fetchr</value>
</reportParameter>
<reportParameter name="manager">
<value>Zeeshan Asgar</value>
</reportParameter>
<reportParameter name="client_add">
<value>Near Bhagat Singh Park, Malviya Nagar, New Delhi-110017</value>
</reportParameter>
</parameters>
</reportExecutionRequest>
"""
response = requests.post(url="http://localhost:8080/jasperserver/rest_v2/reportExecutions",
headers={
"Authorization": "Basic " + token,
"Accept": "application/json",
"Content-Type": "application/xml",
},
data=data)
data = response.json()
request_id = data.get("requestId")
export_id = data.get("exports")[0].get("id")
report_url = "http://localhost:8080/jasperserver/rest_v2/reportExecutions/{request_id}/exports/{export_id}/outputResource".format(
request_id=request_id, export_id=export_id)
report_resp = requests.get(url=report_url,
headers={"Authorization": "Basic " + token, "Content-Type": "application/xml"})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="COD.pdf"'
response.write(report_resp)
return response
Help.
Thanks in advance.

Related

Microsoft Graph API how to send an attachment in a chat

I want to use the Microsoft Graph API to send messages with attachments to chats or channels.
https://learn.microsoft.com/en-us/graph/api/chatmessage-post?view=graph-rest-1.0&tabs=http#example-4-send-a-message-with-file-attachment-in-it
I can send normal messages already just fine like this:
def post_message(chat_id: str, subject: str = "", content_type: str = "text", content: str = "") -> None:
url = f"https://graph.microsoft.com/v1.0/chats/{chat_id}/messages"
json = {
"subject": subject,
"body": {
"contentType": content_type,
"content": content
}
}
res = requests.post(url, headers=header, json=json)
I try to copy the body from the example in the link above, substitute for my values and swap json variable for this one:
attachment_id = '7QW90B10D7-B5AK-420A-AC78-1156324A54F2' # not real, only to show how it looks like
json = {
"body": {
"contentType": 'html',
"content": f'i dunno what i\'m doing. <attachment id="{attachment_id}"></attachment>'
},
'attachments': [
{
'id': attachment_id,
'contentType': 'reference',
'contentUrl': 'https://foo.sharepoint.com/sites/bar/User%20documentation/Databricks/Databricks%20guide.pptx',
'name': 'Databricks guide.pptx'
}
]
}
I get requests.exceptions.HTTPError: 400 Client Error: Bad Request for url
What's wrong with the code? How to get attachment id from a file correctly because I am not sure I got the right value?
I was able to get it working with your code, (using both formats <attachment id=\"\"> and <attachment id="">), so it seems the error is probably with your attachment_id.
I retrieved the driveItem ID by following this answer, where the driveItem ID is the GUID value in the eTag property in the response.
You could get the file by the path:
https://graph.microsoft.com/v1.0/sites/{site-id}/drive/root:/{item-path}
For example:
https://graph.microsoft.com/v1.0/sites/{site-id}/drive/root:/test.docx
If the file is in a folder, it would be like this:
https://graph.microsoft.com/v1.0/sites/{site-id}/drive/root:/folder1/test.docx
Sample request after obtaining the ID
access_token = ""
attachment_name = "file.txt"
attachment_path = "https://domain.sharepoint.com/Shared%20Documents"
attachment_id = "12345678-1234-1234-1234-123456789123"
attachment_url = f"{attachment_path}/{attachment_name}"
chat_id = ""
req_url = f"https://graph.microsoft.com/v1.0/chats/{chat_id}/messages"
req_headers = {
"Authorization": "Bearer " + access_token,
"Content-Type": "application/json"
}
json = {
"body": {
"contentType": "html",
"content": f"Test message <attachment id=\"{attachment_id}\"></attachment>"
},
"attachments": [
{
"id": attachment_id,
"contentType": "reference",
"contentUrl": attachment_url,
"name": attachment_name
}
]
}
result = requests.post(url = req_url, headers = req_headers, json = json)

Facing Issue Sending Gmail Using Google Gmail API

It shows credentials are missing when I try to use the Google Gmail API to send messages. I want to send an email to my other Gmail account using the Google Gmail API.
import sys
import requests
import base64
import sys
from email.mime.text import MIMEText
AccessToken = ""
params = {
"grant_type": "refresh_token",
"client_id": "xxxxxxxxxxxxxxx",
"client_secret": "xxxxxxxxxxxxxxx",
"refresh_token": "xxxxxxxxxxxxxxxxxxxx",
}
authorization_url = "https://www.googleapis.com/oauth2/v4/token"
r = requests.post(authorization_url, data=params)
if r.ok:
AccessToken = str((r.json()['access_token']))
EmailFrom = "Test1#gmail.com"
EmailTo = "test2#gmail.com"
def create_message(sender, to, subject, message_text):
message = MIMEText(message_text, 'html')
message['to'] = to
message['from'] = sender
message['subject'] = subject
raw = base64.urlsafe_b64encode(message.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
body = create_message(EmailFrom, EmailTo, "Just wanna Say Waka Waka!", "Waka Waka!")
url = "https://gmail.googleapis.com/gmail/v1/users/me/messages/send"
header = {
'Authorization': 'Bearer ' + AccessToken,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
r = requests.post(
url,
header,
body
)
print("\n")
print(r.text)
print("\n")
Error:
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"errors": [
{
"message": "Login Required.",
"domain": "global",
"reason": "required",
"location": "Authorization",
"locationType": "header"
}
],
"status": "UNAUTHENTICATED",
"details": [
{
"#type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "CREDENTIALS_MISSING",
"domain": "googleapis.com",
"metadata": {
"method": "caribou.api.proto.MailboxService.SendMessage",
"service": "gmail.googleapis.com"
}
}
]
}
}
I'm not a google api user, but I've used oauth several times, and your setup is a bit different than what I usually use or what I see from a quick sniff of Google's documention. For example, I use client-creds instead of a refresh token. For what I'm seeing above in your code, no reason to refresh an old token, when you can just mint another one. Compared to yours, usually with oauth, we'll do something like auth=(client_id, client_secret)
Lastly, before you change anything big, when you changed your header to place the AccessToken variable in quotes, did you use an f-string? What is the output of
print(header)
after you have defined it? Is it what you expect? If you didn't format it, it's going to have the variable's name rather than value.
If that's all ok, I'd try to write it according to OAuth standards that I've used several times. Not telling you how to do it, but you could try something like:
def getKey():
url = "https://www.googleapis.com/oauth2/v4/token"
client_id = "*yourgoogleclientid*"
client_secret = "*yourgoogleclientsecret*"
data = {
'grant_type': 'client_credentials'
}
r = requests.post(url, json=data, auth=(client_id, client_secret))
key = r.json()['access_token']
return key
def getWhatever(key, url):
header = {
'Authorization': f'Bearer {key} '
}
params = {
'whatever params': 'you might need'
}
response = requests.get(url, headers=header, params=params)
* parse, process, return, whatever you'd like to do with the response.*
now to use it....
if __name__ == '__main__':
myKey = getKey()
whatImLookingFor = getWhatever(myKey, "*https://google_api_endpoint*")

PayPal Tracking showing INVALID_TRACKING_CODE

Looks like I'm doing just about everything correct but I keep receiving this error....
Response text error:
response .text {"name":"INVALID_TRACKING_NUMBER","message":"The requested resource ID was not found","debug_id":"12345","details":[{"field":"tracker_id","value":"1234-567890","location":"path","issue":"INVALID_TRACKING_INFO"}],"links":[]}
Response status: <Response [404]>
I'm using a real transaction and a real tracking number.
I'm doing this through python and this is my code:
def paypal_oauth():
url = 'https://api-m.paypal.com/v1/oauth2/token'
headers = {
"Content-Type": "application/json",
"Accept-Language": "en_US",
}
auth = "1234-1234","0987"
data = {"grant_type":"client_credentials"}
response = requests.post(url, headers=headers, data=data, auth=(auth))
return response
def paypal_tracking(paypal_transaction_token, tracking_number, status, carrier):
try:
_paypal_oauth = paypal_oauth()
_paypal_oauth_response = _paypal_oauth.json()
except Exception as e:
print(e)
pass
access_token = _paypal_oauth_response['access_token']
url = 'https://api-m.paypal.com/v1/shipping/trackers/%s-%s/' % (paypal_transaction_token, tracking_number)
# https://api-m.paypal.com/v1/shipping/trackers/1234-567890/
carrier = carrier_code(carrier)
# This grabs carrier from a method and gets back: 'DHL'
headers = {
'Content-Type' : 'application/json',
'Authorization' : 'Bearer %s' % access_token,
}
# {'Content-Type': 'application/json', 'Authorization': 'Bearer 1234'}
data = {
"transaction_id":"%s" % paypal_transaction_token,
"tracking_number":"%s" % tracking_number,
"status": "%s" % status,
"carrier": "%s" % carrier
}
# {'transaction_id': '1234', 'tracking_number': '567890', 'status': 'SHIPPED', 'carrier': 'DHL'}
response = requests.put(url, headers=headers, data=json.dumps(data))
return HttpResponse(status=200)
Anyone with experience in paypal or using API's see my issue?
To add a tracking number (not update), use an HTTP POST request, as documented.
The URL to POST to is https://api-m.sandbox.paypal.com/v1/shipping/trackers-batch , with no additional URL parameters.
The body format is
{
"trackers": [
{
"transaction_id": "8MC585209K746392H",
"tracking_number": "443844607820",
"status": "SHIPPED",
"carrier": "FEDEX"
},
{
"transaction_id": "53Y56775AE587553X",
"tracking_number": "443844607821",
"status": "SHIPPED",
"carrier": "FEDEX"
}
]
}
Note that trackers is an array of JSON object(s).

Spotify Authorization Code Flow returns incomplete response

I have a django server, and I wish to perform the spotify Authorization code flow.
Here is a basic skeleton I have created:
The user opens the spotify/login url.
The SpotifyLoginView redirects them to https://accounts.spotify.com/authorize url.
The spotify servers callback to the spotify/callback endpoint.
The SpotifyCallbackView makes a POST request to https://accounts.spotify.com/api/token to get the auth token.
urls.py
urlpatterns = [
path(
"spotify/callback", views.SpotifyCallbackView.as_view(), name="spotify callback"
),
path("spotify/login", views.SpotifyLoginView.as_view(), name="spotify login"),
]
views.py
def build_authorize_url(request):
params = {
"client_id": "<my client id>",
"response_type": "code",
"redirect_uri": request.build_absolute_uri(
reverse("spotify callback")
),
"scope": " ".join(
[
"user-library-read",
"user-top-read",
"user-read-recently-played",
"playlist-read-private",
]
),
}
print(params)
url = (
furl("https://accounts.spotify.com/authorize")
.add(params)
.url
)
print(url)
return url
AUTH_HEADER = {
"Authorization": "Basic "
+ base64.b64encode(
"<my client id>:<my client secret>".encode()
).decode()
}
def handle_callback(request):
code = request.GET["code"]
response = requests.post(
"https://accounts.spotify.com/api/token",
data={
"grant_type": "client_credentials",
"code": code,
"redirect_uri": request.build_absolute_uri(
reverse("spotify callback")
),
},
headers=AUTH_HEADER,
)
return response.json()
class SpotifyLoginView(RedirectView):
query_string = True
def get_redirect_url(self, *args, **kwargs):
return build_authorize_url(self.request)
class SpotifyCallbackView(TemplateView):
template_name = "success.html"
def get(self, request, *args, **kwargs):
print(spotify.handle_callback(request))
return super().get(request, *args, **kwargs)
However, the response returned by spotify doesn't contain the scope and refresh_token!
So for these params:
{'client_id': '<my client id>', 'response_type': 'code', 'redirect_uri': 'http://127.0.0.1:8000/spotify/callback', 'scope': 'user-library-read user-top-read user-read-recently-played playlist-read-private'}
which translate to this url:
https://accounts.spotify.com/authorize?client_id=<my client id>&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fspotify%2Fcallback&scope=user-library-read+user-top-read+user-read-recently-played+playlist-read-private
All I get back is:
{'access_token': '<my acess token>', 'token_type': 'Bearer', 'expires_in': 3600, 'scope': ''}
While the docs suggest that I should get this:
{
"access_token": "NgCXRK...MzYjw",
"token_type": "Bearer",
"scope": "user-read-private user-read-email",
"expires_in": 3600,
"refresh_token": "NgAagA...Um_SHo"
}
Furthermore, If I try using that access token, I get a 401 HTTP error back.
$ curl -H "Authorization: Bearer <my acess token>" https://api.spotify.com/v1/me
{
"error" : {
"status" : 401,
"message" : "Unauthorized."
}
}
What's going on here?
You have to use "authorization_code" as grant_type when making POST request to https://accounts.spotify.com/api/token in order to get an initial access token. In your handle_callback() method:
response = requests.post(
"https://accounts.spotify.com/api/token",
data={
"grant_type": "authorization_code",
"code": code,
"redirect_uri": request.build_absolute_uri(
reverse("spotify callback")
),
},
headers=AUTH_HEADER,
)

openstack cannot retrieve authentication token from API

I am trying to retrieve the authentication token from the API using requests library from python. Here is the attempt I have made so far:
def get_token():
data = {
"auth" : {
"identity" : {
"methods" : [ "password" ],
"password": {
"user" : {
"name" : OS_USERNAME,
"domain": { "name": "Default" },
"password": OS_PASSWORD
}
}
}
}
}
r = requests.post(
OS_AUTH_URL+'/auth/tokens',
headers = HEADERS,
json = data, # https://stackoverflow.com/questions/9733638
verify = False
)
print(r.content)
j = json.loads(r.content)
return j['token']['user']['id']
I get token in the response :
{
"token": {
"issued_at": "2018-07-03T11:03:59.000000Z",
"audit_ids": [
"Fg1ywtZBQ1CkigCw70If9g"
],
"methods": [
"password"
],
"expires_at": "2018-07-03T12:03:59.000000Z",
"user": {
"password_expires_at": null,
"domain": {
"id": "default",
"name": "Default"
},
"id": "e0dc5beb383a46b98dad824c5d76e719",
"name": "admin"
}
}
}
However, when I am reusing this token to get, for instance, the list of projects :
def get_tenantID():
r = requests.get(
OS_AUTH_URL+'/auth/projects',
headers = HEADERS,
verify = False
)
return r
r = get_token()
HEADERS['X-Auth-Project-Id'] = 'admin'
HEADERS['X-Auth-Token'] = r
r = get_tenantID()
I get this error as if I would not be authenticated:
<Response [401]>
{"error": {"message": "The request you have made requires authentication.", "code": 401, "title": "Unauthorized"}}
Googling around and using openstack token issue command showed me that usually, token are more like:
gAAAAABaCo1F1CIMVlsTBeuqYH8tm2qR29tbkmUL4vZuhCNPXJI39TQ2YzL6Twoj8fNcAyLe3WhCYW2O1YpbBF0G8mo4bt7Kf0IRsoDOoJ6uWa3RYyJ5SQNoB_5n8EnVXbKPxFYOZ_iFBnaVtL1_XDrGbwsrlDeyy8lZTDdLsqY52pUhFR-7Uow
which is not what I get with get_token.
What am I doing wrong?
Many thanks!
When you use the auth API directly, the token issued comes in the X-Subject-Token header.
Thus, to retrieve in your python example, you could access the response.headers dict like this:
token = r.headers['X-Subject-Token']
More info about authentication in the Keystone v3 docs
1. fetch authentication token as mentioned below:
r = requests.post(
OS_AUTH_URL+'/auth/tokens',
headers = HEADERS,
json = data,
verify = False
)
token = r.headers[X-Subject-Token]
2. Pass this token in header for further request:
{
'X-Auth-Token': token
}

Categories