I'm trying to trigger a GitLab build using Python Requests. Normally one can kick off a build with a curl command.
Example curl command:
curl -X POST \
-F token=TOKEN \
-F ref=master \
-F "variables[UPLOAD_TO_S3]=true" \
https://gitlab.example.com/api/v4/projects/9/trigger/pipeline
I can get this working using the sh module but I'd prefer using requests. I've tried variations with the following:
data = {
'token': token,
'ref': master,
'variables[UPLOAD_TO_S3]': str(uploadS3),
}
headers = {'Content-Type': 'application/json'}
result = requests.post(_trigger_url, headers=headers, json=data)
I tried with and without the headers param. I've also tried passing the data dict using params, json, files, and data. All keep coming back with 400 or 404 errors. Any suggestions?
The above answer is incomplete as it does not deal with the part that makes this complex that is passing trough variables.
To pass variables around with requests using json data one needs to pass the data in the following structure
data = {
'token': token,
'ref': master,
'variables': [{"key": "UPLOAD_TO_S3", "value": True}, {"key": "S3_SERVER", "value": "https://mys3.example.com"}],
}
result = requests.post(_trigger_url, json=data)
You shouldn't send the Content-Type: "application/json" header as part of your request, and you should only need form encoding, so just pass your data dict as the data argument.
Here's a request to my Gitlab instance that succeeds and triggers a build of my project's master branch.
rsp = requests.post('https://gitlab.instance/api/v4/projects/PROJECT_ID/trigger/pipeline',
data={'token': '125fdsfdf1ab3631d2423434347643', 'ref': 'master'})
Here's the output if I inspect my rsp object in `ipython:
In [3]: rsp
Out[3]: <Response [201]>
You should also be able to trigger the pipeline by sending a POST and including the token and ref in the URL itself.
rsp = requests.post('https://gitlab.instance/api/v4/projects/PROJECT_ID/trigger/pipeline?token=TOKEN&ref=master')
If I pass the Content-Type: "application/json" header, Gitlab responds with an HTTP/400 error.
The first answer doesn't address the "variables" part. The second answer didn't work for me. Here's what I ended up with working:
variables = {
"UPLOAD_TO_S3": True,
"S3_SERVER": "https://mys3.example.com"
}
data = {
"token": token,
"ref": ref_name,
"variables": variables
}
res = requests.post(pipeline_trigger, json=data)
Related
I'm trying to use PiXhost's api to upload images. Every time I request something from https://api.pixhost.to/images it always returns 400 Bad request. Their API documentation uses python unirest package, but I can't install it as it seems to use too old code.
Am I doing something wrong here?
Link to documentation
my code:
import requests
headers = {
"Content-Type": "multipart/form-data; charset=utf-8",
"Accept": "application/json"
}
params = {
"content_type": "0",
"max_th_size": "420"
}
files = {
"img": open("image.jpg", mode="rb")
}
response = requests.post("https://api.pixhost.to/images", headers=headers, params=params, files=files)```
import requests
url = "https://api.pixhost.to/images"
payload={'content_type': '0',
'max_th_size': '420'}
files={
'img': ('1.JPG', open('C:/Users/prave/Desktop/1.JPG', 'rb')),
'content_type': '0',
'max_th_size': '420'
}
headers = {
}
response = requests.request("POST", url, data=payload, files=files)
print(response)
Here you go
output :
Response 200
Issue with your code:
THe endpoint expects formdata , you are passing query parameter
So how did i figure it out
goto documentation and click curl tab to get curl equalent code:
Now goto postman and click import>Raw text > paste the curl , and click continue and then import
This creates the request for you
Now goto body and select img type as file and upload the file:
Now click code and generate equalent curl and python request code:
THe generated python code had few isseus one was to remove header completely and then to remove one slash from the file name.
Just a quick test, I managed to get it done via cURL
curl -X POST --include "https://api.pixhost.to/images" \
-H 'Content-Type: multipart/form-data; charset=utf-8' \
-H 'Accept: application/json' \
-F 'img=#test1.jpg' \
-F 'content_type=0' \
-F 'max_th_size=420'
https://pixhost.to/show/39/178828640_test1.jpg
Note: the test1 image is in the same folder when I running the script
I also receive 400 status code without a body when removing the # before the URL (so check you URL again)
HTTP/1.1 400 Bad Request
Server: nginx/1.10.3 (Ubuntu)
I am writing a python program that calls AWS API Gateway to reach dynamoDB.
And it all works fine when I use python "requests":
r = requests.post("https://xxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/log-entries",
data={'logbookTimestamp': timestamp, 'Name': "Fred"})
Now in order to run this as a lambda function, I want to use "urllib3" instead of "requests"
because urllib3 is included by default in lambda's python. So now I am trying to do the same with urllib3 but can't get it to work. I've read the urllib3 user guide here (https://urllib3.readthedocs.io/en/latest/user-guide.html#json) and it says I need to encode the JSON data before sending it so I've done this:
http = urllib3.PoolManager()
fields = {'logbookTimestamp': timestamp, 'Name': "Fred"}
encoded_fields = json.dumps(fields).encode('utf-8')
link = "https://xxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/log-entries"
r = http.request('POST',
link,
body=encoded_fields,
headers={'Content-Type': 'application/json'}
)
When I look at the output of both in CloudWatch I see that the data are formatted differently.
With requests:
(c084a37e-43d8-464a-9dcf-e40c28922ece) Method request body before transformations: logbookTimestamp=2020%3A12%3A15%3A20%3A11%3A02&Name=Fred
With urllib3:
(9b8d84e9-2403-462c-b25f-945a927d1e66) Method request body before transformations:
{
"logbookTimestamp": "2020:12:15:21:31:21",
"Name": "Fred"
}
and returns the following:
(9b8d84e9-2403-462c-b25f-945a927d1e66) Endpoint response body before transformations:
{
"statusCode": 500,
"headers": {
"Content-Type": "text/html; charset=utf-8",
"Content-Length": "290"
},
"body": "\n500 Internal Server Error\nInternal Server Error\nThe server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.\n"
}
(9b8d84e9-2403-462c-b25f-945a927d1e66) Endpoint response body before transformations: {"statusCode": 500, "headers": {"Content-Type": "text/html; charset=utf-8", "Content-Length": "290"}
I can't figure out how to get the data in the format in "urllib3" that will be accepted like it is with "requests". Any thoughts? Thanks!
If you post your json as data in requests it will be submited like a html form:
"Content-Type":["application/x-www-form-urlencoded"]
If you want it to go as json, you should use
requests.post("https://xxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/log-entries", json={'logbookTimestamp': timestamp, 'Name': "Fred"})
which submits data as:
"Content-Type":["application/json"]
I'm trying to make a POST request to https://accounts.spotify.com/api/token via python and the request, library but can't get it to work. I'm able to execute the request via curl command:
note - params enclosed in * * are correct and work in the curl request
curl -H "Authorization: Basic *base 64 encoded client ID and secret*"
-d grant_type=authorization_code -d code=*auth code* -d
redirect_uri=https%3A%2F%2Fopen.spotify.com%2F
https://accounts.spotify.com/api/token
and the request works just fine, however when I try to make what I think is the exact same request in python, I always get the same bad request error
headers = {
"Authorization": "Basic *base64 encoded client ID and secret*"
}
params = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": "https://open.spotify.com/"
}
response = requests.post(
url,
params=params,
headers=headers
)
If you can help me figure out how the two requests differ and why the python one never seems to work that would be amazing.
see section 2. of https://developer.spotify.com/documentation/general/guides/authorization-guide/ for the params
You use -d flag in your curl request which stands for data.
So you should pass your params as data also in your Python POST request:
headers = {
"Authorization": "Basic *base64 encoded client ID and secret*"
}
params = {
"grant_type": "authorization_code",
"code": code,
"redirect_uri": "https://open.spotify.com/"
}
response = requests.post(
url,
data=params,
headers=headers
)
seems like you put payload under wrong argument, try to change params into json or data (depends on what type of requests that API accept):
response = requests.post(
url,
json=params,
headers=headers
)
Making a multipart/form-data request to an api endpoint: https://api-reference.smartling.com/#tag/Files%2Fpaths%2F~1files-api~1v2~1projects~1%7BprojectId%7D~1file%2Fpost
I'm using python requests module with this syntax:
headers = {
'Authorization': 'Bearer ...',
'Content-Type': 'multipart/form-data'
}
files = {'file': open('myfile.xliff', 'rb')}
data = {
'fileUri': '...',
'fileType': 'xliff',
...
}
requests.request('POST', endpoint, headers=headers, files=files, data=data)
I am receiving an error from the endpoint unfortunately it just gives me a general http 500 error.
This does work fine if I manually do it via curl:
curl -XPOST -H 'Authorization: Bearer ...' -F "file=#myfile.xliff' -F "fileUri=..." ...
So I don't believe its the endpoint not accepting a proper request.
Does this curl statement and this python call seem equivalent? Been stuck on this problem, I have tried the following resources:
https://github.com/spulec/uncurl
https://curl.trillworks.com/
To try and get a curl to python equivalent for verification.
Unfortunately uncurl cannot parse my curl statement at all despite it working and curl.trillworks gives me a malformed 'files' dictionary and no 'data':
files = {
'file': ('myfile.xliff.;type', open('myfile.xliff;type', 'rb')),
'fileUri': (None, 'myfile.xliff'),
'fileType': (None, 'xliff'),
}
which is incorrect. (I tried it anyways as I was stuck)
try remove Content-Type from headers it will created automatically
I'm building a shell application that allows my teammates to start new projects by running a few commands. It should be able to create a new project and a new repository inside that project.
Although I'm specifying the project key/uuid when creating a new repository, it doesn't work. What I'm expecting is a success message with the details for the new repository. Most of the time, this is what I get:
{"type": "error", "error": {"message": "string indices must be integers", "id": "ef4c2b1b49c74c7fbd557679a5dd0e58"}}
or the repository goes to the first project created for that team (which is the default behaviour when no project key/uuid is specified, according to Bitbucket's API documentation).
So I'm guessing there's something in between my request & their code receiving it? Because it looks like they're not even getting the request data.
# Setup Request Body
rb = {
"scm": "git",
"project": {
"key": "PROJECT_KEY_OR_UUID"
}
}
# Setup URL
url = "https://api.bitbucket.org/2.0/repositories/TEAM_NAME/REPOSITORY_NAME"
# Request
r = requests.post(url, data=rb)
In the code from the api docs you'll notice that the Content-Type header is "application/json".
$ curl -X POST -H "Content-Type: application/json" -d '{
"scm": "git",
"project": {
"key": "MARS"
}
}' https://api.bitbucket.org/2.0/repositories/teamsinspace/hablanding
In your code you're passing your data in the data parameter, which creates an "application/x-www-form-urlencoded" Content-Type header, and urlencodes your post data.
Instead, you should use the json parameter.
rb = {
"scm": "git",
"project": {
"key": "PROJECT_KEY_OR_UUID"
}
}
url = "https://api.bitbucket.org/2.0/repositories/TEAM_NAME/REPOSITORY_NAME"
r = requests.post(url, json=rb)