What is wrong with my patch request to the Connectwise Rest API? - python

I've got a question about the Rest API for Connectwise. I've been doing get and post requests with no issue, but when I do a patch request I get a 400 response with 'field value is invalid' message regardless of what I try. I'm on 2016v1 and using the Rest API making calls from Python with the requests library.
The Rest API documentation says the following object is supposed to be passed in the body, but I haven't a clue what values are supposed to go with these keys:
{
op (string, optional),
path (string,optional),
value (string,optional)
}
I've tried dozens of calls including with the following bodies:
{'summary': 'updatedsummarytext'}
{'value': {'summary': 'updatedsummarytext'}}
{'op': {'summary': 'updatedsummarytext'}}
I have only gotten the following response so far:
<Response [400]>
{
"code": "InvalidObject",
"message": "operations object is invalid",
"errors": [
{
"code": "InvalidField",
"message": "The field value is invalid.",
"resource": "operations",
"field": "value"
}
]
}
Is their a specific value that connectwise is expecting for the op or value keys, or is there something I'm missing unique to Patch rest api calls?

The PATCH calls at a basic level use RFC6902.
Consider the following (simplified) Ticket document:
{
"summary": "Initial Ticket Summary",
"id": 1,
"company": {
"id": 5
},
"board": {
"id": 10
}
}
If you wish to update the summary field, your PATCH request JSON would look like this:
[
{"op": "replace", "path": "/summary", "value": "Updated Summary"}
]
Hope this helps.

Related

Override the automatically generated parameters in FastAPI

I am writing FastAPI program that is just a bunch of #app.get endpoints for querying data. There are many, many different query arguments they could use that are automatically generated from a config file, for example the #app.get("/ADJUST_COLOR/") endpoint could look something like /ADJUST_COLOR/?RED_darker=10&BLUE_lighter=43&GREEN_inverse=true where all those parameters are generated from a list of colors and a list of operations to perform on those colors (This is only an example, not what I am actually doing).
The way I am doing that is to take in the request object like this:
#app.get("/ADJUST_COLOR/")
def query_COLORS( request: Request ):
return look_through_parameters(request.query_params)
But the problem is that the automatically generated swagger UI does not show any useful data:
Since I am parsing the request manually there are no parameters generated. But since I have a full list of the parameters I am expecting then I should be able to generate my own documentation and have the UI show it.
I have looked through these two documents: https://fastapi.tiangolo.com/tutorial/path-operation-configuration/
And https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/
But I was not able to figure out if it was possible or not
You can define custom api schema in your route via openapi_extra (this is a recent feature of FastAPI, 0.68 will work but I'm not sure the exact earliest version that supports this):
#app.get("/ADJUST_COLOR/", openapi_extra={
"parameters": [
{
"in": "query",
"name": "RED_darker",
"schema": {
"type": "integer"
},
"description": "The level of RED_darker"
},
{
"in": "query",
"name": "BLUE_lighter",
"schema": {
"type": "integer"
},
"description": "The level of BLUE_lighter"
},
{
"in": "query",
"name": "GREEN_inverse",
"schema": {
"type": "boolean"
},
"description": "is GREEN_inverse?"
},
]
})
async def query_COLORS(request: Request):
return look_through_parameters(request.query_params)
Which is rendered like this in your api /docs:

python yt api "The request is missing a valid API key."

