Skip to main content

Hi,

I am wanting to upload files to an instance of NextCloud as part of a distribution service for an department; this would consist of uploading a zipped folder/files to nextcloud, before emailing a link with the data (with shared permissions) to the requester.

I am running FME Desktop 2020.0.3.0, I am able to figure out how to download via the HTTPCaller (GET with specific URLs), but uploading (PUT or POST) does not work.

Has anyone figured out how to utilize HTTPCaller with NextCloud fully?

Thanks!

 

https://docs.nextcloud.com/server/20/user_manual/en/files/access_webdav.html

I don't know much about NextCloud, but I do have an article that I once wrote that may be of help. Here it is below. Let us know how it goes...

 

Calling web services with the HTTPCaller is a question that comes up often. Although the question of the week is very specific, it highlights a bigger problem of not knowing which web service components fit into which HTTPCaller parameters.

 

I had this problem myself this week. Even though I don't have all the answers, I'm going to write down some of the things that I've learned, in the hope that someone finds it useful.

 

Q) I’m trying to contact an external API via HTTP POST to get a token back. If I use Postman from the same computer everything is ok. When I try the same in FME, I get errors. Do you have an idea why?

 

A) The ultimate answer here related to encoding. Content in a web form of type

application/x-www-form-urlencoded means the web service expects special characters such as + or = to be encoded as %2B and %3D, because they are also valid characters in other parts of a URL/URI. The correct encoding was created with a TextEncoder transformer.

 

But there was another issue common to users, so let's look at that too. Let's say we want to use a web service. In this case he sent a username and password to a web service to get a token back. In my case I sent a monochrome image to an AI web service to get a colourized version back. Both are typical web services. The documentation said that I should use a command like:

QOTW-HTTPCaller-03Usually to connect with a web service in FME you use a HTTPCaller transformer. So I put a HTTPCaller down and...

QOTW-HTTPCaller-01Wow! That's a lot of parameters! How do I know what to put and where? How does the command provided in the web service doc map to the FME parameters?

 

As an aside, the first thing I did was turn on Log Debug in FME Options.

In FME training I tell users NOT to turn this on unless they really mean it, because it returns alarming-looking messages that aren't really an issue. Guess what? Here I really mean it. Log Debug is great for logging extra information about HTTP connections and transmissions.

 

For example, with Log Debug a simple GET on safe.com returns this:

User-Agent: FME/2019.7.38.19822  libcurl/7.65.2

It tells me we use cURL, which is interesting because that's the format in which my web service provided examples. So we're in business here. 

 

But first, the user said he had the command working properly in Postman. What is Postman?

Well, Postman is an API client; the same sort of thing as the HTTPCaller transformer, only it's a little more sophisticated.

 

If you've taken our FME Server API training, you'll have encountered Postman because it's a great way to test a web service API. If you can get a web service working in Postman, then you know it should be OK in FME.

 

So Postman is a great tool, and I suggest you download and install it for occasions like this.

Anyway, the setup in Postman looked like this, with a header:

QOTW-HTTPCaller-04...and a body:

QOTW-HTTPCaller-05So it uses the same sort of information, just in a different structure. The user kindly clicked the Code button and choose the cURL option, and this is what the tool returned:

 

curl
 -X POST \  https://dummy_url \  -H 'cache-control: no-cache' \  -H 
 'content-type: application/x-www-form-urlencoded' \  -H 'postman-token: 
 f47655fc-deea-097d-6c30-a53950dc2506' \  -d 
 'grant_type=password&client_id=Portal&username=dummy_username&password=dummy_password'
 

I then took the cURL sample provided by the colourization service and imported it into Postman. It looked like this:

QOTW-HTTPCaller-06and...

QOTW-HTTPCaller-07It ran successfully so I knew it should be OK in FME. So let's look at how I mapped my cURL command. Well, obviously you need to specify the site to connect to, and that is either in the cURL or already known.

 

