Not able to upload file using slack api files.upload - python-3.x

This question may seem duplicate but I have tried a lot but did not get success.
I am trying to upload html file using https://slack.com/api/files.upload API but I am getting below error always.
response
{'ok': False, 'error': 'no_file_data'}
I went through documentation [a link]https://api.slack.com/methods/files.upload and tried with different options but still i am getting the same response {'ok': False, 'error': 'no_file_data'}
Also i have seen many similar questions in stack overflow but none of them resolved the problem.
[a link]no_file_data error when using Slack API upload
[a link]How to upload files to slack using file.upload and requests
Below is my code.
import requests
def post_reports_to_slack(html_report):
"""
"""
url = "https://slack.com/api/files.upload"
# my_file = {html_report, open(html_report, 'rb'), 'html'}
data = {
"token": bot_user_token,
"channels": channel_name,
"file": html_report,
"filetype": "html"
}
# data = "token=" + bot_user_token + \
# "&channels=" + channel_name +\
# "&file=" + html_report + "&filetype=" + "html"
response = requests.post(
url=url, data=data,
headers={"Content-Type": "application/x-www-form-urlencoded"})
print("response", response)
print(response.json())
if response.status_code == 200:
print("successfully completed post_reports_to_slack "
"and status code %s" % response.status_code)
else:
print("Failed to post report on slack channel "
"and status code %s" % response.status_code)
Please help to resolve the issue.

I was needed to add "content" argument and "filename" argument instead of "file" argument in files.upload API payload, Now file uploading to slack channel is working fine.
import requests
def post_reports_to_slack(html_report):
url = "https://slack.com/api/files.upload"
with open(html_report) as fh:
html_data = fh.read()
data = {
"token": bot_user_token,
"channels": "#channel_name",
"content": html_data,
"filename": "report.html",
"filetype": "html",
}
response = requests.post(
url=url, data=data,
headers={"Content-Type": "application/x-www-form-urlencoded"})
if response.status_code == 200:
print("successfully completed post_reports_to_slack "
"and status code %s" % response.status_code)
else:
print("Failed to post report on slack channel "
"and status code %s" % response.status_code)

Related

FastApi and HTTP header Authorization: Token, get error in use "authorization: token is an invalid header name"

I need use HTTP authorization with header Authorization: Token. My code:
#router.get('/versions',tags=["Credentials"],responses={
200: {
"model": List[models.versions_info],
"description": "Return has code",
"headers": {"Authorization": {"description":"Token party","type":"string"}}
}})
async def list_versions(token: Union[str, None] = Header(description="Token party",alias="Authorization: Token",default=None)):
out=[{"version": "2.1.1","url": "https://www.server.com/ocpi/2.1.1/"},{"version": "2.2","url": "https://www.server.com/ocpi/2.2/"}]
return Response(status_code=200,content=json.dumps(out), media_type="application/json", headers={"Authorization: Token "+config.globals["mytoken"]})
However, when using I get an error:
Can you tell me where I'm wrong?
Update: if i modify code to:
async def list_versions(token: Union[str, None] = Header(alias="Authorization",default=None))
the header is not sent at all:

boto3 s3 bucket tagging

