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()
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 81cdb368bd6c9eac2c958b313d70091f172f18f5be34a0cb89d4bc7b11582817 |
|
MD5 | b448a5725eee4c058b5699ecaea9f552 |
|
BLAKE2b-256 | 49ce76e543d5d3585006a1b8cb4e3819f2a62b5f71988db72e8a4d268c3ced10 |
File details
Details for the file ao.shorturl-1.1.6-py2.7.egg
.
File metadata
- Download URL: ao.shorturl-1.1.6-py2.7.egg
- Upload date:
- Size: 17.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 33d81482d825c6a814a58bb728d13f7d8191a202bcee141ff78857ebb03e6f83 |
|
MD5 | 0773ce09d469cc26a8e31ed84746f6e6 |
|
BLAKE2b-256 | 721e442aff49344d95c82bca064df185fce04ac07c781e889e207bfd98875665 |
File details
Details for the file ao.shorturl-1.1.6-py2.6.egg
.
File metadata
- Download URL: ao.shorturl-1.1.6-py2.6.egg
- Upload date:
- Size: 17.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 17e9152564bd3cc42422922b3d2e6417412e17487b1cb646d848a873dc784f6b |
|
MD5 | 79bb3398fe54db6ee3e2e46dd6e64b35 |
|
BLAKE2b-256 | 758b288c9cd5d34f9805bd8efcaede15363a7d5aad8b0456a74d0fcd2b18d076 |
File details
Details for the file ao.shorturl-1.1.6-py2.5.egg
.
File metadata
- Download URL: ao.shorturl-1.1.6-py2.5.egg
- Upload date:
- Size: 17.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | fe9ebb5c1241d4829c96cc196b229f09cadf6be67bf54ca5e2bb962bc48fd1d6 |
|
MD5 | 39c44e587b1092557a6dbaf8a9034a20 |
|
BLAKE2b-256 | 791d97bbfe50247cca9f39aa5799a36521c5516e98c410e0cd8a8739a70362ed |