I'm using the POST method because that's what you generally use for sending data or files. It may also show up in your cURL command. What next caught my eye were the different cURL flags. I had -H and -F, and the user has -H, and -d. The Postman knowledgebase has documentation on these flags.

 

  • H (--header): A header
  • F (--form): A form field
  • d (--data): A data field of type application/x-www-form-urlencoded
  •  

So the user sends data (d), and I send a form (F). In fact, if you look at our respective setups you can see Postman indicates a difference:

QOTW-HTTPCaller-08"form-data", confusingly, is the equivalent to my -F flag.

So, what does that mean for FME and the HTTPCaller? Well, H is a header and we have a section for headers. So that's where I put my api-key header:

QOTW-HTTPCaller-09Because, if you remember, my command was:

 -H 'api-key:quickstart-QUdJIGlzIGNvbWluZy4uLi4K' \

I use a published parameter instead of hard-coding the key, but the effect is the same. The next part is the body. There are various types of body allowed and you specify them with a parameter. Since my body is a form-data type, I selected Multipart/Form Data. In the options I specify the file to upload:

QOTW-HTTPCaller-11Why is the name "image"? Because from the very start I knew the command was:

 -F 'image=@/path/to/your/file.jpg' \

So, I knew the name of the key to use was image. If there were multiple -F flags then I would add each as a separate line. The users x-www-form-urlencoded data isn't-F, but -d, meaning data. So instead of using the Multipart/Form Data option, he would use Specify Upload Body:

QOTW-HTTPCaller-12Notice that all of the bits of the body under the -d flag:

-d 'grant_type=password&client_id=Portal&username=dummy_username&password=dummy_password'

...are concatenated together into a string either here or in a prior transformer. In this case it was in a prior transformer, followed by the TextEncoder. And you can see now why that string needed to be encoded into "Percent Encoding", because if the password included the "=" character (for example) it would cause a clash with the same character in "password=xxxx".

 

Are there other scenarios? Well, yes. For one thing, there are Query String Parameters in the HTTPCaller. How does that work? There is an example on the postman-echo site (which lets you test various scenarios). The URL is this:

https://postman-echo.com/get?foo1=bar1&foo2=bar2 

If I paste that into Postman and export it as cURL, it looks like this:

curl --location --request GET 'https://postman-echo.com/get?foo1=bar1&foo2=bar2'

From that I assume if the parameters for your query are part of the URL, defined after the ? character, then they should be part of the Query String Parameters in the HTTPCaller, like so. The other part not yet covered is when you would use the Upload From File option. I'm told that's the same as the -d (or --data) flag, but using a file instead of an attribute. So you could put content into a file and point this parameter to that file, setting content type to Text (text/plain).

 


I don't know much about NextCloud, but I do have an article that I once wrote that may be of help. Here it is below. Let us know how it goes...

 

Calling web services with the HTTPCaller is a question that comes up often. Although the question of the week is very specific, it highlights a bigger problem of not knowing which web service components fit into which HTTPCaller parameters.

 

I had this problem myself this week. Even though I don't have all the answers, I'm going to write down some of the things that I've learned, in the hope that someone finds it useful.

 

Q) I’m trying to contact an external API via HTTP POST to get a token back. If I use Postman from the same computer everything is ok. When I try the same in FME, I get errors. Do you have an idea why?

 

A) The ultimate answer here related to encoding. Content in a web form of type

application/x-www-form-urlencoded means the web service expects special characters such as + or = to be encoded as %2B and %3D, because they are also valid characters in other parts of a URL/URI. The correct encoding was created with a TextEncoder transformer.

 

But there was another issue common to users, so let's look at that too. Let's say we want to use a web service. In this case he sent a username and password to a web service to get a token back. In my case I sent a monochrome image to an AI web service to get a colourized version back. Both are typical web services. The documentation said that I should use a command like:

QOTW-HTTPCaller-03Usually to connect with a web service in FME you use a HTTPCaller transformer. So I put a HTTPCaller down and...

QOTW-HTTPCaller-01Wow! That's a lot of parameters! How do I know what to put and where? How does the command provided in the web service doc map to the FME parameters?

 

