On twitter, everybody is using an url shortener. Though, there can be several problems using an external service, as for example the fact that there's no garantee that your shortened urls will always be available. So, what about creating our own URL shortner, using the Python language?

Technical choices

Acknowledgements

There’s many tools to help you creating an url shortener, for example, ur1 using PHP and urly using Python. In this tutorial, you’ll learn how to create your own url shortener from scratch.

This tutorial uses the Python programming language. Python’s basic concepts aren’t explained here, but this tutorial can be easily followed by anyone having at least some experience in another language as such as PHP or Ruby.
Full source code is available here.

Goals

Let see what we need to achieve :

  • Being able to easily redirect to blog posts
  • Being able to choose a pertinent shortened url name
  • A minimalistic administration interface

1. Redirections

Let’s start by redirections. For now, we just have to add the following URLs :

urls = (
    "/p/(\d+)",         "RedirectToPost",
    "/t/(\d+)",         "RedirectToThought",
)

Then, it’s time to create the redirection classes :

class RedirectToPost:
    def GET(self, post_id):
        return web.redirect(POST_REDIRECT_URL % post_id)

class RedirectToThought:
    def GET(self, thought_id):
        return web.redirect(THOUGHT_REDIRECT_URL % thought_id)

As you can see, many variables are defined on the beginning of the file, to allow you to easily adapt the code to your own needs.

Now, let’s work on redirection to other urls by adding an entry in the urls :

urls = (
    "/(.*)",            "RedirectToOthers",
)

Now we have to take the URLs which have been created via the admin interface (We’ll see that point later) and are stocked in a shelve object, which allow a quick key/value correspondance.

class RedirectToOthers:
    def GET(self, short_name):
        storage = shelve.open(SHELVE_FILENAME)
        # shelve does not allow unicode keys
        short_name = str(short_name)
        if storage.has_key(short_name):
            response = web.redirect(storage[short_name])
        else:
            response = FAIL_MESSAGE
        storage.close()
        return response

Definitely nothing hard here. The code redirects to the corresponding url, or display and error if non is found.

2. Administration

If you always have a shell connected to your server, you can fill your shelve file using Python shell. But creating an admin interface is simple and useful, so let’s do it.

To “protect” the admin interface URL, we’ll just make it harder to find. Just use what you think is the more pertinent, in a variable :

urls = (
    ADMIN,              "Admin",
    ADMIN+"/done/(.*)", "AdminDone",
)

The Admin class allow you to display the form and to submit a new shortcut/url correspondence:

class Admin:
    def GET(self):
        admin_form = web.form.Form(
            web.form.Textbox("url",     description="Long URL"),
            web.form.Textbox("shortcut",description="Shortcut"),
        )
        admin_template = web.template.Template("""$def with(form)
        <!DOCTYPE HTML>
        <html lang="en">
          <head>
            <meta charset=utf-8>

            <title>URL shortener administration</title>
          </head>
          <body onload="document.getElementById('url').focus()">
            <header><h1>Admin</h1></header>

            <form method="POST" action="/admin">
              $:form.render()
              <input type="submit" value="Shorten this long URL">
            </form>
          </body>
        </html>
        """)
        return admin_template(admin_form())

    def POST(self):
        data = web.input()
        shortcut = str(data.shortcut) or random_shortcut()
        storage = shelve.open(SHELVE_FILENAME)
        if storage.has_key(shortcut) or not data.url:
            response = web.badrequest()
        else:
            storage[shortcut] = data.url
            response = web.seeother(ADMIN+'/done/'+shortcut)
        storage.close()
        return response

Webpy forms and templates are directly used in the code because they’re super concise. If the request is GET we create the form and send it to the template, if the request is a POST, we add the url to the base and redirect user to the confirm page.
The code itself don’t verify a lot of things: It just makes sure that it will not erase an existing url and that a url has been submitted.

Then we just have to display the confirm page with our newly created link and a shortcut to directly tweet the link :

class AdminDone:
    def GET(self, short_name):
        admin_done_template = web.template.Template("""$def with(new_url)
        <!DOCTYPE HTML>
        <html lang="en">
          <head>

            <meta charset=utf-8>
            <title>URL shortener administration</title>
          </head>
          <body>
            <header><h1>Done!</h1></header>

            <p>You created: $new_url</p>
            <p><a href="http://twitter.com/home?status=$new_url"
              title="Tweet it!">Tweet it?</a></p>
          </body>
        </html>

        """)
        return admin_done_template(SERVICE_URL+short_name)

That’s all. This code can easily be enhanced, but right now it does what we needed: It create short urls.

3. Going live

I’m using lighty, which have to be adapted according to your server configuration.

Don’t forget to make code.py executable and modify ADMIN!:

