I need to pull some data from the API. It returns the GET in XML and I have having some issues trying to figure out how to assign some of the data from the API to fields in my model in django/python.
The API for activeCollab does not allow me to create my own projectID number, it automatically generates the number for me. So I would like to take that number, then assign it to my API_id field in my project model. Could someone help me figure out how to take the XML that the GET returns and assign it to one of my fields.
ActiveCollab API Documentation for projects: http://www.activecollab.com/docs/manuals/developers/api/projects
Here is my models.py
class Project(models.Model):
client = models.ForeignKey(Clients, related_name='projects')
created_by = models.ForeignKey(User, related_name='created_by')
#general information
API_id = models.IntegerField(max_length=10, verbose_name='aC ProjectID', null=True, blank=True)
proj_name = models.CharField(max_length=255, verbose_name='Project Name')
pre_quote = models.CharField(max_length=3)
quote = models.IntegerField(max_length=10, verbose_name='Quote #', unique=True)
estimator = models.ForeignKey(User, related_name='Estimator', null=True)
desc = models.TextField(verbose_name='Description', null=True, blank=True)
starts_on = models.DateField(verbose_name='Start Date')
due_date = models.DateField(verbose_name='Due Date', null=True, blank=True)
completed_on = models.DateField(verbose_name='Finished On', null=True, blank=True)
notes = models.TextField(verbose_name='Notes', null=True, blank=True)
Views.py
def addProject(request):
if request.method == 'POST':
form = AddSingleProjectForm(request.POST)
if form.is_valid():
project = form.save(commit=False)
project.created_by = request.user
today = datetime.date.today()
project.pre_quote = "%s-" % (str(today.year)[2:4])
project.quote = Project.objects.latest().quote+1
project.save()
project.status.create(
value = form.cleaned_data.get('status', None)
)
#API activeCollab
params = urllib.urlencode({
'format':'xml',
'submitted':'submitted',
'project[name]': project.proj_name,
'project[overview]': project.desc,
'project[starts_on]': project.starts_on,
'project[leader_id]': 10,
})
req = urllib2.Request("web_url/public/api.php?path_info=/projects/add&token=####################", params)
f = urllib2.urlopen(req)
print f.read()
return HttpResponseRedirect('/project/')
else:
form = AddSingleProjectForm()
return render_to_response('project/addProject.html', {
'form': form, 'user':request.user}, context_instance=RequestContext(request))
Any suggestions will be appreciated.
Steve
Ps. The api call that I have shown is to create a new project
Having looked at the link you posted... something like this might get you started, using lxml
and xpath
:
>>> from lxml import etree
>>> doc = etree.XML("""<projects>
... <project>
... <id>1</id>
... <name>
... <![CDATA[First Project]]>
... </name>
... <overview>
... <![CDATA[<p>This is overview of the first project</p>]]>
... </overview>
... <status>
... <![CDATA[active]]>
... </status>
... <type>...</type>
... <permalink>...</permalink>
... <leader_id>...</leader_id>
... <company_id>...</company_id>
... <group_id>...</group_id>
... </project>
... </projects>""")
>>> data = {}
>>> for a in doc.xpath('/projects/project/*'):
... data[a.tag] = str(a.text).strip()
...
>>> data
{'company_id': '...',
'group_id': '...',
'id': '1',
'leader_id': '...',
'name': 'First Project',
'overview': '<p>This is overview of the first project</p>',
'permalink': '...',
'status': 'active',
'type': '...'}
Update
Slightly more explicit help:
Assuming you have an from lxml import etree
in your file. here's a snippet for your addProject
function:
req = urllib2.Request("web_url/public/api.php?path_info=/projects/add&token=####################", params)
resp = urllib2.urlopen(req)
resp_data = f.read()
if not resp.code == 200 and resp.headers.get('content-type') == 'text/xml':
# Do your error handling.
raise Exception('Unexpected response',req,resp)
data = etree.XML(resp_data)
api_id = int(data.xpath('/project/id/text()')[0])
project.API_id = api_id
project.save()