As an aside, the first thing I did was turn on Log Debug in FME Options.

In FME training I tell users NOT to turn this on unless they really mean it, because it returns alarming-looking messages that aren't really an issue. Guess what? Here I really mean it. Log Debug is great for logging extra information about HTTP connections and transmissions.

 

For example, with Log Debug a simple GET on safe.com returns this:

User-Agent: FME/2019.7.38.19822  libcurl/7.65.2

It tells me we use cURL, which is interesting because that's the format in which my web service provided examples. So we're in business here. 

 

But first, the user said he had the command working properly in Postman. What is Postman?

Well, Postman is an API client; the same sort of thing as the HTTPCaller transformer, only it's a little more sophisticated.

 

If you've taken our FME Server API training, you'll have encountered Postman because it's a great way to test a web service API. If you can get a web service working in Postman, then you know it should be OK in FME.

 

So Postman is a great tool, and I suggest you download and install it for occasions like this.

Anyway, the setup in Postman looked like this, with a header:

QOTW-HTTPCaller-04...and a body:

QOTW-HTTPCaller-05So it uses the same sort of information, just in a different structure. The user kindly clicked the Code button and choose the cURL option, and this is what the tool returned:

 

curl
 -X POST \  https://dummy_url \  -H 'cache-control: no-cache' \  -H 
 'content-type: application/x-www-form-urlencoded' \  -H 'postman-token: 
 f47655fc-deea-097d-6c30-a53950dc2506' \  -d 
 'grant_type=password&client_id=Portal&username=dummy_username&password=dummy_password'
 

I then took the cURL sample provided by the colourization service and imported it into Postman. It looked like this:

QOTW-HTTPCaller-06and...

QOTW-HTTPCaller-07It ran successfully so I knew it should be OK in FME. So let's look at how I mapped my cURL command. Well, obviously you need to specify the site to connect to, and that is either in the cURL or already known.

 

I'm using the POST method because that's what you generally use for sending data or files. It may also show up in your cURL command. What next caught my eye were the different cURL flags. I had -H and -F, and the user has -H, and -d. The Postman knowledgebase has documentation on these flags.

 

  • H (--header): A header
  • F (--form): A form field
  • d (--data): A data field of type application/x-www-form-urlencoded
  •  

So the user sends data (d), and I send a form (F). In fact, if you look at our respective setups you can see Postman indicates a difference:

QOTW-HTTPCaller-08"form-data", confusingly, is the equivalent to my -F flag.

So, what does that mean for FME and the HTTPCaller? Well, H is a header and we have a section for headers. So that's where I put my api-key header:

QOTW-HTTPCaller-09Because, if you remember, my command was:

 -H 'api-key:quickstart-QUdJIGlzIGNvbWluZy4uLi4K' \

I use a published parameter instead of hard-coding the key, but the effect is the same. The next part is the body. There are various types of body allowed and you specify them with a parameter. Since my body is a form-data type, I selected Multipart/Form Data. In the options I specify the file to upload:

QOTW-HTTPCaller-11Why is the name "image"? Because from the very start I knew the command was:

 -F 'image=@/path/to/your/file.jpg' \

So, I knew the name of the key to use was image. If there were multiple -F flags then I would add each as a separate line. The users x-www-form-urlencoded data isn't-F, but -d, meaning data. So instead of using the Multipart/Form Data option, he would use Specify Upload Body:

QOTW-HTTPCaller-12Notice that all of the bits of the body under the -d flag:

-d 'grant_type=password&client_id=Portal&username=dummy_username&password=dummy_password'

...are concatenated together into a string either here or in a prior transformer. In this case it was in a prior transformer, followed by the TextEncoder. And you can see now why that string needed to be encoded into "Percent Encoding", because if the password included the "=" character (for example) it would cause a clash with the same character in "password=xxxx".

 

Are there other scenarios? Well, yes. For one thing, there are Query String Parameters in the HTTPCaller. How does that work? There is an example on the postman-echo site (which lets you test various scenarios). The URL is this:

