CL_HTPP_CLIENT CODE 400 BAD REQUEST - ABAP - rest

i am trying to Post a Json to a Web Service.
The connection is good , but Unfortunately the payload arrives empty to the other side.
The Variable Jsondata is not empty and is a string.
I dont know what is missing. I have another Service to another api with a small json and works well.
Call Method cl_http_client=>create_by_url
Exporting
url = url
Importing
client = client
Exceptions
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
Others = 4.
If Sy-Subrc Ne 0.
Raise Error_conexion_token.
Else.
.
Data(Bearer) = 'Bearer' && | | && token.
client->request->set_header_field(
Exporting
name = 'Authorization'
value = Bearer ).
client->request->set_header_field(
Exporting
Name = 'Content-Type'
Value = 'application/json; charset=utf-8' ).
Call method client->request->set_cdata(
Exporting data = jsondata ).
client->request->set_method( if_http_request=>co_request_method_post).
Call Method client->send.
If sy-subrc Ne 0.
Raise Error_conexion_token.
Else.
Call Method client->receive
Exceptions
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
Others = 4.
If sy-subrc Ne 0.
Data(rc) = sy-subrc.
client->get_last_error(
Importing
code = zhcm_fdexperience=>codigo
message = zhcm_fdexperience=>mensaje ).
Case rc.
When 1.
Raise http_communication_failure.
When 2.
Raise http_invalid_state.
When 3.
Raise http_processing_failed.
Endcase.
Else.
client->get_last_error(
Importing
code = zhcm_fdexperience=>codigo
message = zhcm_fdexperience=>mensaje ).
Call method client->response->get_status( Importing code = zhcm_fdexperience=>codigo
reason = zhcm_fdexperience=>mensaje ).
If zhcm_fdexperience=>codigo Ne '200' Or zhcm_fdexperience=>codigo Ne '000' Or zhcm_fdexperience=>codigo Ne '0'.
Clear zhcm_fdexperience=>codigo.
Clear zhcm_fdexperience=>mensaje.
Data(Respuesta) = client->response->get_cdata( ).
Else.
Respuesta = client->response->get_cdata( ).
Endif.
Call method client->close.
An this is the json.
{
"data": [
{
"apiTipo": 1,
"fechaHoraAccion": "07/09/2021 21:20:03",
"nombreUsuarioSAP": "JUAN",
"numeroPersonal": "00001127",
"numeroPersonalREF": "sin información",
"tratamiento": "Señor",
"apellidoPaterno": "letelier",
"apellidoMaterno": "diaz",
"nombre": "rodrigo",
"sexo": "masculino",
"fechaNacimiento": "29/05/1985",
"estadoCivil": "Casado",
"nacionalidad": "Argentina",
"documentoIdentidad": "15902492-2",
"sociedad": "SBIO",
"divisionPersona": "CL01",
"centroCosto": "sin información",
"subdivisionPersona": "sin información",
"calleNumero": "ladies nIght 3221",
"ciudad": "san fernando",
"region": "Libertador Bernardo",
"pais": "Chile",
"telefono": "717846",
"claseContrato": "INDEFINIDO",
"plazoPreavEmpresa": "22.5 HORAS SEMANALES",
"reglaPlanJornadaColaborador": "BHADP201",
"statGestionTiempo": "9 - Evaluacion",
"indAdicTiempo": "NC",
"claseConvenio": "Sin Negociacion",
"areaConvenio": "No Sindicalizado",
"grupoProfesional": "General",
"subgrupoProfesional": "01",
"claseCorreoPersonal": "adiazs#funk.com",
"idSistema": "0016",
"fechaInicio": "22/08/2021",
"fechaFin": "31/12/9999"
}
]
}
Note : I tested in postman and works well.

Related

How to Yahoo ads conversion tracker name through yahoo api

