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)
Related
I need to update python script to work with additional data which are not there at the moment. Hence the use of "requests" but somehow it's not working for me.
Basically I need python version of below curl which is providing data I need e.g.:
curl -X GET -H "Authorization: GenieKey XXXXXXXXXXXXXXX" 'https://api.eu.opsgenie.com/v2/alerts/f013a45e-4227-44bb-a0a7-9b2cb6c7c2d9-1616676741714?identifierType=id'
{
"data":{
"seen":true,
"id":"f013a45e-4227-44bb-a0a7-9b2cb6c7c2d9-1616676741714",
"tinyId":"400",
"alias":"test MP",
"message":"MP testing",
"status":"open",
"acknowledged":true,
"isSeen":true,
"tags":[
"MP testing",
"sre"
],
"snoozed":false,
"count":1,
"lastOccurredAt":"2021-03-25T12:52:21.714Z",
"createdAt":"2021-03-25T12:52:21.714Z",
"updatedAt":"2021-04-16T10:28:18.372Z",
"source":"mail#mail.no",
"owner":"mail#mail.no",
"priority":"P5",
"teams":[
{
"id":"45c719c5-d3e1-4e75-9284-b0c75103d44a"
}
],
"responders":[
{
"type":"team",
"id":"45c719c5-d3e1-4e75-9284-b0c75103d44a"
}
],
"integration":{
"id":"132f80a5-b653-4b8a-ba33-eed59cfd6a0a",
"name":"Default API",
"type":"API"
},
"report":{
"ackTime":1892156658,
"acknowledgedBy":"mail#mail.no"
},
"ownerTeamId":"45c719c5-d3e1-4e75-9284-b0c75103d44a",
"actions":[
],
"entity":"TEST MP",
"description":"popis problemu {{priority}}",
"details":{
"priority2":"jednicka",
"issueKey":"FIXIT-981939"
}
},
"took":0.005,
"requestId":"b1f0f485-b06e-45f2-88c0-fe5809cd1ea9"
}
Part of the python script I need to create looks like this for now:
import requests
from requests.auth import HTTPBasicAuth
# Making a get request
response = requests.get('https://api.eu.opsgenie.com/v2/alerts/f013a45e-4227-44bb-a0a7-9b2cb6c7c2d9-1616676741714?identifierType=id', auth=('Correct ID', 'Correct PW'))
print(response.text) # To print unicode response string
print(response)
Result I am getting:
root#server: pts/0: 2 files -> python3 get_request2.py
<Response [422]>
{
"message":"Key format is not valid!",
"took":0.001,
"requestId":"cc21637d-c864-4ba0-92a6-e454ddb74663"
}
Can you please help to determine why I am not getting the data as it is working from shell via curl? I tried to find similar topics but no solution for working for me. I tried add headers or verify=False but no success. Sensitive info is hidden.
Source data are in JSON if it matters and python version is 3.4.10
Thank you in advance for any advice
I am currenlty thinkering with the IBMWatson Natural Language Understanding API.
In the official tutorial page it shows the basic curl command to use the api as follows:
curl -X POST -u "apikey:{apikey}" \
--header "Content-Type: application/json" \
--data '{
"url": "http://newsroom.ibm.com/Guerbet-and-IBM-Watson-Health-Announce-Strategic-Partnership-for-Artificial-Intelligence-in-Medical-Imaging-Liver",
"features": {
"sentiment": {},
"categories": {},
"concepts": {},
"entities": {},
"keywords": {}
}
}' \
"{url}/v1/analyze?version=2019-07-12"
The command basicly analyzes the page provided in the url key of data parameter and returns an analysis.
I want to do the same action using Python's requests library, however I am new to it. As far as I've gathered from the web the following format should correspond to the same request:
headers={'Content-Type': 'application/json'}
features = {"sentiment": {},"categories": {},"concepts": {},"entities": {},"keywords": {}}
myData ={
"url": "http://newsroom.ibm.com/Guerbet-and-IBM-Watson-Health-Announce-Strategic-Partnership-for-Artificial-Intelligence-in-Medical-Imaging-Liver",
"features": features
}
d = requests.post(
auth=('apikey','7LNEjCMvP6ZcNShjAkjPob7QSCfIHeZMQkn4Ho3dQgte'),
headers=headers,
data=myData,
url='https://gateway-lon.watsonplatform.net/natural-language-understanding/api/v1/analyze?version=2019-07-12'
)
However, the server responds with a "400", which I believe is caused by an error in my format.
I have tested editing my apikey, which resulted in Error code 401 "Unauthorized", as expected. So, I know that I can access the server and get authenticated with my key.
I have tested removing the "headers" parameter, which resulted in 415 "Unsupported Media Type", so the return type has to be JSON I guess.
I am not sure on what I'm doing wrong, and appreciate any kind of help. Thanks.
Take a look at the Python SDK examples for analyze and Text analytics features
in the API reference. They might help.
I'm struggling with how to properly do this REST API call in Python using requests package.
curl --user aa43ae0a-a7a7-4016-ae96-e253bb126aa8:166291ff148b2878375a8e54aebb1549 \
--request POST --header "Content-Type: application/json" \
--data '{ "startDate": "2016-05-15" , "endDate": "2016-05-16", "format": "tsv", "dataset": "appStart" }' \
https://analytics.cloud.unity3d.com/api/v2/projects/aa43ae0a-a7a7-4016-ae96-e253bb126aa8/rawdataexports
I don't know, how to set the parameters of:
r = requests.post("https://analytics.cloud.unity3d.com/api/v2/projects/aa43ae0a-a7a7-4016-ae96-e253bb126aa8/rawdataexports", ...)
Any help would be appreciated, thanks in advance.
Something like this should do the job :
auth = HTTPBasicAuth('aa43ae0a-a7a7-4016-ae96-e253bb126aa8', '1662[....]549')
payload = {
"startDate": "2016-05-15" ,
"endDate": "2016-05-16",
"format": "tsv",
"dataset": "appStart",
}
url = "https://analytics.cloud.unity3d.com/api/v2/projects/aa43ae0a-a7a7-4016-ae96-e253bb126aa8/rawdataexports"
result = requests.post(url, json=payload, auth=auth)
Authentication : --user argument of curl comand allows to setup an HTTP Basic Auth
--data was a JSON payload, while the requested content-type is configured (via headers) with Content-Type: application/json. Simplify this with requests using json argument and passing a valid python dict as payload. The payload will be converted to json, and the correct header will be added to the request to retrieve a response with json data.
Be careful ! In your question, you provided the user/password used to call this REST API. If this information is the real one, posting it on Stack Overflow is probably a security issue !
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)
I am creating an imposter process using Mountebank and want to record the request and response. To create a http imposter I used the following CURL command as described in their documentation.
curl -i -X POST -H 'Content-Type: application/json' http://127.0.0.1:2525/imposters --data '{
"port": 6568,
"protocol": "http",
"name": "proxyAlways",
"stubs": [
{
"responses": [
{
"proxy": {
"to": "http://localhost:8000",
"mode": "proxyAlways",
"predicateGenerators": [
{
"matches": {
"method": true,
"path": true,
"query": true
}
}
]
}
}
]
}
]
}'
I have another server running at http://localhost:8000 which is listening to all the request coming to port 6568.
Output of my server now:
mb
info: [mb:2525] mountebank v1.6.0-beta.1102 now taking orders - point your browser to http://localhost:2525 for help
info: [mb:2525] POST /imposters
info: [http:6568 proxyAlways] Open for business...
info: [http:6568 proxyAlways] ::ffff:127.0.0.1:55488 => GET /
I want to record all the request and response going around, and unable to do right now. When I enter curl -i -X GET -H 'Content-Type: application/json' http://127.0.0.1:6568/ it is giving me a response but how I do store it?
Also can anyone explain me the meaning of
save off the response in a new stub in front of the proxy response:
(from this Mountebank documentation)
How to store proxy results
The short answer is that mountebank already is storing it. You can verify that by looking at the output of curl http://localhost:2525/imposters/6568. The real question is how do you replay the stored response?
The common usage scenario with mountebank proxies is that you record the proxy responses on one running instance of mb, save off the results, and then start the next instance of mb with those saved responses. The way you would do that is to have the system under test talk to service you're trying to stub out via the mountebank proxy under whatever conditions you need it to, and then save off the responses (and their request predicates) by sending an HTTP GET or DELETE to http://localhost:2525/imposters/6568?removeProxies=true&replayable=true. You feed the JSON body of that response into the next mb instance, either through the REST API, or by saving it on disk and starting mountebank with a command of something like mb --configfile savedProxyResults.json. At that point, mountebank is providing the exact same responses to the requests without connecting to the downstream service.
Proxies create new stubs
Your last question revolves around understanding how the proxyAlways mode works. The default proxyOnce mode means that the first time a mountebank proxy sees a request that uniquely satisfies a predicate, it queries the downstream service and saves the response. The next time it seems a request that satisfies the exact same predicates, it avoids the downstream call and simply returns the saved result. It only proxies downstream once for the same request. The proxyAlways mode, on the other hand, always sends the requests downstream, and saves a list of responses for the same request.
To make this clear, in the example you copied we care about the method, path, and query fields on the request, so if we see two requests with exactly the same combination of those three fields, we need to know whether we should send the saved response back or continue to proxy. Imagine we first sent:
GET /test?q=elephants
The method is GET, the path is /test, and the query is q=elephants. Since this is the first request, we send it to the downstream server, which returns a body of:
No results
That will be true regardless of which proxy mode you set mountebank to, since it has to query downstream at least once. Now suppose, while we're thinking about it, the downstream service added an elephant, and then our system under test makes the same call:
GET /test?q=elephants
If we're in proxyOnce mode, the fact that the elephant was added to the real service simply won't matter, we'll continue to return our saved response:
No results
You'd see the same behavior if you shut the mountebank process down and restarted it as described above. In the config file you saved, you'd see something like this (simplifying a bit):
"stubs": [
{
"predicates": [{
"deepEquals': {
"method": "GET",
"path": "/test",
"query": { "q": "elephants" }
}
}],
"responses": [
{
"is": {
"body": "No results"
}
}
]
}
]
There's only the one stub. If, on the other hand, we use proxyAlways, then the second call to the GET /test?q=elephants would yield the new elephant:
1. Jumbo reporting for duty!
This is important, because if we shut down the mountebank process and restart it, now our tests can rely on the fact that we'll cycle through both responses:
"stubs": [
{
"predicates": [{
"deepEquals': {
"method": "GET",
"path": "/test",
"query": { "q": "elephants" }
}
}],
"responses": [
{
"is": {
"body": "No results"
}
},
{
"is": {
"body": "1. Jumbo reporting for duty!"
}
}
]
}
]