Page 1 of 1

Use cUrl to upload data to online server

PostPosted: Sat May 22, 2021 2:41 pm
by Marc Venken
I was able to retrieve data from my webshop hosted by a 3the company. Normaly we can retrieve and upload data by API

Download = working (I retrieve some productdata)

Upload (Change a name from a product seems to be more difficult)

For upload, the server samples show this :

curl -X PATCH "http://swagger.shoptrader.com/api/v2/products/1994?token=abc" -H "accept: application/json" -H "token: abc" -H "Content-Type: application/json" -d "{\"model\":\"string\",\"sku\":\"string\",\"ean\":\"string\",\"name\":\"Test 1994\",\"description\":\"string\",\"introDescription\":\"string\",\"extraDescription\":\"string\",\"metaTitle\":\"string\",\"metaKeyword\":\"string\",\"metaDescription\":\"string\",\"quantity\":0,\"categoryId\":0,\"price\":0,\"purchasePrice\":0,\"status\":true,\"taxRate\":0,\"manufacturerId\":0,\"width\":0,\"height\":0,\"weight\":0,\"images\":[\"ImageOne\"],\"imagesAlt\":[\"ImageOneAlt\"],\"resources\":[{\"resourceKey\":\"key\",\"resourceValue\":\"value\",\"resourceType\":\"type\"}]}"

and there is

Request Url :

http://swagger.shoptrader.com/api/v2/pr ... ?token=abc

For retrieve we put : "https://swagger.shoptrader.com/api/v2/products?limit=100&token=abc" and this gives resulting data to retrieve

Now for upload/edit online, how does the program need to get the command ? The request Url = not having all the data i thing

Online sample with Swagger: http://apidocs.shoptrader.com/#/Products/productsPatch

Re: Use cUrl to upload data to online server

PostPosted: Sat May 22, 2021 8:02 pm
by Marc Venken
I found a testing server from swagger, and there the folowing is working :

curl -X 'PUT' \
'https://petstore.swagger.io/v2/pet' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": 666,
"name": "Noyca",
"status": "available"
}'

the request url :

https://petstore.swagger.io/v2/pet

I get a Response on the demo server :

200 so it is done ok and
{
"id": 666,
"name": "Noyca",
"photoUrls": [],
"tags": [],
"status": "available"
}

The demo server : https://editor.swagger.io/?_ga=2.123072 ... 1621675979

This is changing the content of the online database. It is 1 field to update, so if I can get this to work from FW i think I can get it to work for my shop as well.

I've seen several postings on cUrl, but non I get working for this code.

In fact,

Re: Use cUrl to upload data to online server

PostPosted: Sat May 22, 2021 8:25 pm
by Marc Venken
I'm getting close.

I found a program that converts cUrl code to programming code.

Can any of these help finding a FW solution ?

So

curl -X 'PUT' \
'https://petstore.swagger.io/v2/pet' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": 666,
"name": "Troy",
"status": "available"
}'

becomes :

PHP

Code: Select all  Expand view


$headers = array(
   "accept: application/json",
   "Content-Type: application/json",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

$data = <<<DATA
{
  "id": 666,
  "name": "Troy",
  "status": "available"
}
DATA;

curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

//for debug only!
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

$resp = curl_exec($curl);
curl_close($curl);
var_dump($resp);

?>

 


JAVASCRIPT

Code: Select all  Expand view

var url = "https://petstore.swagger.io/v2/pet";

var xhr = new XMLHttpRequest();
xhr.open("PUT", url);

xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
   if (xhr.readyState === 4) {
      console.log(xhr.status);
      console.log(xhr.responseText);
   }};

var data = `{
  "id": 666,
  "name": "Troy",
  "status": "available"
}`;

xhr.send(data);

 


Python

Code: Select all  Expand view

import requests
from requests.structures import CaseInsensitiveDict

url = "https://petstore.swagger.io/v2/pet"

headers = CaseInsensitiveDict()
headers["accept"] = "application/json"
headers["Content-Type"] = "application/json"

