A Python curl

It happens that I often have to dial into users sites to troubleshoot problems, and they usually run our Python software on Windows. Since I often don’t have access to tools like curl, I’d like to present the next best thing. A command-line interface to urllib2 which uses the same options as curl. This script doesn’t require curl binaries.

It doesn’t do everything curl does, but I’ll update it as soon as I need the feature.

Update: Patch from Michael Watkins

#!env python
'''python curl.py [options] url
Options
  -I/--head  headers only
  -i        include headers
  -h/--help
  -u user:pass
  --user=user:pass
'''

import getopt
import sys

options = getopt.getopt(sys.argv[1:],
    'hu:iI',
    ['help', 'head', 'user='])
include_header = 0
header_only = 0
username, password = None, ''
for option, value in options[0]:
    if option in ('-h', '--help'):
        print __doc__
        sys.exit(0)
    elif option == '-i':
        include_header = 1
    elif option in ('-I', '--head'):
        header_only = 1
    elif option in ('-u', '--user'):
        username, password = value.split(':', 2)

import urllib2 as u
urls = options[-1]
for url in urls:
    req = u.Request(url)

    if username != None:
        import base64
        header = 'Basic %s' % \\
            base64.encodestring(
            '%s:%s' % (username,password))[:-1]
        req.add_header('Authorization', header)

    try:
      f = u.urlopen(req)
      if include_header or header_only: print f.headers
      if not header_only: print f.read()
    except Exception, e:
      print e.read()
else:
    print 'try curl --help'

2 Responses to “A Python curl”

  1. Michael Watkins writes:

    A good idea, I run into the same need as well. Other than dumping out the page, I find I most often use curl with -I (headers only) parameter. Here’s a patch…

    % diff curl_orig.py curl.py
    1,2c1,2
    #!/usr/bin/env python
    > ‘python curl.py [-i] [-I] [-h|--help] [-u user:pass] [--user=user:pass] url’
    8c8
    ‘hu:iI’,
    10a11
    > header_only = 0
    19a21,22
    > elif option == ‘-I’:
    > header_only = 1
    28,29c31
    header = ‘Basic %s’ % base64.encodestring(’%s:%s’ % (username,password))[:-1]
    34,35c36,37
    if include_header or header_only: print f.headers
    > if not header_only: print f.read()

  2. KH writes:

    That code is broken.

Leave a Reply