I want to change Yahoo ads conversion tracker name through API automatically.
But, when I run the following code, that returned an error.
access_token = XXXXXXXXXXXXX
account_id = XXXXXX
conversion_id = XXXXXXX
new_name = "new_name"
header = {"Content-Type": "application/json",\
"Accept": "application/json",\
"Authorization": "Bearer " + access_token}
url = "https://ads-search.yahooapis.jp/api/v8/ConversionTrackerService/set"
data = {'accountId':account_id, 'operand':[{'accountId': account_id, 'conversionTrackerId': conversion_id, "conversionTrackerName": new_name}]}
data = json.dumps(data).encode()
req = urllib.request.Request(url, data=data, method='POST', headers=header)
try:
with urllib.request.urlopen(req) as response:
body = json.loads(response.read())
headers = response.getheaders()
status = response.getcode()
print(headers)
print(status)
print(body)
except urllib.error.URLError as e:
print(e.reason)`
Retuened error is:
{'errors': [{'code': 'L0001', 'message': 'Lower list size.', 'details': [{'requestKey': 'operand', 'requestValue': None}]}], 'rid': '6fab0e1ac60dd2a871831484791976bf', 'rval': None}
I guess the length of "operand" field is 1 and it is right length according to yahoo api document. What I shuold do to fix this error?
I tryied to make length of "operand" field 2. But the result was same.

How mock requests exception using Pytest fixture for mock_requests?

So I was using the requests-mock library to mock the HTTP requests that I do with the requests library and everything went fine until I had to do a test to catch the exception.
Example of my function to be tested
def get_wordpress_installed_plugins(url: str, user: str, password: str) -> bytes:
try:
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header = {'Authorization': 'Basic ' + token.decode('utf-8')}
response = requests.get(url, headers=header, verify=False)
response.raise_for_status()
except requests.exceptions.HTTPError as err:
logger.exception(f"Got response from {url} correctly with error {err}.")
raise CouldNotConnectWithApi(f"Problem retrieving information.")
logger.info(f"Got response from {url} correctly.")
return response.content
And the test to assert function did ok
#mock.patch("checkpluginsversion.logging.Logger.info")
def test_api_wordpress_list_plugins(logger_mock, requests_mock):
user = "user"
password = "password"
url = "https://www.example.com"
expected_result = b'[{"plugin": "akismet\\/akismet", "status": "active", "name": "Akismet Anti-Spam","version": "4.2.2"}]'
requests_mock.get(url,
content=b'[{"plugin": "akismet\\/akismet", "status": "active", "name": "Akismet Anti-Spam","version": "4.2.2"}]')
result = get_wordpress_installed_plugins(url, user, password)
assert result == expected_result
logger_mock.assert_called_with(f"Got response from {url} correctly.")
To be honest, I don't know if using pytest fixture mode of this library is the best way, but ok it is working for me. So the problem I have is when I have to test the function and raise the exception. Eventually, I did a workaround with #mock.patch, and worked for me.
#mock.patch("checkpluginsversion.requests.get")
#mock.patch("checkpluginsversion.logging.Logger.exception")
def test_api_should_return_an_exception(logger_mock,my_request_mock):
user = "user"
password = "password"
url = "https://www.example.com"
expected_result = b'[{"plugin": "akismet\\/akismet", "status": "active", "name": "Akismet Anti-Spam","version": "4.2.2"}]'
my_request_mock.side_effect = requests.exceptions.HTTPError
with pytest.raises(CouldNotConnectWithApi):
result = get_wordpress_installed_plugins(url, user, password)
#assert result == expected_result
logger_mock.assert_called_with(f"Got response from {url} correctly with error .")
But I would know and I will really appreciate it if someone could explain to me how to do a test to raise an exception using the pytest fixture of requests_mock library, thanks!

How do you post form data using pytest?

I'm trying to write a unit test that posts form data. The actual line in question is:
def test_create_request():
with app.test_client() as test_client:
app_url = '/requests/'
with app.app_context():
new_request = get_new_request()
form_data = json.dumps(new_request, default=str)
print('FORM DATA: ', form_data)
resp = test_client.post(app_url, data=form_data, headers={'Content-Type': 'application/json'})
assert resp.status_code == 200
s = json.loads(resp.data)
assert s['success'] == True
Where new_request is a dict representation of an object. The print statement yields (I've formatted it a bit):
FORM DATA: {
"request_id": "6",
"state_id": 1,
"orig_project_id": "1",
"orig_project_code": "QQQ",
"orig_allocated_funding": "123.45",
"orig_ytd_spend": "123.45",
"orig_ytd_commit": "123.45",
"orig_ytd_ocnr": "123.45",
"new_project_id": 2,
"new_funding_amount": 123.45,
"new_ytd_spend": 123.45,
"new_ytd_commit": 123.45,
"new_ytd_ocnr": 123.45,
"plan": "this is the plan",
"reason": "this is the reason",
"sm_director": "sm.dir#example.com",
"submitted_by": "xfgbn#vexample.com",
"created_on": "2021-09-14 16:32:55",
"meets_approval_guidelines": null
}
In the flask form, most fields are required. When I try to post the data, the form.validate_on_submit() function in the view's route returns False, and the 2nd assert fails. WTForms claims that none of the required orig_allocated_funding, orig_ytd_spend, orig_ytd_commit, orig_ytd_ocnr, new_project_id, new_funding_amount, new_ytd_spend, new_ytd_commit, new_ytd_ocnr, reason, plan, sm_director, or submitted_by fields are supplied.
I've read several tutorials, and I can't see what I'm doing wrong. Can anyone help?
What I was able to make work was scraping form_data altogether:
def test_create_request():
with app.test_client() as test_client:
app_url = '/requests/'
with app.app_context():
new_request = get_new_request()
resp = test_client.post(app_url, data=new_request)
assert resp.status_code == 200
s = json.loads(resp.data)
print(s['html'])
assert s['success'] == True

How to fetch collection of Zuora Accounts using REST API

I want to fetch all customer accounts from Zuora. Apart from Exports REST API, Is there any API available to fetch all accounts in a paginated list?
This is the format I used to fetch revenue invoices, use this code and change the endpoint
import pandas as pd
# Set the sleep time to 10 seconds
sleep = 10
# Zuora OAUTH token URL
token_url = "https://rest.apisandbox.zuora.com/oauth/token"
# URL for the DataQuery
query_url = "https://rest.apisandbox.zuora.com/query/jobs"
# OAUTH client_id & client_secret
client_id = 'your client id'
client_secret = 'your client secret'
# Set the grant type to client credential
token_data = {'grant_type': 'client_credentials'}
# Send the POST request for the OAUTH token
access_token_resp = requests.post(token_url, data=token_data,
auth=(client_id, client_secret))
# Print the OAUTH token respose text
#print access_token_resp.text
# Parse the tokens as json data from the repsonse
tokens = access_token_resp.json()
#print "access token: " + tokens['access_token']
# Use the access token in future API calls & Add to the headers
query_job_headers = {'Content-Type':'application/json',
'Authorization': 'Bearer ' + tokens['access_token']}
# JSON Data for our DataQuery
json_data = {
"query": "select * from revenuescheduleiteminvoiceitem",
"outputFormat": "JSON",
"compression": "NONE",
"retries": 3,
"output": {
"target": "s3"
}
}
# Parse the JSON output
data = json.dumps(json_data)
# Send the POST request for the dataquery
query_job_resp = requests.post(query_url, data=data,
headers=query_job_headers)
# Print the respose text
#print query_job_resp.text
# Check the Job Status
# 1) Parse the Query Job Response JSON data
query_job = query_job_resp.json()
# 2) Create the Job URL with the id from the response
query_job_url = query_url+'/'+query_job["data"]["id"]
# 3) Send the GETrequest to check on the status of the query
query_status_resp = requests.get(query_job_url, headers = query_job_headers)
#print query_status_resp.text
# Parse the status from teh response
query_status = query_status_resp.json()["data"]["queryStatus"]
#print ('query status:'+query_status)
# Loop until the status == completed
# Exit if there is an error
while (query_status != 'completed'):
time.sleep(sleep)
query_status_resp = requests.get(query_job_url, headers = query_job_headers)
#print query_status_resp.text
query_status = query_status_resp.json()["data"]["queryStatus"]
if (query_status == 'failed'):
print ("query: "+query_status_resp.json()["data"]["query"]+' Failed!\n')
exit(1)
# Query Job has completed
#print ('query status:'+query_status)
# Get the File URL
file_url = query_status_resp.json()["data"]["dataFile"]
print (file_url)```
If you don't want to use Data Query or any queue-based solution like that, use Zoql instead.
Note! You need to know all fields from the Account object you need, the asterisk (select *) doesn't work here:
select Id, ParentId, AccountNumber, Name from Account
You may also add custom fields into your selection. You will get up to 200 records per page.