im using the youtube api in python, i using this code :
r = requests.get('https://www.googleapis.com/youtube/v3/videos')
print(r.text)
and i get this output :
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"errors": [
{
"message": "The request is missing a valid API key.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
Process finished with exit code 0
i already have my api key so my question is how do i add this api key to the GET request and make this work
The API key should be added as a GET parameter called key, like so:
r = requests.get('https://www.googleapis.com/youtube/v3/videos?key=YOUR_API_KEY&id=7lCDEYXw3mM&...')
print(r.text)
The documentation has a few more examples.

JSON Parsing issue - Python

So i have build a REST Client that returns JSON response. However, i have an issue, where the JSON output is not exactly what i need:
Current Response:
{
"output": {
"status": "Device 'Test' does not exist",
"result": "null",
"response": {
"output": "success",
"result": 204
}
}
}
This output has an outermost enclosing "output" key, but i don't want that to be present. So basically i want my response to look like below:
{
"status": "Device 'Test' does not exist",
"result": "null",
"response": {
"output": "success",
"result": 204
}
}
I did try converting the JSON to Dict and then remove it, but no luck? any suggestions how to achieve this?
Thank you
if your response is already a dictionary or a json object then you can do following
value_required = response["output"]
if it is in text format (which I think it is) then you just need to do the following
import json
value_required = json.loads(response)["output"]
You should be able to do:
response = json.loads(response)['output']

Python facebook-sdk: retrieving names of users who posted a message on a page

I want to use the Python facebook-sdk library to retrieve the names of the persons who posted a message on a Facebook page I created.
This is an example, returned by the Graph API explorer:
{
"feed": {
"data": [
{
"from": {
"name": "Ralph Crützen",
"id": "440590514975673"
},
"message": "Nog een test.",
"created_time": "2015-10-17T19:33:30+0000",
"id": "649463214822976_649745285127205"
},
{
"from": {
"name": "Ralph Crützen",
"id": "440590514975673"
},
"message": "Testing!",
"created_time": "2015-10-16T20:44:17+0000",
"id": "649463214822976_649492455153388"
},
... etc ...
But when I use the following Python code...
graph = facebook.GraphAPI(page_access_token)
profile = graph.get_object('tinkerlicht')
posts = graph.get_connections(profile['id'], 'feed')
print(posts['data'][0]['message'])
print(posts['data'][0]['from']['name'])
...only the message value is printed. Printing the name of the person who posted the message gives the error:
print(posts['data'][0]['from']['name'])
KeyError: 'from'
At first, I thought that I needed the read_page_mailboxes permission. To use this permission, it has to be approved by Facebook, so I submitted a request. But Facebook replied:
"You don't need any additional permissions to post to Pages or blogs that you administer. You only need to submit your app for review if your app will use a public-facing login."
So what exactly is the reason I can't retrieve the from data from the messages feed? (While reading it from the Graph API explorer works fine...)
Btw, I'm using a page access token which never expires. I generated this token the way it's described here.

Flask or Werkzeug/0.9.4 breaking POST data

I have found some behaviour of Flask-restful caused I think by Werkzeug/0.9.4 that I do not understand. It seems that the use of Multidict is breaking my data when I try to POST valid JSON that contains a "=".
Here's my test JSON:
{
"alert": {
"#id": "90",
"action": "hoojimaflip",
"fruit": {
"#bowl": "bananas",
"#protocol": "tcp"
},
"url": "https://this-is-a-sample/paramer?id=90"
}
}
Here is the POST method.
def post(self):
f1=open("./log", 'w+')
data = request.json
if not data:
# I know this is not equivalent to the JSON above.
# Just troubleshooting by dumping it all out.
data = request.form
print >>f1, data
return ('', 201)
If I POST using cURL with application/json it's fine. I get the POSTed JSON correctly in request.data. I will need to render it back to JSON later, but no issue.
{
u'alert': {
u'#id': u'90'
u'action': u'hoojimaflip',
u'fruit': {
u'#bowl': u'bananas',
u'#protocol': u'tcp'
},
u'url': u'https://this-is-a-sample/paramer?id=90',
}
}
If I post via cURL with application/x-www-form-urlencoded, then I should be able to get the data in request.form. But, it seems that something is breaking my data.
ImmutableMultiDict([('
{ "alert": {
"#id": "90",
"action": "hoojimaflip",
"fruit": {
"#bowl": "bananas",
"#protocol": "tcp"
},
"url": "https://this-is-a-sample/paramer?id', u'90"
}
}'
)])
The "=" sign is being used as some kind of record separator and breaking the POSTed JSON.
Does anyone have any ideas? Am I missing something obvious?
Thanks!
If an external application is stubbornly POST-ing with an alternative mime-type, you can force Flask to treat the data as JSON anyway by using the request.get_json() method instead, setting the force argument to True:
data = request.get_json(force=True)
Don't try to treat a JSON payload as form data, that'll never work.

Categories