C# POST request from C# asp.net to python - python

I try to convert a working c# asp.net Post Request to python code but can#t define the json post request right. Here the working C# example:
public async Task Run()
{
var request = new ExternalExecutionRequest()
{
ConfigPath = Path.Combine(_destinationDir, "Export.json"),
TemplatesPath = _destinationDir,
FilesPaths = new List<string>() { Path.Combine(_destinationDir, "export_xls.xlsx")
},
OutputPath = Path.Combine(_destinationDir, "OutputRest"),
Compress = true
};
var httpClient = new HttpClient();
var response = await httpClient.PostAsJsonAsync($"http://localhost:63155/Login", "c:\\lizenz.lic");
request.Token = await response.Content.ReadAsAsync<string>();
await httpClient.PostAsJsonAsync($"http://localhost:63155/AnalyseRequest", request);
await httpClient.PostAsJsonAsync($"http://localhost:63155/Logout", "");
}
I tried different functions with the librarys request or because it is an asynchronous request with grequests. But i can't even name the variables right in the json request.
license_path = "c:\\lizenz.lic"
license_json = {"value": license_path}
response = grequests.post("http://localhost:63155/Login", json=license_json)
Could someone help me to convert the working request to python?

Related

Fetch JSON.parse: unexpected end of data at line 1 column 1 of the JSON data fast api

Hi i got a python fast api backend server.
#app.get("/getName")
async def getName() -> JSONResponse:
data_sniffer = DataSniffer()
data = json.dumps(data_sniffer.get_data())
print(data)
return JSONResponse(content=data,headers={'content-type':'application/json'})
this is the console output of data :{"first_name": "test"}
My Frontend Code looks like this
useEffect(() => {
async function query() {
const options = {
method: 'GET',
mode: 'no-cors',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application-json',
},
};
const res = await fetch('http://127.0.0.1:3000/getName', options);
console.log(res);
const data = await res.json();
console.log(data);
}
query();
});
but i get following error message SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
my network response looks like this:
"{"first_name": "test"}"
Has anyone a clue why fetch cant parse the json?
For anyone who has the same issue what worked for me is I moved my Backend folder to the root directory of my Frontend and removed the mode no-cors of the fetch request. I installed the no cors app and now it works. I think the mode no-cors broke my request.

API POST request - Python example to Google Script - 'Unexpected end of JSON input'

I'm trying to connect a Google spreadsheet to snov.io service using an API POST request, they have provided a Python code as example and I have tried to run the google script below based on it, but without success. Any ideas? Thank you :)
Python (provided by the company)
def get_access_token():
params = {
'grant_type':'client_credentials',
'client_id':'c57a0459f6t141659ea75cccb393c111',
'client_secret': '77cbf92b71553e85ce3bfd505214f40b'
}
res = requests.post('https://api.snov.io/v1/oauth/access_token', data=params)
resText = res.text.encode('ascii','ignore')
return json.loads(resText)['access_token']
Google Script (Error:SyntaxError:'Unexpected end of JSON input')
var params = {
'grant_type':'client_credentials',
'client_id':'c57a0459f6t141659ea75cccb393c111',
'client_secret': '77cbf92b71553e85ce3bfd505214f40b',
'method':'post'
}
var url = 'https://api.snov.io/v1/oauth/access_token';
var response = UrlFetchApp.fetch(url,params)
var json = response.getContentText();
obj = JSON.parse(json);
token = obj.result.access_token;
return token
In order to achieve the same request with your python script, how about modifying your Google Apps Script as follows?
Modified script:
From:
var params = {
'grant_type':'client_credentials',
'client_id':'c57a0459f6t141659ea75cccb393c111',
'client_secret': '77cbf92b71553e85ce3bfd505214f40b',
'method':'post'
}
var url = 'https://api.snov.io/v1/oauth/access_token';
var response = UrlFetchApp.fetch(url,params)
To:
var params = {
'grant_type': 'client_credentials',
'client_id': 'c57a0459f6t141659ea75cccb393c111',
'client_secret': '77cbf92b71553e85ce3bfd505214f40b',
}
var url = 'https://api.snov.io/v1/oauth/access_token';
var response = UrlFetchApp.fetch(url, {method: "post", payload: params});
In this case, even when method: "post" is removed, the same request is achieved.
Reference:
fetch(url, params)

HTTP POST a python file using dart