Matlab urlread2 - HTTP response code: 415 for URL

I am attempting to access the betfair API using Matlab and the urlread2 function available here.
EDIT: I have posted this problem on Freelancer if anyone can help with it: tinyurl.../pa7sblb
The documentation for the betfair API I am following is this getting started guide. I have successfully logged in and kept the session open using these codes: (I am getting a success response)
%% Login and get Token
url = 'https://identitysso.betfair.com/api/login';
params = {'username' '******' 'password' '******'};
header1 = http_createHeader('X-Application','*****');
header2 = http_createHeader('Accept','application/json');
header = [header1, header2];
[paramString] = http_paramsToString(params)
[login,extras] = urlread2(url,'POST',paramString,header)
login = loadjson(login)
token = login.token
%% Keep Alive
disp('Keep Session Alive')
url_alive = 'https://identitysso.betfair.com/api/keepAlive';
header1 = http_createHeader('X-Application','******');
header2 = http_createHeader('Accept','application/json');
header3 = http_createHeader('X-Authentication',token');
header_alive = [header1, header2, header3];
[keep_alive,extras] = urlread2(url_alive,'POST',[],header_alive);
keep_alive = loadjson(keep_alive);
keep_alive_status = keep_alive.status
My trouble starts when I am attempting to do the next step and load all available markets. I am trying to replicate this example code which is designed for Python
import requests
import json
endpoint = "https://api.betfair.com/exchange/betting/rest/v1.0/"
header = { 'X-Application' : 'APP_KEY_HERE', 'X-Authentication' : 'SESSION_TOKEN_HERE' ,'content-type' : 'application/json' }
json_req='{"filter":{ }}'
url = endpoint + "listEventTypes/"
response = requests.post(url, data=json_req, headers=header)
The code I am using for Matlab is below.
%% Get Markets
url = 'https://api.betfair.com/exchange/betting/rest/v1.0/listEventTypes/';
header_application = http_createHeader('X-Application','******');
header_authentication = http_createHeader('X-Authentication',token');
header_content = http_createHeader('content_type','application/json');
header_list = [header_application, header_authentication, header_content];
json_body = savejson('','filter: {}');
[list,extras] = urlread2(url_list,'POST',json_body,header_list)
I am having trouble with a http response code 415. I believe that the server cannot understand my parameter since the headings I have used with success previously.
Any help or advice would be greatly appreciated!
This is the error:
Response stream is undefined
below is a Java Error dump (truncated):
Error using urlread2 (line 217)
Java exception occurred:
java.io.IOException: Server returned HTTP response code: 415 for URL....
I looked at your problem and it seems to be caused by two things:
1) The content type should be expressed as 'content-type' and not 'content_type'
2) The savejson-function doesn't create an adequate json-string. If you use the json-request from the Python-script it works.
This code work for me:
%% Get Markets
url = 'https://api.betfair.com/exchange/betting/rest/v1.0/listEventTypes/';
header_application = http_createHeader('X-Application','*********');
header_authentication = http_createHeader('X-Authentication',token');
header_content = http_createHeader('content-type','application/json');
header_list = [header_application, header_authentication, header_content];
json_body = '{"filter":{ }}';
[list,extras] = urlread2(url,'POST',json_body,header_list)