https://postman-echo.com/get?foo1=bar1&foo2=bar2 

If I paste that into Postman and export it as cURL, it looks like this:

curl --location --request GET 'https://postman-echo.com/get?foo1=bar1&foo2=bar2'

From that I assume if the parameters for your query are part of the URL, defined after the ? character, then they should be part of the Query String Parameters in the HTTPCaller, like so. The other part not yet covered is when you would use the Upload From File option. I'm told that's the same as the -d (or --data) flag, but using a file instead of an attribute. So you could put content into a file and point this parameter to that file, setting content type to Text (text/plain).

 

Thank you @mark2atsafe​ for the detailed post. I have managed to upload/name the test file with authentication. My next issue is setting permissions (Share, expiry), which I believe I would use the "Headers" when using the "PUT" HTTP Method. Using the chrome development tools to Inspect the Elements of the page has not helped to figure out what "values" and "names" I need for initial settings/expiry of the data.


I am building a custom transformer that is based on the WebDav protocol and use it to perform actions against NextCloud. Problem is that WebDav (and Nextcloud) use methods that can't be triggered by the HTTPCaller. My only work around for those is Python. I dislike to use build-in usernames and passwords. For these actions like Create directory, List folder, Move and Copy you would need to provide an additional username and password. I will publish it on the 24th of August 2021.

WebDav


I am building a custom transformer that is based on the WebDav protocol and use it to perform actions against NextCloud. Problem is that WebDav (and Nextcloud) use methods that can't be triggered by the HTTPCaller. My only work around for those is Python. I dislike to use build-in usernames and passwords. For these actions like Create directory, List folder, Move and Copy you would need to provide an additional username and password. I will publish it on the 24th of August 2021.

WebDav

I look forward to seeing your solution!


I am building a custom transformer that is based on the WebDav protocol and use it to perform actions against NextCloud. Problem is that WebDav (and Nextcloud) use methods that can't be triggered by the HTTPCaller. My only work around for those is Python. I dislike to use build-in usernames and passwords. For these actions like Create directory, List folder, Move and Copy you would need to provide an additional username and password. I will publish it on the 24th of August 2021.

WebDav

Hi janb

 

I finally trying out to the FME Server, and keen to try connecting to NextCloud. Do you have an update on the custom Transformer? Otherwise I will have a crack at calling the Webservices myself.

 

Cheers

Fred


I am building a custom transformer that is based on the WebDav protocol and use it to perform actions against NextCloud. Problem is that WebDav (and Nextcloud) use methods that can't be triggered by the HTTPCaller. My only work around for those is Python. I dislike to use build-in usernames and passwords. For these actions like Create directory, List folder, Move and Copy you would need to provide an additional username and password. I will publish it on the 24th of August 2021.

WebDav

Hi @janb​ , any update?

Thanks!


Hi @janb​ , any update?

Thanks!

Yes! I finally made it work and put the WebDAVFileConnector on the FME Hub. If you use FME 2022.1 you should be able to simply search it in the canvas and download it. I had to wait for the HTTPCaller to get more HTTP Methods. Now that is the case I can make a very easy custom transformer that does most of the WebDav methods. I tested this on a NextCloud instance so hope it also works on any other WebDAV service. Hope it works!


Hi @janb​ , any update?

Thanks!

Hi Janb. This is fantastic news!!!

I will definitely try it out soon. Thank you so much for the effort!​


Hi @janb​ , any update?

Thanks!

Hi @janb​ , thank you for the solution.

I am stuck on an older version of FME (2021.0.1.0) for at least another year, with an earlier version of the HTTPCALLER, would you be able to post a screenshot of one of the httpcallers to show the setup? Opening your transformer in an earlier version loses all the httpcallers.

Thanks!


Hi @janb​ , any update?

Thanks!

Indeed. The latest http caller has the necessary changes. We made our own httpcaller for the previous version.

I can send that too you….

Jan Bliki
Mobile:+45 40408186
(This is an out of office reply)

Reply