I want to send a python file via http post in dart. I can do it in CURL the following way:
curl -X POST -F 'file=#/home/user/file.py' http://192.168.80.1:9888/dir/file.py
I am also able to do it in python like this:
import requests
url = 'http://192.168.80.1:9888/dir/file.py'
files = {'file': open('file.py', 'rb')}
print(files)
r = requests.post(url, files=files)
But in dart I am not able to send the post. I have tried several methods but is at this on currently:
import 'package:http/http.dart' as http;
import 'dart:io';
void main(List<String> arguments) async {
var response;
var file;
var url = 'http://192.168.80.1:9888/dir/file.py';
file = File('file.py').readAsStringSync();
var files = {'file': file};
response = await http.post(url, body: files);
}
Which result in the following exception: Exception has occurred.
ClientException (Connection closed before full header was received)
I know that the server is working due to CURL and python. How do I mimic the functionality in CURL/python using dart?
I was able to send the python file via a POST using dio.
import 'package:dio/dio.dart' as dio;
Future<dio.FormData> FormData3() async {
return dio.FormData.fromMap({
'file': await dio.MultipartFile.fromFile(
'files/file.py',
filename: 'file.py',
),
});
}
Future<dio.Response> sendFile() async {
dio.Response response;
response = await dio.Dio().post('http://192.168.80.1:9888/dir/file.py',
data: await FormData2(), onSendProgress: (received, total) {
if (total != -1) {
print((received / total * 100).toStringAsFixed(0) + '%');
}
},
options: dio.Options(
method: 'POST',
responseType: dio.ResponseType.plain,
));
return response;
}
void main() async {
response = await sendFile();
}

How do i authenticate to and get catalog from Azure Data Catalog using Rest API in Python

