[Subversion] / PyDicia / README.txt  

Diff of /PyDicia/README.txt

Parent Directory | Revision Log

version 2320, Wed Jul 4 16:25:46 2007 UTC version 2321, Wed Jul 4 17:13:50 2007 UTC
Line 17 
Line 17 
 requires Python 2.4 or higher (due to use of decorators and the ``Decimal``  requires Python 2.4 or higher (due to use of decorators and the ``Decimal``
 type).  type).
   
   IMPORTANT
       Please note that PyDicia does not attempt to implement all of the US Postal
       Service's business rules for what options may be used in what combinations.
       It doesn't even validate most of the DAZzle client's documented
       restrictions!  So it's strictly a "Garbage In, Garbage Out" kind of deal.
       If you put garbage in, who knows what the heck will happen.  You might end
       up spending lots of money *and* getting your packages returned to you --
       and **I AM NOT RESPONSIBLE**, even if your problem is due to an error in
       PyDicia or its documentation!
   
       So, make sure you understand the shipping options you wish to use, and test
       your application thoroughly before using this code in production.  You have
       been warned!
   
 TODO:  
   
 * global defaults  TODO:
   
 * Cmd-line and queue mode handlers  * Cmd-line and queue mode handlers
   
Line 31 
Line 43 
 Developer's Guide  Developer's Guide
 -----------------  -----------------
   
   
 Basic XML Generation  Basic XML Generation
 ====================  ====================
   
 PyDicia simplifies the creation of XML for DAZzle by using objects to specify  PyDicia simplifies the creation of XML for DAZzle by using objects to specify
 what data needs to go in the XML.  These objects are mostly ``DocInfo``  what data needs to go in the XML.  These objects are mostly ``Option``
 instances, or callables that create ``DocInfo`` instances.  However, the  instances, or callables that create ``Option`` instances.  However, the
 framework is extensible, so that you can use your own object types with the  framework is extensible, so that you can use your own object types with the
 same API.  Your object types can either generate ``DocInfo`` instances, or  same API.  Your object types can either generate ``Option`` instances, or
 directly manipulate the XML using ElementTree APIs for maximum control.  directly manipulate the XML using ElementTree APIs for maximum control.
   
 In the simpler cases, however, you will just use lists or tuples of objects  In the simpler cases, however, you will just use lists or tuples of objects
Line 93 
Line 106 
 have been passed to ``add_package()``::  have been passed to ``add_package()``::
   
     >>> b.packages      >>> b.packages
     [(DocInfo('ToName', 'Phillip Eby', None),),      [(Option('ToName', 'Phillip Eby', None),),
      ([DocInfo('Services', 'ON', 'COD'), (DocInfo('Stealth', 'TRUE', None),       ([Option('Services', 'ON', 'COD'), (Option('Stealth', 'TRUE', None),
        DocInfo('ToName', 'Ty Sarna', None))],         Option('ToName', 'Ty Sarna', None))],
       DocInfo('PackageType', 'FLATRATEBOX', None))]        Option('PackageType', 'FLATRATEBOX', None))]
   
 Each "package" in the list is a tuple of the arguments that were supplied for  Each "package" in the list is a tuple of the arguments that were supplied for
 each invocation of ``add_package()``.  each invocation of ``add_package()``.
Line 106 
Line 119 
 ---------------------------------  ---------------------------------
   
 It also accepts any custom objects of your own design, that are registered with  It also accepts any custom objects of your own design, that are registered with
 the ``pydicia.add_to_package()`` or ``pydicia.iter_docinfo()`` generic  the ``pydicia.add_to_package()`` or ``pydicia.iter_options()`` generic
 functions::  functions::
   
     >>> class Customer:      >>> class Customer:
     ...     def __init__(self, **kw):      ...     def __init__(self, **kw):
     ...         self.__dict__ = kw      ...         self.__dict__ = kw
   
     >>> @iter_docinfo.when_type(Customer)      >>> @iter_options.when_type(Customer)
     ... def cust_docinfo(ob):      ... def cust_options(ob):
     ...     yield ToName(ob.name)      ...     yield ToName(ob.name)
     ...     yield ToAddress(ob.address)      ...     yield ToAddress(ob.address)
     ...     yield ToCity(ob.city)      ...     yield ToCity(ob.city)
