Skip to main content

Reusable url shortener and lookup library.

Project description

In a nutshell

ao.shorturl is a library for integrating short URLs to a web application. Its front-end configuration is not specific to any web application framework, instead it uses various back-ends for different frameworks.

For example, ao.shorturl.appengine implements a Datastore backand for Google / Typhoon App Engine. If installed as a Django application, ao.shorturl also provides a template tag for easily displaying short URLs for any object that supports them.

Using the short URL library without any framework

Registering and getting handlers

To use the library, you need to register a handler first, using the ao.shorturl.registerHandler() function. To get back the handler, use the getHandler() function:

>>> from ao import shorturl
>>> shorturl.getHandler()
Traceback (most recent call last):
...
ImproperlyConfigured: The requested handler is not initialized.

>>> handler = shorturl.registerHandler()
>>> shorturl.getHandler() is handler
True
>>> handler
<ao.shorturl.BaseShortUrlHandler object at ...>

Note that if you intend to use multiple handlers, you need to give them names, as the default handler is stored as a module global. However, to utilize named handlers, you need to make the zope.component and zope.interface packages available. Each handler is stored in the local site, meaning that if you use multiple sites, you can have different handlers with the same name on a per-site basis. However, the unnamed handler is still a module global, so take thet in consideration when using multiple handlers and sites:

>>> foo = shorturl.registerHandler(name='foo')
>>> shorturl.getHandler(name='foo') is shorturl.getHandler('foo') is foo
True

If you don’t have the zope.component and zope.interface packages available, you won’t be able to use named handlers.

Let’s pretend we don’t have zope.component and zope.interface:

>>> import sys

>>> class _():
...     def __init__(self, modules):
...         self.modules = modules
...
...     def find_module(self, fullname, path=None):
...         if fullname in self.modules:
...             raise ImportError('Debug import failure for %s' % fullname)
...

>>> fail_loader = _(['zope.component', 'zope.interface'])
>>> sys.meta_path.append(fail_loader)

>>> for elem in ('zope.component', 'zope.interface'):
...     del sys.modules[elem]
...

>>> reload(shorturl)
<module 'ao.shorturl' from '...'>

>>> del shorturl.zc  # delete the leftover zope.component module

>>> shorturl.registerHandler(name='bar')
Traceback (most recent call last):
...
ImproperlyConfigured: To use named handlers, you need to make the ...

>>> shorturl.getHandler('bar')
Traceback (most recent call last):
...
ImproperlyConfigured: To use named handlers, you need to make the ...

Remove our import hook:

>>> del sys.meta_path[0]

Configuring the handler

To overwrite any default handler configuration, just pass the apropriate keyword argument to the ao.shorturl.registerHandler() function:

>>> len(shorturl.registerHandler().generate_url())
6

>>> len(shorturl.registerHandler(url_length=10).generate_url())
10

>>> shorturl.registerHandler(url_length=10, url_elems='x').generate_url()
'xxxxxxxxxx'

Using custom handlers

When calling ao.shorturl.registerHandler() without a handler argument, it will not have any real functionality:

>>> shorturl.registerHandler().assign_url(None)
Traceback (most recent call last):
...
NotImplementedError: You must overload `assign_url`.

>>> shorturl.registerHandler().construct_url(None)
Traceback (most recent call last):
...
NotImplementedError: You must overload `construct_url`.

Registering a custom handler is easy, just subclass ao.shorturl.BaseShortUrlHandler:

>>> class FancyShortUrlHandler(shorturl.BaseShortUrlHandler):
...     def assign_url(self, context):
...         context['shorturl'] = self.generate_url()
...     def get_context_from_cache(self, url):
...         if context['shorturl'] == url:
...             return context
...         raise LookupError
...
>>> handler = shorturl.registerHandler(handler=FancyShortUrlHandler, url_length=20)
>>> handler
<FancyShortUrlHandler object at ...>

>>> context = {'foo': 'bar'}
>>> handler.assign_url(context)
>>> len(context['shorturl']) == 20
True

As for now, there’s one custom handler provided for App Engine: ao.shorturl.appengine.AppEngineShortUrlHandler. It uses the datastore API to store the short url associations and the memcache API to cache the keys for better performance.

Getting the context from the handler

In your view (if you’re using an MCV framework), you can call the handler’s get_context() method to query the context for a given short url:

>>> handler.get_context('xxx')
Traceback (most recent call last):
...
ShortUrlNotFound: Short URL could not be found: xxx