I would like to get the name of the catalog from Azure Data Catalog using API. When I tried using the following command to get catalog from Azure Data Catalog
requests.get("https://management.azure.com/subscriptions/{id}/resourceGroups/{group_name}/providers/Microsoft.DataCatalog/catalogs/{catalogname}")
as mentioned in the link https://learn.microsoft.com/en-us/rest/api/datacatalog/data-catalog-data-catalog
It throws the following error
Response [400]
Looks like I have to authenticate first. How do I authenticate prior to getting catalog?
Adding the new answer in python
for getting the auth context in python you could do the following
here is the settings for the parameters we need it while calling graph api.
RESOURCE = "https://graph.microsoft.com" # Add the resource you want the access token for
TENANT = "Your tenant" # Enter tenant name, e.g. contoso.onmicrosoft.com
AUTHORITY_HOST_URL = "https://login.microsoftonline.com"
CLIENT_ID = "Your client id " # copy the Application ID of your app from your Azure portal
CLIENT_SECRET = "Your client secret" # copy the value of key you generated when setting up the application
# These settings are for the Microsoft Graph API Call
API_VERSION = 'v1.0'
here is the code for logging in
AUTHORITY_URL = config.AUTHORITY_HOST_URL + '/' + config.TENANT
REDIRECT_URI = 'http://localhost:{}/getAToken'.format(PORT)
TEMPLATE_AUTHZ_URL = ('https://login.microsoftonline.com/{}/oauth2/authorize?' +
'response_type=code&client_id={}&redirect_uri={}&' +
'state={}&resource={}')
def login():
auth_state = str(uuid.uuid4())
flask.session['state'] = auth_state
authorization_url = TEMPLATE_AUTHZ_URL.format(
config.TENANT,
config.CLIENT_ID,
REDIRECT_URI,
auth_state,
config.RESOURCE)
resp = flask.Response(status=307)
resp.headers['location'] = authorization_url
return resp
here is how you can retrieve the token
auth_context = adal.AuthenticationContext(AUTHORITY_URL)
token_response = auth_context.acquire_token_with_authorization_code(code, REDIRECT_URI, config.RESOURCE,
config.CLIENT_ID, config.CLIENT_SECRET)
and then you can create a endpoint for your azure data catalog api. Here is the http header for the same-
http_headers = {'Authorization': 'Bearer ' + token_response['accessToken'],
'User-Agent': 'adal-python-sample',
'Accept': 'application/json',
'Content-Type': 'application/json',
'client-request-id': str(uuid.uuid4())}
and then finally you can call the api. Here endpoint being the data catalog API URL.
data = requests.get(endpoint, headers=http_headers, stream=False).json()
Hope it helps.
To call a Data Catalog REST operation, create an instance of AuthenticationContext and call AcquireToken. AuthenticationContext is part of the Active Directory Authentication Library NuGet package. To install the Active Directory Authentication Library NuGet package in Visual Studio,run
"Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory"
from the NuGet Package Manager Console.
Here is the code to get the token for the same.
static async Task<AuthenticationResult> AccessToken()
{
if (authResult == null)
{
//Resource Uri for Data Catalog API
string resourceUri = "https://api.azuredatacatalog.com";
//To learn how to register a client app and get a Client ID, see https://msdn.microsoft.com/en-us/library/azure/mt403303.aspx#clientID
string clientId = clientIDFromAzureAppRegistration;
//A redirect uri gives AAD more details about the specific application that it will authenticate.
//Since a client app does not have an external service to redirect to, this Uri is the standard placeholder for a client app.
string redirectUri = "https://login.live.com/oauth20_desktop.srf";
// Create an instance of AuthenticationContext to acquire an Azure access token
// OAuth2 authority Uri
string authorityUri = "https://login.windows.net/common/oauth2/authorize";
AuthenticationContext authContext = new AuthenticationContext(authorityUri);
// Call AcquireToken to get an Azure token from Azure Active Directory token issuance endpoint
// AcquireToken takes a Client Id that Azure AD creates when you register your client app.
authResult = await authContext.AcquireTokenAsync(resourceUri, clientId, new Uri(redirectUri), new PlatformParameters(PromptBehavior.Always));
}
return authResult;
}
Here is the sample code to get the data asset base on id
// The Get Data Asset operation retrieves data asset by Id
static JObject GetDataAsset(string assetUrl)
{
string fullUri = string.Format("{0}?api-version=2016-03-30", assetUrl);
//Create a GET WebRequest as a Json content type
HttpWebRequest request = WebRequest.Create(fullUri) as HttpWebRequest;
request.KeepAlive = true;
request.Method = "GET";
request.Accept = "application/json;adc.metadata=full";
try
{
var response = SetRequestAndGetResponse(request);
using (var reader = new StreamReader(response.GetResponseStream()))
{
var itemPayload = reader.ReadToEnd();
Console.WriteLine(itemPayload);
return JObject.Parse(itemPayload);
}
}
catch (WebException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.Status);
if (ex.Response != null)
{
// can use ex.Response.Status, .StatusDescription
if (ex.Response.ContentLength != 0)
{
using (var stream = ex.Response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
}
}
return null;
}
Here is how you can set the request, token and get the response.
static HttpWebResponse SetRequestAndGetResponse(HttpWebRequest request, string payload = null)
{
while (true)
{
//To authorize the operation call, you need an access token which is part of the Authorization header
request.Headers.Add("Authorization", AccessToken().Result.CreateAuthorizationHeader());
//Set to false to be able to intercept redirects
request.AllowAutoRedirect = false;
if (!string.IsNullOrEmpty(payload))
{
byte[] byteArray = Encoding.UTF8.GetBytes(payload);
request.ContentLength = byteArray.Length;
request.ContentType = "application/json";
//Write JSON byte[] into a Stream
request.GetRequestStream().Write(byteArray, 0, byteArray.Length);
}
else
{
request.ContentLength = 0;
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
// Requests to **Azure Data Catalog (ADC)** may return an HTTP 302 response to indicate
// redirection to a different endpoint. In response to a 302, the caller must re-issue
// the request to the URL specified by the Location response header.
if (response.StatusCode == HttpStatusCode.Redirect)
{
string redirectedUrl = response.Headers["Location"];
HttpWebRequest nextRequest = WebRequest.Create(redirectedUrl) as HttpWebRequest;
nextRequest.Method = request.Method;
request = nextRequest;
}
else
{
return response;
}
}
}
Basically you need to get the bearer token and pass it as a request parameter to get the catalog using azure data catalog api.
for further code sample, please browse below code repository.
https://github.com/Azure-Samples/data-catalog-dotnet-get-started
Hope it helps.

How can I make a Swift HTTP POST hit a Flask server?

I am trying to post some data to a Flask server, whose code is the following:
#app.route('/tasks', methods=['POST'])
def create_task():
if not request.json or not 'title' in request.json:
abort(400)
task = {
'title': request.json['title'],
'description': request.json.get('description', ""),
}
return jsonify({'task' : task}), 201
When I run this, it works fine, and I can make POST requests successfully using curl, with the expected behavior on the back end above and the expected return value in command line. I want to make a post to this server using Swift, however, and am having trouble with that. I have followed the tutorial detailing this behavior here. In particular, I put the code in my AppDelegate.swift so it is executed as soon as the app launches. The full code is in the link posted, but for reference I am also posting it below:
func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
var request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:4567/login"))
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var params = ["username":"jameson", "password":"password"] as Dictionary<String, String>
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(err != nil) {
println(err!.localizedDescription)
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: '\(jsonStr)'")
}
else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
var success = parseJSON["success"] as? Int
println("Succes: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: \(jsonStr)")
}
}
})
task.resume()
return true
}
However, when I launch this app, I have the following logged in my xcode
Response: <NSHTTPURLResponse: 0x7fc4dae218a0> { URL: http://localhost:5000/task } { status code: 404, headers {
"Content-Length" = 26;
"Content-Type" = "application/json";
Date = "Tue, 07 Oct 2014 19:22:57 GMT";
Server = "Werkzeug/0.9.6 Python/2.7.5";
} }
Body: {
"error": "Not found"
}
Succes: nil
I've been working with this and tinkering with the input, it seems that the back end is fine, but I'm wondering what is wrong with this front end, unfortunately Swift documentation is for the moment fairly moot on this point and seems to be the only solution floating around for RESTful API calls at the moment.
Your flask route is '/tasks' and you're trying to post to http://localhost:5000/task. Is that a typo, or are you a victim of failure to pluralize?

Categories