Face.com w/ NetworkTools?

mattgolsen's picture

Hey all, has anyone experimented with Face.com for facial recognition with QC? I've been attempting to get NetworkTools to post image data to the Face.com API, with not much luck. I'm pretty sure I'm doing something wrong though.

Can anyone take a look at this comp? I've included my API key & API secret for ease of development, but after a couple of days I'm going to revoke it and generate a new one.


Face.com_MGO.qtz61.65 KB
ss.png27.59 KB

mattgolsen's picture
Re: Face.com w/ NetworkTools?

So I think I know what the problem is here:

w3.org wrote:
The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.

Kineme NetworkTools does not use Query Parameters if the Content-Type is changed from "application/x-www-form-urlencoded", but to POST data properly to this API I should be using "multipart/form-data", correct?

jstrecker's picture
Re: Face.com w/ NetworkTools?

From the API documentation it looks like there are 2 ways to send the request -- either put an image URL in the query parameters, or use multipart/form-data and put actual image data in the POST request.

You should be able to construct the POST request with a String Printer, filling in the API key, API secret, and image byte string. The one missing piece is how to convert an image to a byte string. I started whipping together a new patch to do that. But before I finished...

... I noticed that even with a valid-looking multipart/form-data string, the response has the error "MISSING_ARGUMENTS - api_key is missing". So I tried it outside of Quartz Composer. I put some POST data into a text file and did curl -d @post.txt http://api.face.com/faces/detect.json. Same error.

So, if you can figure out what a valid POST request looks like, and get that working with curl, we can help you get that working with NetworkTools.

mattgolsen's picture
Re: Face.com w/ NetworkTools?

Thinks for looking into this for me. So here's the proper syntax for curl:

curl -F media=@YOURIMAGE "http://api.face.com/faces/detect.xml?api_key=YOURAPIKEY&api_secret=YOURAPISECRET"

The -F flag does the following:

(HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data accord-
              ing to RFC 2388. This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an @ sign. To just get the content part  from
              a file, prefix the file name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file upload, while the < makes a text
              field and just get the contents for that text field from a file.
              Example, to send your password file to the server, where 'password' is the name of the form-field to which /etc/passwd will be the input:
              curl -F password=@/etc/passwd www.mypasswords.com
              To read content from stdin instead of a file, use - as the filename. This goes for both @ and < constructs.
              You can also tell curl what Content-Type to use by using 'type=', in a manner similar to:
              curl -F "web=@index.html;type=text/html" url.com
              curl -F "name=daniel;type=text/foo" url.com
              You can also explicitly change the name field of a file upload part by setting filename=, like this:
              curl -F "file=@localfile;filename=nameinpost" url.com
              See further examples and details in the MANUAL.
              This option can be used multiple times.

Amazing what happens when you read the MAN page :/ The "@" is definitely important as well in this case for curl.

jstrecker's picture
Re: Face.com w/ NetworkTools?

Great. This also works:

curl trace.txt -F api_key=8e7bfe8565ae1ae9a8f7ca279d8d5cf2 -F api_secret=d568480ede4ec34a49d802134b1d8b82 -F media=@face.png "http://api.face.com/faces/detect.xml"

So you can pass the API key and secret, not just the image, inside the POST.

And if you add the flag --trace or --trace-ascii, you can see the text of the POST request.

Thank you. That gives me enough to go on. This week I'll add some patches to DataTools to make the NetworkTools POSTing actually useful.

jstrecker's picture
Re: Face.com w/ NetworkTools?

@mattgolsen, I made some progress and will hand it back over to you.

You'll need the new beta version of NetworkTools and the latest version of DataTools from GitHub.

The attached composition does not quite work. It seems to be sending the API key and API secret correctly via POST, but not the image. The error from Face.com is "INVALID_ARGUMENTS_VALUE - Upload error - The uploaded file was only partially uploaded".

I've compared the output of curl --

curl --trace -F api_key=YOUR_API_KEY -F api_secret=YOUR_API_SECRET media=@face.png "http://api.face.com/faces/detect.xml"

-- with the output of tcpdump while running the composition. I've looked at it for a while and I'm not seeing any meaningful differences between the two.

If you can figure out why it's not working, and it's a problem with NetworkTools or DataTools, then let me know what I can do to help.

(One thing you might try would be to POST to a web service other than Face.com, to see if the problem is specific to their site.)

NetworkTools-multipart_form-data.qtz157.2 KB

mattgolsen's picture
Re: Face.com w/ NetworkTools?

So I captured a session using tcpdump and compared POSTing via curl, and then through NetworkTools. After reviewing it with WireShark I'm seeing a Header Checksum problem with the submission from NetworkTools.

Header checksum: 0x0000 [incorrect, should be 0xc4da (maybe caused by "IP checksum offload"?)]

I did have a little strangeness with our firewall when I posted with:

curl --trace -F api_key=YOUR_API_KEY -F api_secret=YOUR_API_SECRET media=@face.png "http://api.face.com/faces/detect.xml"

It returned a 404 as well as the resulting XML from face.com, but I think that's just something on our end TBH.

But using the original solution seemed to work out ok.

curl -F media=@703981.jpg "http://api.face.com/faces/detect.xml?api_key=8e7bfe8565ae1ae9a8f7ca279d8d5cf2&api_secret=d568480ede4ec34a49d802134b1d8b82"

Does this give you any ideas?

jstrecker's picture
Re: Face.com w/ NetworkTools?

Are you sure the header checksum error isn't some problem with how you're capturing packets?