>>> handler.get_context(context['shorturl']) is context
True

Note that ao.shorturl.get_context() will be called at least once each time a new short url is created, to check for duplicates:

>>> fired = False
>>> def get_context(name):
...     global fired
...     if not fired:
...         print 'This URL already exists!'
...         fired = True
...         return 'Dummy context'
...     raise LookupError
...

>>> handler.get_context = get_context

>>> handler.generate_url()
This URL already exists!
'...'

Clean up after the tests:

>>> from zope.testing import cleanup
>>> cleanup.cleanUp()

Using with Django and template tags

If you use Django, you can access an object’s short URL from a template with the shorturl template tag. To use it, add ao.shorturl to your INSTALLED_APPS. Then in the template you can do something like this:

{% load shorturl %}
<a href="{% shorturl city %}">{{ city.name }}</a>

Note that this will create an _absolute_ url.

Test the template tag:

>>> from ao.shorturl.templatetags import shorturl

>>> class Parser(object):
...     def split_contents(self):
...         return (None, 'xxx')
...

>>> node = shorturl.shorturl(None, Parser())
>>> node
<ao.shorturl.templatetags.shorturl.URL object at ...>

>>> node.render({'xxx': None})
Traceback (most recent call last):
...
NotImplementedError: You must overload `construct_url`.

Clean up after the tests:

>>> from zope.testing import cleanup
>>> cleanup.cleanUp()

TODO

  • Write unit tests for the App Engine backend

  • Add backends for Django Models and SQLAlchemy/Elixir

Changelog

1.1.6 (2010-03-21)

  • Fixed a few typos

  • More documentation

  • Better test coverage

1.1.4 (2010-03-19)

  • Added some unit tests

  • Updated the documentation

  • Changed the way registering and getting handlers work

1.0.0 (2010-03-19)

  • First public release

  • Added Django template tag

  • Added App Engine backend

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ao.shorturl-1.1.6.tar.gz (7.9 kB view details)

Uploaded Source

Built Distributions

ao.shorturl-1.1.6-py2.7.egg (17.2 kB view details)

Uploaded Source

ao.shorturl-1.1.6-py2.6.egg (17.3 kB view details)

Uploaded Source

ao.shorturl-1.1.6-py2.5.egg (17.3 kB view details)

Uploaded Source

File details

Details for the file ao.shorturl-1.1.6.tar.gz.

File metadata

  • Download URL: ao.shorturl-1.1.6.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for ao.shorturl-1.1.6.tar.gz
Algorithm Hash digest
SHA256 81cdb368bd6c9eac2c958b313d70091f172f18f5be34a0cb89d4bc7b11582817
MD5 b448a5725eee4c058b5699ecaea9f552
BLAKE2b-256 49ce76e543d5d3585006a1b8cb4e3819f2a62b5f71988db72e8a4d268c3ced10

See more details on using hashes here.

File details

Details for the file ao.shorturl-1.1.6-py2.7.egg.

File metadata

File hashes

Hashes for ao.shorturl-1.1.6-py2.7.egg
Algorithm Hash digest
SHA256 33d81482d825c6a814a58bb728d13f7d8191a202bcee141ff78857ebb03e6f83
MD5 0773ce09d469cc26a8e31ed84746f6e6
BLAKE2b-256 721e442aff49344d95c82bca064df185fce04ac07c781e889e207bfd98875665

See more details on using hashes here.

File details

Details for the file ao.shorturl-1.1.6-py2.6.egg.

File metadata

File hashes

Hashes for ao.shorturl-1.1.6-py2.6.egg
Algorithm Hash digest
SHA256 17e9152564bd3cc42422922b3d2e6417412e17487b1cb646d848a873dc784f6b
MD5 79bb3398fe54db6ee3e2e46dd6e64b35
BLAKE2b-256 758b288c9cd5d34f9805bd8efcaede15363a7d5aad8b0456a74d0fcd2b18d076

See more details on using hashes here.

File details

Details for the file ao.shorturl-1.1.6-py2.5.egg.

File metadata

File hashes

Hashes for ao.shorturl-1.1.6-py2.5.egg
Algorithm Hash digest
SHA256 fe9ebb5c1241d4829c96cc196b229f09cadf6be67bf54ca5e2bb962bc48fd1d6
MD5 39c44e587b1092557a6dbaf8a9034a20
BLAKE2b-256 791d97bbfe50247cca9f39aa5799a36521c5516e98c410e0cd8a8739a70362ed

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page