data = """
{
  "
id": 666,
  "
name": "Troy",
  "
status": "available"
}
"
""


resp = requests.put(url, headers=headers, data=data)

print(resp.status_code)


 


JAVA

Code: Select all  Expand view

URL url = new URL("https://petstore.swagger.io/v2/pet");
HttpURLConnection http = (HttpURLConnection)url.openConnection();
http.setRequestMethod("PUT");
http.setDoOutput(true);
http.setRequestProperty("accept", "application/json");
http.setRequestProperty("Content-Type", "application/json");

String data = "{\n  \"id\": 666,\n  \"name\": \"Troy\",\n  \"status\": \"available\"\n}";

byte[] out = data.getBytes(StandardCharsets.UTF_8);

OutputStream stream = http.getOutputStream();
stream.write(out);

System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
http.disconnect();

 


c#/NET

Code: Select all  Expand view

var url = "https://petstore.swagger.io/v2/pet";

var httpRequest = (HttpWebRequest)WebRequest.Create(url);
httpRequest.Method = "PUT";

httpRequest.Headers["accept"] = "application/json";
httpRequest.ContentType = "application/json";

var data = @"{
  "
"id"": 666,
  "
"name"": ""Troy"",
  "
"status"": ""available""
}"
;

using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream()))
{
   streamWriter.Write(data);
}

var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
   var result = streamReader.ReadToEnd();
}

Console.WriteLine(httpResponse.StatusCode);
 


cUrl/BASH

Code: Select all  Expand view

#!/bin/bash

curl -X PUT https://petstore.swagger.io/v2/pet -H "accept: application/json" -H "Content-Type: application/json" --data-binary @- <<DATA
{
  "id": 666,
  "name": "Troy",
  "status": "available"
}
DATA

 

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 5:13 am
by nageswaragunupudi
Please try this:
Code: Select all  Expand view
function TestHttp()

   local oHttp
   local cUrl  := "https://petstore.swagger.io/v2/pet"
   local cData

   cData    := '{ "id" : 666, "name": "Troy", "status" : "available" }'

   oHttp := FWGetOleObject( "WINHTTP.WinHttpRequest.5.1" )

   WITH OBJECT oHttp
      :SetTimeouts(0, 60000, 30000, 120000)
      :Open( "POST", cUrl, .f. )
      :SetRequestHeader( "Accept",        "application/json" )
      :SetRequestHeader( "Content-Type",  "application/json" )
      :Send( cData )
      :WaitForResponse()
      ? :Status, :StatusText // 200 OK
   END

return nil
 

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 7:13 am
by cnavarro
Try with this: ( sorry, I have not been able to prove it )

Code: Select all  Expand view

local aHeaders  := {}
local cError
local cRet
local cData       := := '{ "id" : 666, "name": "Troy", "status" : "available" }'
curl_global_init()

   if ! empty( hCurl := curl_easy_init() )
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, cUrl )
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_BUFF_SETUP )
      curl_easy_setopt( hCurl, HB_CURLOPT_CONNECTTIMEOUT, 30 )
      //for debug only!
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYHOST, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_VERBOSE, .F. )
      AAdd( aHeaders, "accept: application/json" )
      AAdd( aHeaders, "Content-Type: application/json" )
      curl_easy_setopt( hCurl, HB_CURLOPT_HTTPHEADER, aHeaders )
      curl_easy_setopt( hCurl, HB_CURLOPT_POST, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_POSTFIELDS, cData )
      cError  := curl_easy_perform( hCurl )
      if !Empty( cError )
         //MsgInfo( curl_easy_strerror( cError ), "Error" )
         cRet := curl_easy_strerror( cError )
      else
         cRet := curl_easy_dl_buff_get( hCurl )
      endif

   endif

   curl_global_cleanup()

Return cRet
 

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 8:28 pm
by Marc Venken
nageswaragunupudi wrote:Please try this:
Code: Select all  Expand view
function TestHttp()

   local oHttp
   local cUrl  := "https://petstore.swagger.io/v2/pet"
   local cData

   cData    := '{ "id" : 666, "name": "Troy", "status" : "available" }'

   oHttp := FWGetOleObject( "WINHTTP.WinHttpRequest.5.1" )

   WITH OBJECT oHttp
      :SetTimeouts(0, 60000, 30000, 120000)
      :Open( "POST", cUrl, .f. )
      :SetRequestHeader( "Accept",        "application/json" )
      :SetRequestHeader( "Content-Type",  "application/json" )
      :Send( cData )
      :WaitForResponse()
      ? :Status, :StatusText // 200 OK
   END

return nil
 


Yes, This will update the data on the test server.

On my server it also changes the data, but always there is a new record created ?

I put some code I was testing. Data is written, but also every time a new record.

The ID of the product = 2062 and is put in the url.

I have tried also 'PUT' and 'PATCH' have been reading about it, but the I get return code 404 = not found error

Code: Select all  Expand view

function TestMarc()

   local oHttp

   local cUrl  := "https://maveco-webshop.be/api/v2/products/2062?token=47b en rest ...."
   local cData

   /*  This is the Curl that has the data insite needed to send


   curl -X PATCH "http://swagger.shoptrader.com/api/v2/products/1994?token=abc" -H "accept: application/json"
   -H "token: abc" -H "Content-Type: application/json"
   -d "{\"model\":\"string\",\"sku\":\"string\",\"ean\":\"string\",\"name\":\"Test 1994\",
   \"description\":\"string\",\"introDescription\":\"string\",\"extraDescription\":\"string\",
   \"metaTitle\":\"string\",\"metaKeyword\":\"string\",\"metaDescription\":\"string\",\"quantity\":0,
   \"categoryId\":0,\"price\":0,\"purchasePrice\":0,\"status\":true,\"taxRate\":0,\"manufacturerId\":0,
   \"width\":0,\"height\":0,\"weight\":0,\"images\":[\"ImageOne\"],\"imagesAlt\":[\"ImageOneAlt\"],
   \"resources\":[{\"resourceKey\":\"key\",\"resourceValue\":\"value\",\"resourceType\":\"type\"}]}"
   */



   //cData    := '{ "id" : 333, "name": "Noyca", "status" : "available" }'  //  PETSTORE

   cData := '{"model":"510.10.00","sku":"skuData","ean":"123456","name":"Noyca 1994","description":"MemoData"}'

   oHttp := FWGetOleObject( "WINHTTP.WinHttpRequest.5.1" )

   WITH OBJECT oHttp
      :SetTimeouts(0, 60000, 30000, 120000)

      //:Open( "PUT", cUrl )      // By Marc seen on Google
      //:Open( "PATCH", cUrl )      // By Marc seen on Google

      :Open( "POST", cUrl, .f. )  //By Rao

      :SetRequestHeader( "Accept",        "application/json" )
      //:SetRequestHeader( "Token",        "47b en rest ...." )   //  By Marc from Google
      :SetRequestHeader( "Content-Type",  "application/json" )
      :Send( cData )
      :WaitForResponse()
      ? :Status, :StatusText // 200 OK
   END

return nil
 

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 9:15 pm
by Marc Venken
cnavarro wrote:Try with this: ( sorry, I have not been able to prove it )

Code: Select all  Expand view

local aHeaders  := {}
local cError
local cRet
local cData       := := '{ "id" : 666, "name": "Troy", "status" : "available" }'
curl_global_init()

   if ! empty( hCurl := curl_easy_init() )
      curl_easy_setopt( hCurl, HB_CURLOPT_URL, cUrl )
      curl_easy_setopt( hCurl, HB_CURLOPT_DL_BUFF_SETUP )
      curl_easy_setopt( hCurl, HB_CURLOPT_CONNECTTIMEOUT, 30 )
      //for debug only!
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYHOST, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
      curl_easy_setopt( hCurl, HB_CURLOPT_VERBOSE, .F. )
      AAdd( aHeaders, "accept: application/json" )
      AAdd( aHeaders, "Content-Type: application/json" )
      curl_easy_setopt( hCurl, HB_CURLOPT_HTTPHEADER, aHeaders )
      curl_easy_setopt( hCurl, HB_CURLOPT_POST, 1 )
      curl_easy_setopt( hCurl, HB_CURLOPT_POSTFIELDS, cData )
      cError  := curl_easy_perform( hCurl )
      if !Empty( cError )
         //MsgInfo( curl_easy_strerror( cError ), "Error" )
         cRet := curl_easy_strerror( cError )
      else
         cRet := curl_easy_dl_buff_get( hCurl )
      endif

   endif

   curl_global_cleanup()

Return cRet
 


Sorry, But this was not working.

It also needs a extra ch file (found) and i think 2 libs to link.

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 9:25 pm
by nageswaragunupudi
Try
Code: Select all  Expand view
     :Open( "PUT", cUrl, .f. )
 


not
Code: Select all  Expand view
     :Open( "PUT", cUrl )
 


POST is for adding a new pet and PUT is for modifying an existing one.
Error 404 means the id you are trying to modify is not found on the server.

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 9:42 pm
by cnavarro
Marc Venken wrote:
Sorry, But this was not working.

It also needs a extra ch file (found) and i think 2 libs to link.


Yes, sure, if you want to use curl you need the appropriate harbour and compiler libraries
What C compiler do you use in your development?

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 9:50 pm
by Marc Venken
nageswaragunupudi wrote:Try
Code: Select all  Expand view
     :Open( "PUT", cUrl, .f. )
 


not
Code: Select all  Expand view
     :Open( "PUT", cUrl )
 


POST is for adding a new pet and PUT is for modifying an existing one.
Error 404 means the id you are trying to modify is not found on the server.


Using PATCH did work ! (PUT was not changing data) don't know way, because it should i think

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 10:00 pm
by Marc Venken
Where do I put the dbf loop to update the data ?
The object http = already created once.

Maybe it is the intension that the loop will fill the cData var and that we patch it only once ?
The cData will become a large file or mem variable then. Do we ever can have memory problems when we do large updates ?

Code: Select all  Expand view

function TestMarc()

   local oHttp

   local cUrl  := "https://maveco-webshop.be/api/v2/products/2062?token=47b en rest ...."
   local cData

   //cData    := '{ "id" : 333, "name": "Noyca", "status" : "available" }'  //  PETSTORE

   cData := '{"model":"510.10.00","sku":"skuData","ean":"123456","name":"Noyca 1994","description":"MemoData"}'

   oHttp := FWGetOleObject( "WINHTTP.WinHttpRequest.5.1" )

   WITH OBJECT oHttp
      :SetTimeouts(0, 60000, 30000, 120000)
      :Open( "PATCH", cUrl, .f.)    
      :SetRequestHeader( "Accept",        "application/json" )
      :SetRequestHeader( "Content-Type",  "application/json" )
      :Send( cData )
      :WaitForResponse()
      ? :Status, :StatusText // 200 OK
   END

return nil
 

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 10:26 pm
by nageswaragunupudi
The cData will become a large file or mem variable then. Do we ever can have memory problems when we do large updates ?

No problem at all.
cData is getting replaced. It is not growing.

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 10:32 pm
by Marc Venken
nageswaragunupudi wrote:
The cData will become a large file or mem variable then. Do we ever can have memory problems when we do large updates ?

No problem at all.
cData is getting replaced. It is not growing.


Size will be no problem, but cData is in the loop until full processed not ? And then the call to the Function to update by http

Re: Use cUrl to upload data to online server

PostPosted: Sun May 23, 2021 10:37 pm
by Marc Venken
API programming... A whole new world is opening ))))

I spend lot's of time creating functions so I could use the import function of the hosting company. With the API I can go direct. Very Nice.