Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions
distutils.command.register.register Class Reference
Inheritance diagram for distutils.command.register.register:
Inheritance graph
[legend]
Collaboration diagram for distutils.command.register.register:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def initialize_options
def finalize_options
def run
def check_metadata
def classifiers
def verify_metadata
def send_metadata
def build_post_data
def post_to_server

Public Attributes

 list_classifiers
 strict
 username
 password
 repository
 realm
 has_config

Static Public Attributes

tuple description = ("register the distribution with the Python package index")
list user_options
list boolean_options
list sub_commands = [('check', lambda self: True)]

Private Member Functions

def _set_config

Detailed Description

Definition at line 17 of file register.py.


Member Function Documentation

Reads the configuration file and set attributes.

Definition at line 68 of file register.py.

00068 
00069     def _set_config(self):
00070         ''' Reads the configuration file and set attributes.
00071         '''
00072         config = self._read_pypirc()
00073         if config != {}:
00074             self.username = config['username']
00075             self.password = config['password']
00076             self.repository = config['repository']
00077             self.realm = config['realm']
00078             self.has_config = True
00079         else:
00080             if self.repository not in ('pypi', self.DEFAULT_REPOSITORY):
00081                 raise ValueError('%s not found in .pypirc' % self.repository)
00082             if self.repository == 'pypi':
00083                 self.repository = self.DEFAULT_REPOSITORY
00084             self.has_config = False

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 221 of file register.py.

00221 
00222     def build_post_data(self, action):
00223         # figure the data to send - the metadata plus some additional
00224         # information used by the package server
00225         meta = self.distribution.metadata
00226         data = {
00227             ':action': action,
00228             'metadata_version' : '1.0',
00229             'name': meta.get_name(),
00230             'version': meta.get_version(),
00231             'summary': meta.get_description(),
00232             'home_page': meta.get_url(),
00233             'author': meta.get_contact(),
00234             'author_email': meta.get_contact_email(),
00235             'license': meta.get_licence(),
00236             'description': meta.get_long_description(),
00237             'keywords': meta.get_keywords(),
00238             'platform': meta.get_platforms(),
00239             'classifiers': meta.get_classifiers(),
00240             'download_url': meta.get_download_url(),
00241             # PEP 314
00242             'provides': meta.get_provides(),
00243             'requires': meta.get_requires(),
00244             'obsoletes': meta.get_obsoletes(),
00245         }
00246         if data['provides'] or data['requires'] or data['obsoletes']:
00247             data['metadata_version'] = '1.1'
00248         return data

Here is the caller graph for this function:

Deprecated API.

Definition at line 58 of file register.py.

00058 
00059     def check_metadata(self):
00060         """Deprecated API."""
00061         warn("distutils.command.register.check_metadata is deprecated, \
00062               use the check command instead", PendingDeprecationWarning)
00063         check = self.distribution.get_command_obj('check')
00064         check.ensure_finalized()
00065         check.strict = self.strict
00066         check.restructuredtext = 1
00067         check.run()

Fetch the list of classifiers from the server.

Definition at line 85 of file register.py.

00085 
00086     def classifiers(self):
00087         ''' Fetch the list of classifiers from the server.
00088         '''
00089         url = self.repository+'?:action=list_classifiers'
00090         response = urllib.request.urlopen(url)
00091         log.info(response.read())

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 36 of file register.py.

00036 
00037     def finalize_options(self):
00038         PyPIRCCommand.finalize_options(self)
00039         # setting options for the `check` subcommand
00040         check_options = {'strict': ('register', self.strict),
00041                          'restructuredtext': ('register', 1)}
00042         self.distribution.command_options['check'] = check_options

Here is the caller graph for this function:

Definition at line 31 of file register.py.

00031 
00032     def initialize_options(self):
00033         PyPIRCCommand.initialize_options(self)
00034         self.list_classifiers = 0
00035         self.strict = 0

def distutils.command.register.register.post_to_server (   self,
  data,
  auth = None 
)
Post a query to the server, and return a string response.

Definition at line 249 of file register.py.