Line 140 
Line 153 
   
 This allows you to pass customer, package, product, invoice, or other  This allows you to pass customer, package, product, invoice, or other
 application-specific objects into ``add_package()``.  And the objects yielded  application-specific objects into ``add_package()``.  And the objects yielded
 by your ``iter_docinfo`` implementation can also be application objects, e.g.::  by your ``iter_options`` implementation can also be application objects, e.g.::
   
     >>> class Invoice:      >>> class Invoice:
     ...     def __init__(self, **kw):      ...     def __init__(self, **kw):
     ...         self.__dict__ = kw      ...         self.__dict__ = kw
   
     >>> @iter_docinfo.when_type(Invoice)      >>> @iter_options.when_type(Invoice)
     ... def invoice_docinfo(ob):      ... def invoice_options(ob):
     ...     yield ob.shippingtype      ...     yield ob.shippingtype
     ...     yield ob.products      ...     yield ob.products
     ...     yield ob.customer      ...     yield ob.customer
Line 175 
Line 188 
 Also note that there is no particular significance to my choice of lists vs.  Also note that there is no particular significance to my choice of lists vs.
 tuples in these examples; they're more to demonstrate that you can use  tuples in these examples; they're more to demonstrate that you can use
 arbitrary structures, as long as they contain objects that are supported by  arbitrary structures, as long as they contain objects that are supported by
 either ``iter_docinfo()`` or ``add_to_package()``.  Normally, you will simply  either ``iter_options()`` or ``add_to_package()``.  Normally, you will simply
 use collections of either PyDicia-provided symbols, or application objects for  use collections of either PyDicia-provided symbols, or application objects for
 which you've defined an ``iter_docinfo()`` method.  which you've defined an ``iter_options()`` method.
   
 You will also usually want to implement your PyDicia support in a module by  You will also usually want to implement your PyDicia support in a module by
 itself, so you can use ``from pydicia import *`` without worrying about symbol  itself, so you can use ``from pydicia import *`` without worrying about symbol
Line 326 
Line 339 
 Invoking DAZzle  Invoking DAZzle
 ===============  ===============
   
   XXX
   
   
 Application Integration  Application Integration
 =======================  =======================
   
 Status handling, Address updating, ...  Status handling, Address updating, ToReturnCode()...
   
   
 Advanced Customization  Advanced Customization
 ======================  ======================
   
 Using DocInfo elements, add_to_package()  Using Option elements, add_to_package()
   
   
   
 -----------------  -----------------
Line 349 
Line 365 
 MailClass(text), NoPostage  MailClass(text), NoPostage
   
 DateAdvance(), Today, Tomorrow  DateAdvance(), Today, Tomorrow
 WeightOz(), Width(), Length(), Depth()  
 Value()  Value()
 Description()  Description()
   WeightOz()
   
   
 Addresses  Addresses
 =========  =========
   
     >>> ToName("Phillip J. Eby")      >>> ToName("Phillip J. Eby")
     DocInfo('ToName', 'Phillip J. Eby', None)      Option('ToName', 'Phillip J. Eby', None)
   
     >>> ToTitle("President")      >>> ToTitle("President")
     DocInfo('ToTitle', 'President', None)      Option('ToTitle', 'President', None)
   
     >>> ToCompany("Dirt Simple, Inc.")      >>> ToCompany("Dirt Simple, Inc.")
     DocInfo('ToCompany', 'Dirt Simple, Inc.', None)      Option('ToCompany', 'Dirt Simple, Inc.', None)
   
   
 ToAddress(*lines)  ToAddress(*lines)
Line 374 
Line 391 
 ToDeliveryPoint(text)  ToDeliveryPoint(text)
 EndorsementLine(text)  EndorsementLine(text)
 ToCarrierRoute(text)  ToCarrierRoute(text)
 ToReturnCode(text)  
   
   
 Service Options  Package Details
 ===============  ===============
   
   PackageType()
 FlatRateEnvelope  FlatRateEnvelope
 FlatRateBox  FlatRateBox
 RectangularParcel  RectangularParcel