$HTTP["host"] =~ "bgk.me" {
        server.document-root = "/path/"

        fastcgi.server = (
            "/code.py" => (
                "main" => (
                    "socket" => "/path/bgkme.socket",
                    "bin-path" => "/path/code.py",
                    "max-procs" => 1,
                    "bin-environment" => (
                        "REAL_SCRIPT_NAME" => ""
                    ),
                    "check-local" => "disable"
                )
            )
        )

        url.rewrite-once = (
            "^(/.*)$" => "/code.py$1",
        )
}

Get the full code

This article is an adapted translation of Son propre TinyURL en Python et HTML5 avec webpy by David Larlet and is available with Creative Commons licence.

Related Posts

No related posts.
 

18 Comments

  1. Posted August 24, 2009 at 10:33 pm | Permalink

    Thanks for sharing this self made solution for url shortener creation. Surely, not everybody wants to rely on remote url services, so having own service should soon enough be very used technique because it gives greater customization options.

  2. Posted August 25, 2009 at 12:38 pm | Permalink

    Great guide, thank you for sharing

  3. Posted August 25, 2009 at 6:48 pm | Permalink

    Thanks for this guide! Finally, I can shorten my url. Absolutely great technique because I can personally do the changes.

  4. Posted August 25, 2009 at 7:44 pm | Permalink

    This is the one I’m looking and I’ve found it..thanks for this it really a great help for me..

  5. Posted August 27, 2009 at 5:16 pm | Permalink

    Nice and sweet

    This is a an excellent guide. I am using my own shortener myself, z2z.ca , links are pretty short at the moment!

    I have also added the functionality to check if a URL is already shortened (this will help against spam a lot), and return the long url in that case.

  6. Posted August 28, 2009 at 3:37 pm | Permalink

    Simple, down to earth and easy to understand tutorial..

    Great job, keep up the good work!

  7. Posted August 29, 2009 at 12:20 pm | Permalink

    Very nice to learn in an easy way. Thanks a lot buddy!

  8. Posted August 30, 2009 at 11:33 am | Permalink

    URL shortener? But isn’t the one you presented much more complicated then just using url shortener tools?

  9. Posted September 3, 2009 at 5:42 pm | Permalink

    What might be cool is to use one of the existing URL shortener APIs with a greasemonkey script that automatically finds URLs you input in certain sites (i.e. Twitter)… then send an ajax call to that API, fetch the new URL, and automatically change it out. Written correctly, it would seem almost instantaneous. Just an idea, who knows if I’ll ever implement it though.

  10. Posted September 7, 2009 at 8:21 am | Permalink

    Is URL shortener safe for your websites? What is it’s advantages and disadvantages?

  11. Posted September 12, 2009 at 5:23 am | Permalink

    Great tips there, Jean. Always wondered on creating url shortner from the scratch, and the tutorial explains all in a simple way. Also thanks a bunch for the source code.

  12. Posted September 19, 2009 at 10:10 pm | Permalink

    Very nice, I am definitely going to use this for now on.

  13. Posted September 24, 2009 at 1:41 am | Permalink

    Why Python and not PHP? Do any shared servers even have Python installed?

  14. Posted October 28, 2009 at 5:09 pm | Permalink

    I have a great easy to use url shortener that pays users for each impression!

  15. Posted December 6, 2009 at 11:56 pm | Permalink

    Mot having much experience programming in Python, this was a very easy to understand walk-through. Thanks alot.

  16. Posted December 7, 2009 at 9:02 am | Permalink

    Thanks for sharing. For those who are looking for quick (and dirty?) solution – there is also a wordpress plugin which bringes url-shortening features to your blog.

  17. Posted December 7, 2009 at 5:58 pm | Permalink

    thanks for the info.. i usually use bitly

  18. Posted December 27, 2009 at 9:37 am | Permalink

    I used it for a long time and it’s very useful. Everyone should use it :)

5 Trackbacks

  1. [...] Creating an url shortener using Python Share and Enjoy: [...]

  2. [...] Creating an url shortener using Python 24Aug2009 Filed under: Programming, Python, Uncategorized Author: Author Hello there! If you are new here, you might want to subscribe to the RSS feed for updates on this topic.Powered by WP Greet BoxThis tutorial uses the Python programming language. Python’s basic concepts aren’t explained here, but this tutorial can be easily followed by anyone having at least some experience in another language as such as PHP or Ruby. … Read more: Creating an url shortener using Python [...]

  3. By Creating A URL Shortener Using Python | Design Newz on August 31, 2009 at 12:31 am

    [...] Creating A URL Shortener Using Python [...]

  4. [...] Creating an URL-Shortener using Python Der Belgier Jean-Baptiste Jung stellt sehr ausführlich vor, wie man einen URL-Kürzer in Python programmiert. Interessante Alternative zur PHP-Front. [...]

  5. [...] ulr kısaltma sistemini yapma http://www.catswhocode.com/blog/creating-an-url-shortener-using-python 0 people like this post. Like  [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting

  • Smashing Network
WordPress Appliance - Powered by TurnKey Linux