00249 
00250     def post_to_server(self, data, auth=None):
00251         ''' Post a query to the server, and return a string response.
00252         '''
00253         if 'name' in data:
00254             self.announce('Registering %s to %s' % (data['name'],
00255                                                     self.repository),
00256                                                     log.INFO)
00257         # Build up the MIME payload for the urllib2 POST data
00258         boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
00259         sep_boundary = '\n--' + boundary
00260         end_boundary = sep_boundary + '--'
00261         body = io.StringIO()
00262         for key, value in data.items():
00263             # handle multiple entries for the same name
00264             if type(value) not in (type([]), type( () )):
00265                 value = [value]
00266             for value in value:
00267                 value = str(value)
00268                 body.write(sep_boundary)
00269                 body.write('\nContent-Disposition: form-data; name="%s"'%key)
00270                 body.write("\n\n")
00271                 body.write(value)
00272                 if value and value[-1] == '\r':
00273                     body.write('\n')  # write an extra newline (lurve Macs)
00274         body.write(end_boundary)
00275         body.write("\n")
00276         body = body.getvalue().encode("utf-8")
00277 
00278         # build the Request
00279         headers = {
00280             'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary,
00281             'Content-length': str(len(body))
00282         }
00283         req = urllib.request.Request(self.repository, body, headers)
00284 
00285         # handle HTTP and include the Basic Auth handler
00286         opener = urllib.request.build_opener(
00287             urllib.request.HTTPBasicAuthHandler(password_mgr=auth)
00288         )
00289         data = ''
00290         try:
00291             result = opener.open(req)
00292         except urllib.error.HTTPError as e:
00293             if self.show_response:
00294                 data = e.fp.read()
00295             result = e.code, e.msg
00296         except urllib.error.URLError as e:
00297             result = 500, str(e)
00298         else:
00299             if self.show_response:
00300                 data = result.read()
00301             result = 200, 'OK'
00302         if self.show_response:
00303             dashes = '-' * 75
00304             self.announce('%s%s%s' % (dashes, data, dashes))
00305         return result

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 43 of file register.py.

00043 
00044     def run(self):
00045         self.finalize_options()
00046         self._set_config()
00047 
00048         # Run sub commands
00049         for cmd_name in self.get_sub_commands():
00050             self.run_command(cmd_name)
00051 
00052         if self.dry_run:
00053             self.verify_metadata()
00054         elif self.list_classifiers:
00055             self.classifiers()
00056         else:
00057             self.send_metadata()

Here is the call graph for this function:

Here is the caller graph for this function:

Send the metadata to the package index server.

    Well, do the following:
    1. figure who the user is, and then
    2. send the data as a Basic auth'ed POST.

    First we try to read the username/password from $HOME/.pypirc,
    which is a ConfigParser-formatted file with a section
    [distutils] containing username and password entries (both
    in clear text). Eg:

[distutils]
index-servers =
    pypi

[pypi]
username: fred
password: sekrit

    Otherwise, to figure who the user is, we offer the user three
    choices:

     1. use existing login,
     2. register as a new user, or
     3. set the password to a random string and email the user.

Definition at line 99 of file register.py.