Line 388 
Line 405 
 Flat  Flat
 Envelope  Envelope
   
   Width(), Length(), Depth()
   
 NonMachinable  NonMachinable
 BalloonRate  BalloonRate
   
   
   
   Service Options
   ===============
   
 ReplyPostage  ReplyPostage
 Stealth  Stealth
   
Line 399 
Line 423 
 NoHolidayDelivery  NoHolidayDelivery
 ReturnToSender  ReturnToSender
   
 RegisteredMail  
   
 Insurance.USPS  Insurance.USPS
 Insurance.Endicia  Insurance.Endicia
 Insurance.UPIC  Insurance.UPIC
 Insurance.NONE  Insurance.NONE
   
 Domestic.  RegisteredMail
   
 CertifiedMail  CertifiedMail
 RestrictedDelivery  RestrictedDelivery
 CertificateOfMailing  CertificateOfMailing
Line 420 
Line 441 
 Customs Forms  Customs Forms
 =============  =============
   
 Sample  Customs.Sample
 Gift  Customs.Gift
 Documents  Customs.Documents
 Other  Customs.Other
 Merchandise  Customs.Merchandise
   
 Customs.GEM(ctype, *items)  Customs.GEM
 Customs.CN22(ctype, *items)  Customs.CN22
 Customs.CP72(ctype, *items)  Customs.CP72
   Customs.NONE
   
 Customs(formtype, ctype, *items)  Customs.Item(desc, weight, value, qty=1, origin='United States')
   
 Item(desc, weight, value, qty=1, origin='United States')  Customs.Signer(text)
   Customs.Certify
   
 CustomsSigner(text)  ContentsType(), CustomsFormType()
 CustomsCertify  
   
   
 Processing Options  Processing Options
Line 443 
Line 465 
   
 Test  Test
 Layout(filename)  Layout(filename)
   OutputFile(filename)
   
 Print  Print
 Verify  Verify
   
 SkipUnverified  SkipUnverified
 AutoClose  AutoClose
 Prompt  Prompt
Line 465 
Line 490 
 Internals and Tests  Internals and Tests
 -------------------  -------------------
   
     >>> from pydicia import add_to_package, ET, DocInfo, Batch, Package      >>> from pydicia import add_to_package, ET, Option, Batch, Package
   
 Packages::  Packages::
   
Line 477 
Line 502 
         <Package ID="1" />          <Package ID="1" />
     </DAZzle>      </DAZzle>
   
     >>> Box = DocInfo('FlatRate', 'BOX')      >>> Box = Option('FlatRate', 'BOX')
     >>> add_to_package(Box, p, False)      >>> add_to_package(Box, p, False)
   
     >>> print b.tostring()      >>> print b.tostring()
Line 487 
Line 512 
         </Package>          </Package>
     </DAZzle>      </DAZzle>
   
     >>> Envelope = DocInfo('FlatRate', 'TRUE')      >>> Envelope = Option('FlatRate', 'TRUE')
     >>> add_to_package(Envelope, p, False)      >>> add_to_package(Envelope, p, False)
     Traceback (most recent call last):      Traceback (most recent call last):
       ...        ...
     DocInfoConflict: Can't set 'FlatRate=TRUE' when 'FlatRate=BOX' already set      OptionConflict: Can't set 'FlatRate=TRUE' when 'FlatRate=BOX' already set
   
     >>> print b.tostring()      >>> print b.tostring()
     <DAZzle>      <DAZzle>
Line 522 
Line 547 
         <Package ID="1" />          <Package ID="1" />
     </DAZzle>      </DAZzle>
   
     >>> verify_zip = DocInfo('DAZzle', 'DAZ', 'Start')      >>> verify_zip = Option('DAZzle', 'DAZ', 'Start')
   
     >>> add_to_package(verify_zip, p, False)      >>> add_to_package(verify_zip, p, False)
     >>> print b.tostring()      >>> print b.tostring()
