I'm using swagger editor (version 2.10.5) to generate a flask api that uses custom headers and started to add the following line to each path:
parameters:
- $ref: '#/parameters/X-Forwarded-Host'
the relative definition:
X-Forwarded-Host:
name: 'X-Forwarded-Host'
in: header
description: Forwarded host header
required: true
type: string
Then running the auto-generated flask server
$ python3 -m swagger_server
creates some problems:
When making a curl request, headers are not right evaluated:
$ curl -X GET --header 'Accept: application/json' --header 'X-Forwarded-Host: example.com' http://localhost:8080
returns
health_get() missing required positional argument: 'X_Forwarded_Host'
Auto-generated tests are useless too:
headers = [('X_Forwarded_Host', 'X_Forwarded_Host_example'), ...
What am I doing wrong? Why is swagger-editor (or codegen) setting all "-" to "_"?
Thanks in advance
Ok, I figured out..
The problem was NOT with swagger-editor itself but how it generates the flask (Connexion) code.
Connexion request handling docs (url) says:
"Currently, header parameters are not passed to the handler functions as parameters. But they can be accessed through the underlying connexion.request.headers object which aliases the flask.request.headers object."
The solution is to remove all function attributes (related to headers) from the auto-generated controller and pick them from the request object, therefore:
From:
def health_get(X_Forwarded_Host):
...
To:
def health_get():
forwarded_host = connexion.request.headers['X-Forwarded-Host']
Bye!
Related
I am using lacinia-pedestal for server and re-graph for client side clojuresript
My client code looks like
(re-frame/dispatch [::re-graph/init {:http-url
"http://localhost:8888/graphql"
:ws-url nil
:http-parameters {:headers {"Content-Type" "application/graphql"}
}}])
(re-frame/dispatch [::re-graph/query
"{current_user(token: ss) {id}}"
nil some-func])
However when I connect to my server, I see following error in console log
"message":"Failed to parse GraphQL query.","extensions":{"errors":[{"locations":[{"line":1,"column":null}],"message":"mismatched input '\"query\"' expecting {'query', 'mutation', 'subscription', '...', NameId}"}
Following curl request it works,
curl http://localhost:8888/graphql
-H 'Content-Type: application/graphql'
-d 'query {
current_user(token: "foo"){
id
}}'
Any help will be appreciated
I am attaching my network console log
re-graph uses application/json by default to send the query and variables as a JSON payload. You don't need to override the content-type in your init call.
I am trying to integrate compojure-api (version 1.1.12) into an existing compojure-based application. While most things work, I am having an issue with request coercions on an existing REST call whose usage would be difficult to change at this point.
It's a POST
It expects parameters via multipart/form-data
Most parameters are optional.
Most parameters are simple: string or array of string.
One optional parameter is expected to be a JSON-encoded map.
I define the route like this:
(POST "/endpoint" request
:multipart-params
[required-strings :- (describe [s/Str] "Required, an array of strings"),
{optional-string :- (describe s/Str "An optional string") ""},
{others :- {s/Keyword s/Any} {}}]
...)
This works, unless I try to pass other-parameters in a request. For example, via curl:
curl -F "required-strings=[\"Hello\"]" -F "others={\"a\":1.0}" ...
This results in an invalid request (i.e. status 400) error with the content:
{"errors":{"others":"(not (map? a-clojure.lang.PersistentVector))"}}
I'm using ring-default's site-defaults, and I haven't modified the default coercions for the compojure api. I've traced the error to compojure.api.coerce/coerce. I can see the value that the coercer is working on, and it looks like:
{:required-strings "[\"Hello\"]"
:others "{\"a\":1.0}"}
On line 59 of coerce.clj, (coerce value) returns an error (per schema.utils/error?).
So, is it not possible to coerce a JSON-encoded multipart parameter to a Clojure map? I can define the parameter to be a string instead of a map, and do the parsing myself, but this defeats the purpose of using compojure-api and ring-swagger.
The coercer for others expects a clojure map not a string. To make it work you have to options.
First option: add wrap-json-params middleware and do application/json request instead of multipart/form-data:
curl ... -H 'Content-Type: application/json' \
-d $'{
"required-strings": ["Hello"],
"others": {"a": 1.0}
}'
Second option: add wrap-nested-params middleware and multipart/form-data request using nested param names:
curl ... -H 'Content-Type: multipart/form-data' \
-F "required-strings[]=Hello" \
-F "others[a]=1.0"
There are three variants of format selection:
curl -uadmin:admin "http://localhost:8080/alfresco/service/hellouser.json"
curl -uadmin:admin "http://localhost:8080/alfresco/service/hellouser?format=json"
curl -uadmin:admin -H "Accept: text/html" "http://localhost:8080/alfresco/service/hellouser"
But this is unclear from the DOC what format would be selected for next query:
curl -uadmin:admin -H "Accept: text/html" "http://localhost:8080/alfresco/service/hellouser.xml?format=json"
I expect json here.
May someone provide links to relevant specifications or documentation which describes priority how {format} negotiated? like this is described for Rails:
Rails picks up the expected format from the query parameter format, or if not there from the URL path suffix, or it not there from the Accept header
UPD
The controller can handle all supplied formats: json, xml, html
UPD
Another corner case:
curl -uadmin:admin "http://localhost:8080/alfresco/service/hellouser.pl?format=json"
curl -uadmin:admin "http://localhost:8080/alfresco/service/hellouser.pl?format=xml"
I'd believe you wouldn't have a 200 response, only an error with content negotiation.
The code shows that:
?format=json(format_query_param) will be discarded by the .xml (format_suffix)
filter available renderers leaving only the XMLRenderer left
then it will loop on the accept header but none will match text/html
finally this will be down to the exception
Followed instructions in the below to send the json request payload in the curl command
https://docs.wso2.com/display/DSS351/JSON+Mapping+Sample.
Below is the curl command:
D:\testing\curl-7.46.0-win64\bin>curl -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' --data "#article-payload.json" http://8.39.51.27:9763/services/KMTool/insertarticles
The error:
**Error: Getting below error:**
Warning: Couldn't read data from file "article-payload.json", this makes an
Warning: empty POST.
curl: (6) Could not resolve host: application
curl: (6) Could not resolve host: application
<axis2ns22:DataServiceFault xmlns:axis2ns22="http://ws.wso2.org/dataservice"><ax
is2ns22:current_params>{articleTitle=null, articlePath=null, articleContent=null
, articleDesc=null, categoryID=null}</axis2ns22:current_params><axis2ns22:source
_data_service><axis2ns22:data_service_name>KMTool</axis2ns22:data_service_name><
axis2ns22:description>N/A</axis2ns22:description><axis2ns22:location>\KMTool.dbs
</axis2ns22:location><axis2ns22:default_namespace>http://ws.wso2.org/dataservice
</axis2ns22:default_namespace></axis2ns22:source_data_service><axis2ns22:ds_code
>DATABASE_ERROR</axis2ns22:ds_code><axis2ns22:nested_exception>org.postgresql.ut
il.PSQLException: ERROR: null value in column "articleTitle" violates not-null c
onstraint
Detail: Failing row contains (31, null, null, null, null, null).</axis2ns22:ne
sted_exception><axis2ns22:current_request_name>_postinsertarticles</axis2ns22:cu
rrent_request_name></axis2ns22:DataServiceFault>
I saved the file under below location:
C:\Users\testUser\Downloads\wso2dss-3.5.1\repository\deployment\server\dataservices\article-payload.json
Not sure what is causing issue. Just followed the instructions provided by wso2dss documentation.
Seems like the parameters are not passed correctly (ex: articleTitle has become null, but in the database table you have defined it as a not null column). The article-payload.json file should be located in the directory that you are trying to invoke the request using curl (ie. inside D:\testing\curl-7.46.0-win64\bin)
I i am new to django-rest-auth and apis.
Its the first time i build a rest auth and i am not very familiar with Authorization headers and Content Types.
I am trying to understand why when i try to authenticate a user in /login/ with Basic Authorization like this:
curl -X POST -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" 'https://myurl.com/rest-auth/login/' --insecure
i got this error message:
{"password":["(This field is required"]}
When passing the username and password in the body like this:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'username=myuser&password=mypassword' 'https://myurl.com/rest-auth/login/' --insecure
I got the key:
{"key":"b5c0f3a9c7b2fc2f58a74b25f816e2968c64712f"}
Why this is happening?
I also wonder why when trying the same in /user/ it didn't throw me any error and give me my user model serialized
curl -X GET -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" -H "Cache-Control: no-cache" 'https://myurl.com/rest-auth/user/' --insecure
The only difference i can understand is that in /login i am using POST and in /user/ is GET
Can anybody explain this to me?
Thanks for reading!
The '/auth/login/' endpoint is specifically for getting an authentication token to use with token authentication on the rest of the app. It doesn't itself support any authentication methods. The second curl command uses the correct method. the third curl command works because you are using an endpoint which does support Basic Authentication (you can could also use the token you got in the second call).
pls refer
Inet Mode Example (unprivileged user with AltAuth)
$ echo -e "GET http://localhost/slurm/v1/diag HTTP/1.1\r\nAccept: */*\r\n" |
slurmrestd -f etc/slurm.token.conf
● slurmrestd: operations_router: /slurm/v1/diag for pipe:[1052487]
● HTTP/1.1 200 OK
● Content-Length: 973
● {
● "parts_packedg": 1,
● "req_timeg": 1568051342,
● "req_time_startg": 1568050812,
● "server_thread_count": 3,
… JSON continues ...