The provided documentation is somewhat confusing, and the solution I worked out was derived from the nifi api deploy groovy script at https://github.com/aperepel/nifi-api-deploy
Ultimately, to POST a template directly, you can use the following in Python requests
requests.post("%s/nifi-api/controller/templates"%(url,), files={"template":open(filename, 'rb')})
Where filename is the filename of your template and url is the path to your nifi instance. I haven't figured it out in curl directly but this should hopefully get folks with a similar question started!
Edit:
Note that you also can't upload a template with the same name as an existing template. Make sure to delete your existing template before attempting to re-upload. Using the untangle library to parse the XML of the template, the following script works just fine:
import untangle, sys, requests
def deploy_template(filename, url):
p = untangle.parse(filename)
new_template_name=p.template.name.cdata
r=requests.get("%s/nifi-api/controller/templates"%(url,), headers={"Accept":"application/json"})
for each in r.json()["templates"]:
if each["name"]==new_template_name:
requests.delete(each["uri"])
requests.post("%s/nifi-api/controller/templates"%(url,), files={"template":open(filename, 'rb')})
if __name__=="__main__":
deploy_template(sys.argv[1], sys.argv[2])