Line 530 
Line 555 
         <Package ID="1" />          <Package ID="1" />
     </DAZzle>      </DAZzle>
   
     >>> add_to_package(DocInfo('DAZzle', 'PRINTING', 'Start'), p, False)      >>> add_to_package(Option('DAZzle', 'PRINTING', 'Start'), p, False)
     Traceback (most recent call last):      Traceback (most recent call last):
       ...        ...
     DocInfoConflict: Can't set 'DAZzle.Start=PRINTING' when 'DAZzle.Start=DAZ' already set      OptionConflict: Can't set 'DAZzle.Start=PRINTING' when 'DAZzle.Start=DAZ' already set
   
     >>> b = Batch()      >>> b = Batch()
     >>> p = Package(b)      >>> p = Package(b)
Line 576 
Line 601 
     >>> b.add_package(FlatRateEnvelope, FlatRateBox)      >>> b.add_package(FlatRateEnvelope, FlatRateBox)
     Traceback (most recent call last):      Traceback (most recent call last):
       ...        ...
     DocInfoConflict: Can't set 'PackageType=FLATRATEBOX' when      OptionConflict: Can't set 'PackageType=FLATRATEBOX' when
                                'PackageType=FLATRATEENVELOPE' already set                                 'PackageType=FLATRATEENVELOPE' already set
   
     >>> print b.tostring()  # rollback on error      >>> print b.tostring()  # rollback on error
Line 600 
Line 625 
     </DAZzle>      </DAZzle>
   
   
 DocInfo inversion::  Option inversion::
   
     >>> ~Envelope      >>> ~Envelope
     DocInfo('FlatRate', 'FALSE', None)      Option('FlatRate', 'FALSE', None)
     >>> ~~Envelope      >>> ~~Envelope
     DocInfo('FlatRate', 'TRUE', None)      Option('FlatRate', 'TRUE', None)
   
     >>> ~DocInfo('Services', 'ON', 'RegisteredMail')      >>> ~Option('Services', 'ON', 'RegisteredMail')
     DocInfo('Services', 'OFF', 'RegisteredMail')      Option('Services', 'OFF', 'RegisteredMail')
     >>> ~~DocInfo('Services', 'ON', 'RegisteredMail')      >>> ~~Option('Services', 'ON', 'RegisteredMail')
     DocInfo('Services', 'ON', 'RegisteredMail')      Option('Services', 'ON', 'RegisteredMail')
   
     >>> ~DocInfo('DAZzle', 'YES', 'Prompt')      >>> ~Option('DAZzle', 'YES', 'Prompt')
     DocInfo('DAZzle', 'NO', 'Prompt')      Option('DAZzle', 'NO', 'Prompt')
     >>> ~~DocInfo('DAZzle', 'YES', 'Prompt')      >>> ~~Option('DAZzle', 'YES', 'Prompt')
     DocInfo('DAZzle', 'YES', 'Prompt')      Option('DAZzle', 'YES', 'Prompt')
   
   
 The ``iter_docinfo()`` generic function yields "docinfo" objects for an  The ``iter_options()`` generic function yields "option" objects for an
 application object.  The default implementation is to raise an error::  application object.  The default implementation is to raise an error::
   
     >>> from pydicia import iter_docinfo      >>> from pydicia import iter_options
   
     >>> iter_docinfo(27)      >>> iter_options(27)
     Traceback (most recent call last):      Traceback (most recent call last):
       ...        ...
     NotImplementedError: ('No docinfo producer registered for', <type 'int'>)      NotImplementedError: ('No option producer registered for', <type 'int'>)
   
 And for lists and tuples, the default is to yield their contents::  And for lists and tuples, the default is to yield their contents::
   
     >>> list(iter_docinfo((1, 2, 3)))      >>> list(iter_options((1, 2, 3)))
     [1, 2, 3]      [1, 2, 3]
   
     >>> list(iter_docinfo(['a', 'b']))      >>> list(iter_options(['a', 'b']))
     ['a', 'b']      ['a', 'b']
   
 This routine is used internally by ``add_to_package()``.  This routine is used internally by ``add_to_package()``.


Generate output suitable for use with a patch program
Legend:
Removed from v.2320  
changed lines
  Added in v.2321

cvs-admin@eby-sarna.com

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help