00099 
00100     def send_metadata(self):
00101         ''' Send the metadata to the package index server.
00102 
00103             Well, do the following:
00104             1. figure who the user is, and then
00105             2. send the data as a Basic auth'ed POST.
00106 
00107             First we try to read the username/password from $HOME/.pypirc,
00108             which is a ConfigParser-formatted file with a section
00109             [distutils] containing username and password entries (both
00110             in clear text). Eg:
00111 
00112                 [distutils]
00113                 index-servers =
00114                     pypi
00115 
00116                 [pypi]
00117                 username: fred
00118                 password: sekrit
00119 
00120             Otherwise, to figure who the user is, we offer the user three
00121             choices:
00122 
00123              1. use existing login,
00124              2. register as a new user, or
00125              3. set the password to a random string and email the user.
00126 
00127         '''
00128         # see if we can short-cut and get the username/password from the
00129         # config
00130         if self.has_config:
00131             choice = '1'
00132             username = self.username
00133             password = self.password
00134         else:
00135             choice = 'x'
00136             username = password = ''
00137 
00138         # get the user's login info
00139         choices = '1 2 3 4'.split()
00140         while choice not in choices:
00141             self.announce('''\
00142 We need to know who you are, so please choose either:
00143  1. use your existing login,
00144  2. register as a new user,
00145  3. have the server generate a new password for you (and email it to you), or
00146  4. quit
00147 Your selection [default 1]: ''', log.INFO)
00148             choice = input()
00149             if not choice:
00150                 choice = '1'
00151             elif choice not in choices:
00152                 print('Please choose one of the four options!')
00153 
00154         if choice == '1':
00155             # get the username and password
00156             while not username:
00157                 username = input('Username: ')
00158             while not password:
00159                 password = getpass.getpass('Password: ')
00160 
00161             # set up the authentication
00162             auth = urllib.request.HTTPPasswordMgr()
00163             host = urllib.parse.urlparse(self.repository)[1]
00164             auth.add_password(self.realm, host, username, password)
00165             # send the info to the server and report the result
00166             code, result = self.post_to_server(self.build_post_data('submit'),
00167                 auth)
00168             self.announce('Server response (%s): %s' % (code, result),
00169                           log.INFO)
00170 
00171             # possibly save the login
00172             if code == 200:
00173                 if self.has_config:
00174                     # sharing the password in the distribution instance
00175                     # so the upload command can reuse it
00176                     self.distribution.password = password
00177                 else:
00178                     self.announce(('I can store your PyPI login so future '
00179                                    'submissions will be faster.'), log.INFO)
00180                     self.announce('(the login will be stored in %s)' % \
00181                                   self._get_rc_file(), log.INFO)
00182                     choice = 'X'
00183                     while choice.lower() not in 'yn':
00184                         choice = input('Save your login (y/N)?')
00185                         if not choice:
00186                             choice = 'n'
00187                     if choice.lower() == 'y':
00188                         self._store_pypirc(username, password)
00189 
00190         elif choice == '2':
00191             data = {':action': 'user'}
00192             data['name'] = data['password'] = data['email'] = ''
00193             data['confirm'] = None
00194             while not data['name']:
00195                 data['name'] = input('Username: ')
00196             while data['password'] != data['confirm']:
00197                 while not data['password']:
00198                     data['password'] = getpass.getpass('Password: ')
00199                 while not data['confirm']:
00200                     data['confirm'] = getpass.getpass(' Confirm: ')
00201                 if data['password'] != data['confirm']:
00202                     data['password'] = ''
00203                     data['confirm'] = None
00204                     print("Password and confirm don't match!")
00205             while not data['email']:
00206                 data['email'] = input('   EMail: ')
00207             code, result = self.post_to_server(data)
00208             if code != 200:
00209                 log.info('Server response (%s): %s' % (code, result))
00210             else:
00211                 log.info('You will receive an email shortly.')
00212                 log.info(('Follow the instructions in it to '
00213                           'complete registration.'))
00214         elif choice == '3':
00215             data = {':action': 'password_reset'}
00216             data['email'] = ''
00217             while not data['email']:
00218                 data['email'] = input('Your email address: ')
00219             code, result = self.post_to_server(data)
00220             log.info('Server response (%s): %s' % (code, result))

Here is the call graph for this function:

Here is the caller graph for this function:

Send the metadata to the package index server to be checked.

Definition at line 92 of file register.py.

00092 
00093     def verify_metadata(self):
00094         ''' Send the metadata to the package index server to be checked.
00095         '''
00096         # send the info to the server and report the result
00097         (code, result) = self.post_to_server(self.build_post_data('verify'))
00098         log.info('Server response (%s): %s' % (code, result))

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Initial value:
PyPIRCCommand.boolean_options+[
        'verify', 'list-classifiers', 'strict']

Definition at line 26 of file register.py.

tuple distutils.command.register.register.description = ("register the distribution with the Python package index") [static]

Definition at line 19 of file register.py.

Definition at line 77 of file register.py.

Definition at line 33 of file register.py.

Definition at line 74 of file register.py.

Definition at line 76 of file register.py.

Definition at line 75 of file register.py.

Definition at line 34 of file register.py.

list distutils.command.register.register.sub_commands = [('check', lambda self: True)] [static]

Definition at line 29 of file register.py.

Initial value:
PyPIRCCommand.user_options+[
        ('list-classifiers', None,
         'list the valid Trove classifiers'),
        ('strict', None ,
         'Will stop the registering if the meta-data are not fully compliant')
        ]

Definition at line 20 of file register.py.

Definition at line 73 of file register.py.


The documentation for this class was generated from the following file: