tags:

views:

184

answers:

2

I know about urllib and urlparse, but I want to make sure I wouldn't be reinventing the wheel.

My problem is that I am going to be fetching a bunch of urls from the same domain via the urllib library. I basically want to be able to generate urls to use (as strings) with different paths and query params. I was hoping that something might have a syntax like:

url_builder = UrlBuilder("some.domain.com")
# should give me "http://some.domain.com/blah?foo=bar
url_i_need_to_hit = url_builder.withPath("blah").withParams("foo=bar")  # maybe a ".build()" after this

Basically I want to be able to store defaults that get passed to urlparse.urlunsplit instead of constantly clouding up the code by passing in the whole tuple every time.

Does something like this exist? Do people agree it's worth throwing together?

+2  A: 

Are you proposing an extension to http://docs.python.org/library/urlparse.html#urlparse.urlunparse that would substitute into the 6-item tuple?

Are you talking about something like this?

def myUnparse( someTuple, scheme=None, netloc=None, path=None, etc. ):
    parts = list( someTuple )
    if scheme is not None: parts[0] = scheme
    if netloc is not None: parts[1]= netloc
    if path is not None: parts[2]= path
    etc.
    return urlunparse( parts )

Is that what you're proposing?

This?

class URLBuilder( object ):
    def __init__( self, base ):
        self.parts = list( urlparse(base) )
    def __call__( self, scheme=None, netloc=None, path=None, etc. ):
        if scheme is not None: self.parts[0] = scheme
        if netloc is not None: self.parts[1]= netloc
        if path is not None: self.parts[2]= path
        etc.
        return urlunparse( self.parts )

bldr= URLBuilder( someURL )
print bldr( scheme="ftp" )

Something like that?

S.Lott
mehhh... maybe. But I was thinking of something more along the lines of a class that stored the default the values. I don't want to keep passing in "someTuple". I just want to pass in some default values to some class, then reuse an instance to generate all different urls. Something similar to the Builder pattern that is ubiquitous in Java.
Tom
@Tom: It doesn't seem complex enough to wring your hands over. Indeed, if you put more more than 25 lines of code into it, you've probably done too much.
S.Lott
Oh yeah, the __call___() method is what I was trying to think of. I like it...
ewall
+1  A: 

Still not quite sure what you're looking for... But I'll give it a shot. If you're just looking to make a class that will keep your default values and such, it's simple enough to make your own class and use Python magic like str. Here's a scratched-out example (suboptimal):

class UrlBuilder:
    def __init__(self,domain,path="blah",params="foo=bar"):
        self.domain = domain
        self.path = path
        self.params = params

    def withPath(self,path):
        self.path = path
        return self

    def withParams(self,params):
        self.params = params
        return self

    def __str__(self):
        return 'http://' + self.domain + '/' + self.path + '?' + self.params
        # or return urlparse.urlunparse( ( "http", self.domain, self.path, self.params, "", "" )

    def build(self):
        return self.__str__()

if __name__ == '__main__':
    u = UrlBuilder('www.example.com')
    print u.withPath('bobloblaw')
    print u.withParams('lawyer=yes')
    print u.withPath('elvis').withParams('theking=true')

If you're looking for more of the Builder Design Pattern, the Wikipedia article has a reasonable Python example (as well as Java).

ewall
I prefer to use something like `urlparse.urlunparse` rather than hard-code punctuation.
S.Lott
Accepting this answer pretty late... In the end I really didn't need something like this... but this is what I was looking for. It's obvious there was nothing built in to Python like this, but that was all I was wondering. (I knew I could easily code it myself). My only comment is like S.Lott's... I would have used urlparse in the implementation of the class... thanks ewall.
Tom