I'm getting access error while tagging a bucket. Please note that the role I'm using has s3 full access.
The code works fine till this point-
for bucket in s3.buckets.all():
s3_bucket = bucket
s3_bucket_name = s3_bucket.name
try:
response = s3_client.get_bucket_tagging(Bucket=s3_bucket_name)
print(response)
except ClientError:
print (s3_bucket_name, "does not have tags")
but after adding putTag code, it gives error even for GetBucketTagging operation.
This is my final code:
for bucket in s3.buckets.all():
s3_bucket = bucket
s3_bucket_name = s3_bucket.name
try:
response = s3_client.get_bucket_tagging(Bucket=s3_bucket_name)
print(response)
except ClientError:
print (s3_bucket_name, "does not have tags")
bucket_tagging = s3.BucketTagging(s3_bucket_name)
response = bucket_tagging.put(
Tagging={
'TagSet': [
{
'Key': 'pcs:name',
'Value': s3_bucket_name
},
]
},
)
The error I'm getting is-
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the GetBucketTagging operation: Access Denied
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tagging.py", line 91, in <module>
tagging()
File "tagging.py", line 71, in tagging
'Value': s3_bucket_name
File "/home/ec2-user/compass_backend/compass_backend/lib64/python3.7/site-packages/boto3/resources/factory.py", line 520, in do_action
response = action(self, *args, **kwargs)
File "/home/ec2-user/compass_backend/compass_backend/lib64/python3.7/site-packages/boto3/resources/action.py", line 83, in __call__
response = getattr(parent.meta.client, operation_name)(*args, **params)
File "/home/ec2-user/compass_backend/compass_backend/lib64/python3.7/site-packages/botocore/client.py", line 395, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/home/ec2-user/compass_backend/compass_backend/lib64/python3.7/site-packages/botocore/client.py", line 725, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutBucketTagging operation: Access Denied
am I passing the tag parameters wrong? Got this from Boto3 documentation itself
I couldn't find a way to catch the exception, however, this worked for me:
tagging_client = boto3.client('resourcegroupstaggingapi')
s3 = boto3.resource('s3')
s3_client = boto3.client('s3')
for bucket in s3.buckets.all():
s3_bucket = bucket
s3_bucket_name = s3_bucket.name
bucket_tagging = s3.BucketTagging(s3_bucket_name)
try:
response = s3_client.get_bucket_tagging(Bucket=s3_bucket_name)
a = response
except ClientError:
response = tagging_client.tag_resources(
ResourceARNList=[
"arn:aws:s3:::" + bucket.name
],
Tags={
'pcs:name': bucket.name
}
)
pls note that you'll need the additional "resource tagging" policy attached to your role.
Hope this helps. Cheers.
I took out the try sections and ran this version of your code:
import boto3
s3_resource = boto3.resource('s3')
bucket_tagging = s3_resource.BucketTagging('my-bucket-name')
response = bucket_tagging.put(
Tagging={
'TagSet': [
{
'Key': 'pcs:name',
'Value': 'stackoverflow'
},
]
},
)
It worked fine:
[
Therefore, there must be something else that is causing your request to fail. You might want to check AWS CloudTrail to see if there is a hint as to why the request was denied.
"get_bucket_tagging" throws NoSuchTagSet when there are no tags. for testing create a tag first before run test or Catch the exception and create tags.

Flask - TypeError: Object of type cycle is not JSON serializable

I'm trying to return a json response from server to client after client makes a post via AJAX.
Like this, it works:
#app.route("/test", methods=["GET", "POST"])
#login_required
def test():
if request.is_xhr:
try:
json_response = {
"result": "success"
}
except Exception as e:
err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
json_response = {"result": "failure", "msg": err}
return jsonify(json_response)
else:
return redirect("/not-found")
return ''
If I do like this, it doesn't works:
#app.route("/test", methods=["GET", "POST"])
#login_required
def test():
if request.is_xhr:
try:
_dict = {
"key1": "value1",
"key2": "value2"
}
if not "my_dict" in session:
session["my_dict"] = [_dict]
else:
session["my_dict"] = session["my_dict"] + [_dict]
session.modified = True
json_response = {
"result": "success"
}
except Exception as e:
err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
json_response = {"result": "failure", "msg": err}
return jsonify(json_response)
else:
return redirect("/not-found")
return ''
I get the following error and client doesn't receives json response:
File "~/myprojectenv/lib/python3.8/site-packages/flask/json/__init__.py", line 100, in default
return _json.JSONEncoder.default(self, o)
File "/usr/lib/python3.8/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type cycle is not JSON serializable
[2020-09-26 19:01:14,091] ERROR in app: Request finalizing failed with an error while handling an error
If I remove that stretch:
if not "my_dict" in session:
session["my_dict"] = [_dict]
else:
session["my_dict"] = session["my_dict"] + [_dict]
session.modified = True
It works again. Client receives json response.
I figured out the trouble.
Check out the following function:
#app.route("/test", methods=["GET", "POST"])
def test():
if request.is_xhr:
try:
licycle = cycle(files)
nextelem = next(licycle)
_dict = {
"sid": session["_id"],
"licycle": licycle,
"nextelem": nextelem,
"licycle2": licycle2,
"nextelem2": nextelem2,
"mon_id": _id,
"sch_id": 0
}
if not "all_submons" in session:
session["all_submons"] = [_dict]
else:
session["all_submons"] = session["all_submons"] + [_dict]
session.modified = True
all_submons.setdefault("sub_mons", []).append(_dict)
json_response = {"result": "success"}
except Exception as e:
err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
json_response = {"result": "failure", "err": err}
finally:
try:
print("exiting...")
except Exception as e:
pass
return jsonify(json_response)
else:
return redirect("/not-found")
return ""
The reason is that type of licycle variable is <class 'itertools.cycle'> and session "probably doesn't accepts" that type of variable like a dictionary accepts as you can see in my all_submons dict variable.
The point is:
The execution DOESN'T FALLS in exception. And _dict is stored on session as you can see to next.
print(f"Session before: {session}")
print(f"all_submons before: {all_submons}")
if not "all_submons" in session:
session["all_submons"] = [_dict]
else:
session["all_submons"] = session["all_submons"] + [_dict]
session.modified = True
all_submons.setdefault("sub_mons", []).append(_dict)
print(f"Session after: {session}")
print(f"all_submons after: {all_submons}\n")
You can check the output:
Session before: <SecureCookieSession {'_fresh': True, '_id': 'e253a950...', 'all_submons': [], 'user_id': '1'}>
all_submons before: {}
Session after: <SecureCookieSession {'_fresh': True, '_id': 'e253a...', 'all_submons': [{'sid': 'e253a95...', 'licycle': <itertools.cycle object at 0x7fc989237280>, 'nextelem': ('1a4add0f275c7275.jpg',), 'licycle2': None, 'nextelem2': None, 'mon_id': 1, 'sch_id': 0}], 'user_id': '1'}>
all_submons after: {'sub_mons': [{'sid': 'e253a...', 'licycle': <itertools.cycle object at 0x7fd6f1a17b80>, 'nextelem': ('1a4add0f275c7275.jpg',), 'licycle2': None, 'nextelem2': None, 'mon_id': 1, 'sch_id': 0}]}
I'm not sure about session "probably doesn't accepts" that type of variable - <class 'itertools.cycle'>
But I created other dictionary with others variables, without type of itertools.cycle and it worked.

Flask TypeError: argument of type 'NoneType' is not iterable

I am not sure why I am getting this TypeError:
File "C:/Users/PycharmProjects/REST/app.py", line 30, in
valid_book_object
if ("isbn" in book and "name" in book and "price" in book):
TypeError: argument of type 'NoneType' is not iterable
127.0.0.1 - - [12/Nov/2018 14:22:29] "POST /books HTTP/1.1" 500 -
Code:
from flask import Flask, jsonify, request
from test import *
app=Flask(__name__)
books=[
{'name': 'M',
'price': 6.75,
'isbn':123
},
{'name': 'G',
'price': 7.75,
'isbn':456
},
]
#GET /store
#app.route('/books') #first endpoint
def get_books():
return jsonify({'books': books})
# POST /books
#{'name': 'F',
#'price': 7.00,
#'isbn': 789
#},
def valid_book_object(book):
if ("isbn" in book and "name" in book and "price" in book):
return True
print("true")
else:
return False
print("false")
#app.route('/books', methods=['POST'])
def add_book():
#return jsonify(request.get_json())
request_data=request.get_json()
if(valid_book_object(request_data)):
books.insert(0, request_data)
return "True"
else:
return "False"
#GET /books/456
#app.route('/books/<int:isbn>') #second endpoint
def get_book_by_isbn(isbn):
return_value={}
for book in books:
if book["isbn"]==isbn:
return_value={
'name': book["name"],
'price':book["price"]
}
return jsonify(return_value)
app.run(port=5000)
You are not sending JSON data to /books route using POST method.
I tried your solution with postman and it worked. Also, if you want to use some route for GET and POST, don't split them. Use methods=['GET', 'POST']. Here is your code reformatted with PEP 8 standard:
from flask import Flask, jsonify, request
app = Flask(__name__)
books = [
{'name': 'M',
'price': 6.75,
'isbn': 123
},
{'name': 'G',
'price': 7.75,
'isbn': 456
}
]
# POST /books
# {
# "name": "F",
# "price": 7.00,
# "isbn": 789
# }
def valid_book_object(book):
if "isbn" in book and "name" in book and "price" in book:
return True
else:
return False
#app.route('/books', methods=['GET', 'POST'])
def add_book():
# If request is GET, just return JSON data of books.
if request.method == 'GET':
return jsonify({'books': books})
else:
# This is part if it is POST request
request_data = request.get_json()
if valid_book_object(request_data):
books.insert(0, request_data)
return "True"
else:
return "False"
# GET /books/456
#app.route('/books/<int:isbn>') # second endpoint
def get_book_by_isbn(isbn):
return_value = {}
for book in books:
if book["isbn"] == isbn:
return_value = {
'name': book["name"],
'price': book["price"]
}
return jsonify(return_value)
return 'No book with {} isbn value'.format(isbn)
if __name__ == '__main__':
app.run(port=5000)
And here is the output from postman (you can see True at the bottom, that is what you return if POST was successful):
If you use postman, be sure to select application/json content-type.
If you are using JQuery ajax method, please read this answer. But anyway, here is using JQuery (tested):
data = JSON.stringify({
name: "F",
price: 7.00,
isbn: 789
});
$.ajax({
url: '/books',
type: "POST",
data: data,
contentType: "application/json",
dataType: "json",
success: function(){
console.log('Post executed successfully');
}
})

Google Adwords Traffic Estimator Service and Python

I've downloaded a code sample that looks for particular keywords and pulls some metrics. I've noticed a lot of Google Adwords API examples are compliant with python 3.x so I'm wondering if there is an issue with that? See below for code sample:
from googleads import adwords
def main(client):
# Initialize appropriate service.
traffic_estimator_service = client.GetService(
'TrafficEstimatorService', version='v201609')
# Construct selector object and retrieve traffic estimates.
keywords = [
{'text': 'mars cruise', 'matchType': 'BROAD'},
{'text': 'cheap cruise', 'matchType': 'PHRASE'},
{'text': 'cruise', 'matchType': 'EXACT'}
]
negative_keywords = [
{'text': 'moon walk', 'matchType': 'BROAD'}
]
keyword_estimate_requests = []
for keyword in keywords:
keyword_estimate_requests.append({
'keyword': {
'xsi_type': 'Keyword',
'matchType': keyword['matchType'],
'text': keyword['text']
}
})
for keyword in negative_keywords:
keyword_estimate_requests.append({
'keyword': {
'xsi_type': 'Keyword',
'matchType': keyword['matchType'],
'text': keyword['text']
},
'isNegative': 'true'
})
# Create ad group estimate requests.
adgroup_estimate_requests = [{
'keywordEstimateRequests': keyword_estimate_requests,
'maxCpc': {
'xsi_type': 'Money',
'microAmount': '1000000'
}
}]
# Create campaign estimate requests.
campaign_estimate_requests = [{
'adGroupEstimateRequests': adgroup_estimate_requests,
'criteria': [
{
'xsi_type': 'Location',
'id': '2840' # United States.
},
{
'xsi_type': 'Language',
'id': '1000' # English.
}
],
}]
# Create the selector.
selector = {
'campaignEstimateRequests': campaign_estimate_requests,
}
# Optional: Request a list of campaign-level estimates segmented by
# platform.
selector['platformEstimateRequested'] = True
# Get traffic estimates.
estimates = traffic_estimator_service.get(selector)
campaign_estimate = estimates['campaignEstimates'][0]
# Display the campaign level estimates segmented by platform.
if 'platformEstimates' in campaign_estimate:
platform_template = ('Results for the platform with ID: "%d" and name: '
'"%s".')
for platform_estimate in campaign_estimate['platformEstimates']:
platform = platform_estimate['platform']
DisplayEstimate(platform_template % (platform['id'],
platform['platformName']),
platform_estimate['minEstimate'],
platform_estimate['maxEstimate'])
# Display the keyword estimates.
if 'adGroupEstimates' in campaign_estimate:
ad_group_estimate = campaign_estimate['adGroupEstimates'][0]
if 'keywordEstimates' in ad_group_estimate:
keyword_estimates = ad_group_estimate['keywordEstimates']
keyword_template = ('Results for the keyword with text "%s" and match '
'type "%s":')
keyword_estimates_and_requests = zip(keyword_estimates,
keyword_estimate_requests)
for keyword_tuple in keyword_estimates_and_requests:
if keyword_tuple[1].get('isNegative', False):
continue
keyword = keyword_tuple[1]['keyword']
keyword_estimate = keyword_tuple[0]
DisplayEstimate(keyword_template % (keyword['text'],
keyword['matchType']),
keyword_estimate['min'], keyword_estimate['max'])
def _CalculateMean(min_est, max_est):
if min_est and max_est:
return (float(min_est) + float(max_est)) / 2.0
else:
return None
def _FormatMean(mean):
if mean:
return '%.2f' % mean
else:
return 'N/A'
def DisplayEstimate(message, min_estimate, max_estimate):
"""Displays mean average cpc, position, clicks, and total cost for estimate.
Args:
message: str message to display for the given estimate.
min_estimate: sudsobject containing a minimum estimate from the
TrafficEstimatorService response.
max_estimate: sudsobject containing a maximum estimate from the
TrafficEstimatorService response.
"""
# Find the mean of the min and max values.
mean_avg_cpc = (_CalculateMean(min_estimate['averageCpc']['microAmount'],
max_estimate['averageCpc']['microAmount'])
if 'averageCpc' in min_estimate else None)
mean_avg_pos = (_CalculateMean(min_estimate['averagePosition'],
max_estimate['averagePosition'])
if 'averagePosition' in min_estimate else None)
mean_clicks = _CalculateMean(min_estimate['clicksPerDay'],
max_estimate['clicksPerDay'])
mean_total_cost = _CalculateMean(min_estimate['totalCost']['microAmount'],
max_estimate['totalCost']['microAmount'])
print (message)
print ('Estimated average CPC: %s' % _FormatMean(mean_avg_cpc))
print ('Estimated ad position: %s' % _FormatMean(mean_avg_pos))
print ('Estimated daily clicks: %s' % _FormatMean(mean_clicks))
print ('Estimated daily cost: %s' % _FormatMean(mean_total_cost))
if __name__ == '__main__':
# Initialize client object.
adwords_client = adwords.AdWordsClient.LoadFromStorage()
main(adwords_client)
Here is the error message:
(Money) not-found
path: "Money", not-found
(Keyword) not-found
path: "Keyword", not-found
(Keyword) not-found
path: "Keyword", not-found
(Keyword) not-found
path: "Keyword", not-found
(Keyword) not-found
path: "Keyword", not-found
(Location) not-found
path: "Location", not-found
(Language) not-found
path: "Language", not-found
<suds.sax.document.Document object at 0x03BF1D10>
Server raised fault in response.
Traceback (most recent call last):
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\suds\transport\http.py", line 82, in send
fp = self.u2open(u2request)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\suds\transport\http.py", line 132, in u2open
return url.open(u2request, timeout=tm)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\urllib\request.py", line 472, in open
response = meth(req, response)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\urllib\request.py", line 582, in http_response
'http', request, response, code, msg, hdrs)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\urllib\request.py", line 510, in error
return self._call_chain(*args)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\urllib\request.py", line 444, in _call_chain
result = func(*args)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\urllib\request.py", line 590, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 500: Internal Server Error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\suds\client.py", line 613, in send
reply = self.options.transport.send(request)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\suds\transport\http.py", line 94, in send
raise TransportError(e.msg, e.code, e.fp)
suds.transport.TransportError: Internal Server Error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\adwords test - Copy (2).py", line 177, in <module>
main(adwords_client)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\adwords test - Copy (2).py", line 95, in main
estimates = traffic_estimator_service.get(selector)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\googleads\common.py", line 696, in MakeSoapRequest
raise e
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\googleads\common.py", line 692, in MakeSoapRequest
for arg in args])
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\suds\client.py", line 521, in __call__
return client.invoke(args, kwargs)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\suds\client.py", line 581, in invoke
result = self.send(soapenv)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\suds\client.py", line 619, in send
description=tostr(e), original_soapenv=original_soapenv)
File "C:\Users\sfroese\AppData\Local\Programs\Python\Python35-32\lib\site-packages\suds\client.py", line 670, in process_reply
raise WebFault(fault, replyroot)
suds.WebFault: Server raised fault: '[AuthenticationError.CLIENT_CUSTOMER_ID_IS_REQUIRED # ; trigger:'<null>']'
You should set client_customer_id in your googleads.yaml file . you can get client_customer_id from your manager account. go to your manager account and add client then copy your id from upright corner of screen. in googleads.yaml file paste that id to client_customer_id .

Resources