1

Im trying to learn how to use APIs in Django and I want to return some simple data from one within a web page in html. The API is Mozscape and when running it in a terminal one can obtain the score of a website out of 100 like so:

from mozscape import Mozscape

client = Mozscape(
    'api_user_id',
    'secret_key')

url = 'http://www.google.com'

get_da = client.urlMetrics(url, cols=68719476736)

print(get_da)

and this prints the following

{u'pda': 100}

the '100' is all I want there. I want a user to enter a url into a form in a page in Django and to get that score int back so I have made the following models, views and form

class DomainAuthority(models.Model):
    url = models.URLField(max_length=300)


    def __str__(self):
        return self.url

    class Meta:
        verbose_name = 'Domain'
        verbose_name_plural = 'Domains'

views.py

def DomainAuthorityView(request):


    form = DomainAuthorityForm(request.POST or None)


    if form.is_valid():
        new_domain = form.save(commit=False)
        new_domain.save()


    return render(request, 'domain_authority.html', {'form': form})

forms.py

class DomainAuthorityForm(forms.ModelForm):
    class Meta:
        model = DomainAuthority 
        fields = ['url']

so I have the form working and when a url is entered in the html form its saved in the admin backend but what I dont know how to do now is how to pass that url into the Mozscape API so that I can get the score back.

I took a look at the Django rest framework and installed it and followed some quick tutorial videos on Youtube and other places but in those examples they were taking saved Django objects such as blog posts and returning them as JSON data which is not what I want to do.

I tried import the API into the views file and then adding this line into then view

get_da = client.urlMetrics(new_domain, cols=68719476736)

but then I get this error after entering the url into the form in the web page

<DomainAuthority: https://www.google.com> is not JSON serializable

what do I need to do here to pass the user inputted urls to the API and return the correct response in a web page?

thanks

EDIT - UPDATED VIEW as of 19th Aug

def DomainAuthorityView(request):


    form = DomainAuthorityForm(request.POST or None)


    if form.is_valid():
        new_domain = form.save(commit=False)
        new_domain.save()


        response = requests.get(new_domain.url, cols=68719476736)
        #response = requests.get(client.urlMetrics(new_domain.url,  cols=68719476736))
        json_response = response.json()

        score = json_response['pda']

        return render(request, 'domain_authority_checked.html', {'score': score})

    else:

    return render(request, 'domain_authority.html', {'form': form})

so now it should redirect after successful form completion with url and the url is passed to the API to get the score and the redirects to 'domain_authority_checked.html' with just this

{{ score }}

so I have two outcomes here, if I pass in 'client.urlMetrics' into response I can load the 'domain_authority.html' but after a url his input into the form an error page returns with this

InvalidSchema at /domainauthority/
No connection adapters were found for '{'pda': 100}'

if I dont pass 'client.urlMetrics' to response then Django doesn't know what 'cols' is and returns this

TypeError at /domainauthority/
request() got an unexpected keyword argument 'cols'
2
  • 1
    The cause of the error is that new_domain a DomainAuthority instance, not a string which is what the urlMetrics() function is expecting. You should call it as urlMetrics(new_domain.url) instead. Now, do you want to store the result of the call in your database, or just use it in a view? Commented Aug 12, 2016 at 14:25
  • thank you, Im going to try the answer below, to answer your question Id like to try both really, so to save the score to the db and also use it in a view Commented Aug 13, 2016 at 1:08

2 Answers 2

3

I suggest this approach:

import requests

response = requests.get(url)
json_response = response.json()

score = json_response['key_name']

You can then simply render a template, add the score to the template context and display the value using {{ }}.

You may also want to define a rest_framework serializer (otherwise you don't need django_rest_framework) and verify the response against this serializer in order to ensure that you've received what you expected:

serializer = MySerializer(data=json_response)
  if serializer.is_valid():
      score = json_response['key_name']
Sign up to request clarification or add additional context in comments.

6 Comments

ok, can you clarify what 'key_name' is supposed to be please as Im not clear, thanks
Usually, API's returns json-parsed data. Eg. {'key_name', 'value'}. You have to examine the return of the api you are querying, using curl for example and set the set the key_name accordingly (indeed api's often returns several fields)
nope, still v.stuck tbh and not really sure what Im doing here, can you see my edited code above? Im not really sure if Im going about this the right way, 'pda' is the key to the score in the API (I think).
I see a dupplicate with the 6th and 7th line of your edited view. Those two do the same thing: querying the api. You should get rid of the line 6th (beginning with get_da) and add the cols parameter to the line below. In addition, you need to add the score variable to the context, same way you did with form, otherwise you can't display it in the template using the templatetag {{ }}
Here's what your render is suppose to look like: return render(request, 'domain_authority.html', {'form': form, 'score': score})
|
1

You can use:

return HttpResponse(json.dumps(data), content_type='application/json')

instead of render the form. Only you need to import json in the header and create an empty dict named "data".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.