+
+
+
+
diff --git a/docs/2.2.0/crarr.png b/docs/2.2.0/crarr.png
new file mode 100644
index 0000000..26b43c5
Binary files /dev/null and b/docs/2.2.0/crarr.png differ
diff --git a/docs/2.2.0/epydoc.css b/docs/2.2.0/epydoc.css
new file mode 100644
index 0000000..86d4170
--- /dev/null
+++ b/docs/2.2.0/epydoc.css
@@ -0,0 +1,322 @@
+
+
+/* Epydoc CSS Stylesheet
+ *
+ * This stylesheet can be used to customize the appearance of epydoc's
+ * HTML output.
+ *
+ */
+
+/* Default Colors & Styles
+ * - Set the default foreground & background color with 'body'; and
+ * link colors with 'a:link' and 'a:visited'.
+ * - Use bold for decision list terms.
+ * - The heading styles defined here are used for headings *within*
+ * docstring descriptions. All headings used by epydoc itself use
+ * either class='epydoc' or class='toc' (CSS styles for both
+ * defined below).
+ */
+body { background: #ffffff; color: #000000; }
+p { margin-top: 0.5em; margin-bottom: 0.5em; }
+a:link { color: #0000ff; }
+a:visited { color: #204080; }
+dt { font-weight: bold; }
+h1 { font-size: +140%; font-style: italic;
+ font-weight: bold; }
+h2 { font-size: +125%; font-style: italic;
+ font-weight: bold; }
+h3 { font-size: +110%; font-style: italic;
+ font-weight: normal; }
+code { font-size: 100%; }
+/* N.B.: class, not pseudoclass */
+a.link { font-family: monospace; }
+
+/* Page Header & Footer
+ * - The standard page header consists of a navigation bar (with
+ * pointers to standard pages such as 'home' and 'trees'); a
+ * breadcrumbs list, which can be used to navigate to containing
+ * classes or modules; options links, to show/hide private
+ * variables and to show/hide frames; and a page title (using
+ *
). The page title may be followed by a link to the
+ * corresponding source code (using 'span.codelink').
+ * - The footer consists of a navigation bar, a timestamp, and a
+ * pointer to epydoc's homepage.
+ */
+h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; }
+h2.epydoc { font-size: +130%; font-weight: bold; }
+h3.epydoc { font-size: +115%; font-weight: bold;
+ margin-top: 0.2em; }
+td h3.epydoc { font-size: +115%; font-weight: bold;
+ margin-bottom: 0; }
+table.navbar { background: #a0c0ff; color: #000000;
+ border: 2px groove #c0d0d0; }
+table.navbar table { color: #000000; }
+th.navbar-select { background: #70b0ff;
+ color: #000000; }
+table.navbar a { text-decoration: none; }
+table.navbar a:link { color: #0000ff; }
+table.navbar a:visited { color: #204080; }
+span.breadcrumbs { font-size: 85%; font-weight: bold; }
+span.options { font-size: 70%; }
+span.codelink { font-size: 85%; }
+td.footer { font-size: 85%; }
+
+/* Table Headers
+ * - Each summary table and details section begins with a 'header'
+ * row. This row contains a section title (marked by
+ * 'span.table-header') as well as a show/hide private link
+ * (marked by 'span.options', defined above).
+ * - Summary tables that contain user-defined groups mark those
+ * groups using 'group header' rows.
+ */
+td.table-header { background: #70b0ff; color: #000000;
+ border: 1px solid #608090; }
+td.table-header table { color: #000000; }
+td.table-header table a:link { color: #0000ff; }
+td.table-header table a:visited { color: #204080; }
+span.table-header { font-size: 120%; font-weight: bold; }
+th.group-header { background: #c0e0f8; color: #000000;
+ text-align: left; font-style: italic;
+ font-size: 115%;
+ border: 1px solid #608090; }
+
+/* Summary Tables (functions, variables, etc)
+ * - Each object is described by a single row of the table with
+ * two cells. The left cell gives the object's type, and is
+ * marked with 'code.summary-type'. The right cell gives the
+ * object's name and a summary description.
+ * - CSS styles for the table's header and group headers are
+ * defined above, under 'Table Headers'
+ */
+table.summary { border-collapse: collapse;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #608090;
+ margin-bottom: 0.5em; }
+td.summary { border: 1px solid #608090; }
+code.summary-type { font-size: 85%; }
+table.summary a:link { color: #0000ff; }
+table.summary a:visited { color: #204080; }
+
+
+/* Details Tables (functions, variables, etc)
+ * - Each object is described in its own div.
+ * - A single-row summary table w/ table-header is used as
+ * a header for each details section (CSS style for table-header
+ * is defined above, under 'Table Headers').
+ */
+table.details { border-collapse: collapse;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #608090;
+ margin: .2em 0 0 0; }
+table.details table { color: #000000; }
+table.details a:link { color: #0000ff; }
+table.details a:visited { color: #204080; }
+
+/* Fields */
+dl.fields { margin-left: 2em; margin-top: 1em;
+ margin-bottom: 1em; }
+dl.fields dd ul { margin-left: 0em; padding-left: 0em; }
+dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; }
+div.fields { margin-left: 2em; }
+div.fields p { margin-bottom: 0.5em; }
+
+/* Index tables (identifier index, term index, etc)
+ * - link-index is used for indices containing lists of links
+ * (namely, the identifier index & term index).
+ * - index-where is used in link indices for the text indicating
+ * the container/source for each link.
+ * - metadata-index is used for indices containing metadata
+ * extracted from fields (namely, the bug index & todo index).
+ */
+table.link-index { border-collapse: collapse;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #608090; }
+td.link-index { border-width: 0px; }
+table.link-index a:link { color: #0000ff; }
+table.link-index a:visited { color: #204080; }
+span.index-where { font-size: 70%; }
+table.metadata-index { border-collapse: collapse;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #608090;
+ margin: .2em 0 0 0; }
+td.metadata-index { border-width: 1px; border-style: solid; }
+table.metadata-index a:link { color: #0000ff; }
+table.metadata-index a:visited { color: #204080; }
+
+/* Function signatures
+ * - sig* is used for the signature in the details section.
+ * - .summary-sig* is used for the signature in the summary
+ * table, and when listing property accessor functions.
+ * */
+.sig-name { color: #006080; }
+.sig-arg { color: #008060; }
+.sig-default { color: #602000; }
+.summary-sig { font-family: monospace; }
+.summary-sig-name { color: #006080; font-weight: bold; }
+table.summary a.summary-sig-name:link
+ { color: #006080; font-weight: bold; }
+table.summary a.summary-sig-name:visited
+ { color: #006080; font-weight: bold; }
+.summary-sig-arg { color: #006040; }
+.summary-sig-default { color: #501800; }
+
+/* Subclass list
+ */
+ul.subclass-list { display: inline; }
+ul.subclass-list li { display: inline; }
+
+/* To render variables, classes etc. like functions */
+table.summary .summary-name { color: #006080; font-weight: bold;
+ font-family: monospace; }
+table.summary
+ a.summary-name:link { color: #006080; font-weight: bold;
+ font-family: monospace; }
+table.summary
+ a.summary-name:visited { color: #006080; font-weight: bold;
+ font-family: monospace; }
+
+/* Variable values
+ * - In the 'variable details' sections, each varaible's value is
+ * listed in a 'pre.variable' box. The width of this box is
+ * restricted to 80 chars; if the value's repr is longer than
+ * this it will be wrapped, using a backslash marked with
+ * class 'variable-linewrap'. If the value's repr is longer
+ * than 3 lines, the rest will be ellided; and an ellipsis
+ * marker ('...' marked with 'variable-ellipsis') will be used.
+ * - If the value is a string, its quote marks will be marked
+ * with 'variable-quote'.
+ * - If the variable is a regexp, it is syntax-highlighted using
+ * the re* CSS classes.
+ */
+pre.variable { padding: .5em; margin: 0;
+ background: #dce4ec; color: #000000;
+ border: 1px solid #708890; }
+.variable-linewrap { color: #604000; font-weight: bold; }
+.variable-ellipsis { color: #604000; font-weight: bold; }
+.variable-quote { color: #604000; font-weight: bold; }
+.variable-group { color: #008000; font-weight: bold; }
+.variable-op { color: #604000; font-weight: bold; }
+.variable-string { color: #006030; }
+.variable-unknown { color: #a00000; font-weight: bold; }
+.re { color: #000000; }
+.re-char { color: #006030; }
+.re-op { color: #600000; }
+.re-group { color: #003060; }
+.re-ref { color: #404040; }
+
+/* Base tree
+ * - Used by class pages to display the base class hierarchy.
+ */
+pre.base-tree { font-size: 80%; margin: 0; }
+
+/* Frames-based table of contents headers
+ * - Consists of two frames: one for selecting modules; and
+ * the other listing the contents of the selected module.
+ * - h1.toc is used for each frame's heading
+ * - h2.toc is used for subheadings within each frame.
+ */
+h1.toc { text-align: center; font-size: 105%;
+ margin: 0; font-weight: bold;
+ padding: 0; }
+h2.toc { font-size: 100%; font-weight: bold;
+ margin: 0.5em 0 0 -0.3em; }
+
+/* Syntax Highlighting for Source Code
+ * - doctest examples are displayed in a 'pre.py-doctest' block.
+ * If the example is in a details table entry, then it will use
+ * the colors specified by the 'table pre.py-doctest' line.
+ * - Source code listings are displayed in a 'pre.py-src' block.
+ * Each line is marked with 'span.py-line' (used to draw a line
+ * down the left margin, separating the code from the line
+ * numbers). Line numbers are displayed with 'span.py-lineno'.
+ * The expand/collapse block toggle button is displayed with
+ * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not
+ * modify the font size of the text.)
+ * - If a source code page is opened with an anchor, then the
+ * corresponding code block will be highlighted. The code
+ * block's header is highlighted with 'py-highlight-hdr'; and
+ * the code block's body is highlighted with 'py-highlight'.
+ * - The remaining py-* classes are used to perform syntax
+ * highlighting (py-string for string literals, py-name for names,
+ * etc.)
+ */
+pre.py-doctest { padding: .5em; margin: 1em;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #708890; }
+table pre.py-doctest { background: #dce4ec;
+ color: #000000; }
+pre.py-src { border: 2px solid #000000;
+ background: #f0f0f0; color: #000000; }
+.py-line { border-left: 2px solid #000000;
+ margin-left: .2em; padding-left: .4em; }
+.py-lineno { font-style: italic; font-size: 90%;
+ padding-left: .5em; }
+a.py-toggle { text-decoration: none; }
+div.py-highlight-hdr { border-top: 2px solid #000000;
+ border-bottom: 2px solid #000000;
+ background: #d8e8e8; }
+div.py-highlight { border-bottom: 2px solid #000000;
+ background: #d0e0e0; }
+.py-prompt { color: #005050; font-weight: bold;}
+.py-more { color: #005050; font-weight: bold;}
+.py-string { color: #006030; }
+.py-comment { color: #003060; }
+.py-keyword { color: #600000; }
+.py-output { color: #404040; }
+.py-name { color: #000050; }
+.py-name:link { color: #000050 !important; }
+.py-name:visited { color: #000050 !important; }
+.py-number { color: #005000; }
+.py-defname { color: #000060; font-weight: bold; }
+.py-def-name { color: #000060; font-weight: bold; }
+.py-base-class { color: #000060; }
+.py-param { color: #000060; }
+.py-docstring { color: #006030; }
+.py-decorator { color: #804020; }
+/* Use this if you don't want links to names underlined: */
+/*a.py-name { text-decoration: none; }*/
+
+/* Graphs & Diagrams
+ * - These CSS styles are used for graphs & diagrams generated using
+ * Graphviz dot. 'img.graph-without-title' is used for bare
+ * diagrams (to remove the border created by making the image
+ * clickable).
+ */
+img.graph-without-title { border: none; }
+img.graph-with-title { border: 1px solid #000000; }
+span.graph-title { font-weight: bold; }
+span.graph-caption { }
+
+/* General-purpose classes
+ * - 'p.indent-wrapped-lines' defines a paragraph whose first line
+ * is not indented, but whose subsequent lines are.
+ * - The 'nomargin-top' class is used to remove the top margin (e.g.
+ * from lists). The 'nomargin' class is used to remove both the
+ * top and bottom margin (but not the left or right margin --
+ * for lists, that would cause the bullets to disappear.)
+ */
+p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em;
+ margin: 0; }
+.nomargin-top { margin-top: 0; }
+.nomargin { margin-top: 0; margin-bottom: 0; }
+
+/* HTML Log */
+div.log-block { padding: 0; margin: .5em 0 .5em 0;
+ background: #e8f0f8; color: #000000;
+ border: 1px solid #000000; }
+div.log-error { padding: .1em .3em .1em .3em; margin: 4px;
+ background: #ffb0b0; color: #000000;
+ border: 1px solid #000000; }
+div.log-warning { padding: .1em .3em .1em .3em; margin: 4px;
+ background: #ffffb0; color: #000000;
+ border: 1px solid #000000; }
+div.log-info { padding: .1em .3em .1em .3em; margin: 4px;
+ background: #b0ffb0; color: #000000;
+ border: 1px solid #000000; }
+h2.log-hdr { background: #70b0ff; color: #000000;
+ margin: 0; padding: 0em 0.5em 0em 0.5em;
+ border-bottom: 1px solid #000000; font-size: 110%; }
+p.log { font-weight: bold; margin: .5em 0 .5em 0; }
+tr.opt-changed { color: #000000; font-weight: bold; }
+tr.opt-default { color: #606060; }
+pre.log { margin: 0; padding: 0; padding-left: 1em; }
diff --git a/docs/2.2.0/epydoc.js b/docs/2.2.0/epydoc.js
new file mode 100644
index 0000000..e787dbc
--- /dev/null
+++ b/docs/2.2.0/epydoc.js
@@ -0,0 +1,293 @@
+function toggle_private() {
+ // Search for any private/public links on this page. Store
+ // their old text in "cmd," so we will know what action to
+ // take; and change their text to the opposite action.
+ var cmd = "?";
+ var elts = document.getElementsByTagName("a");
+ for(var i=0; i";
+ s += " ";
+ for (var i=0; i... ";
+ elt.innerHTML = s;
+ }
+}
+
+function toggle(id) {
+ elt = document.getElementById(id+"-toggle");
+ if (elt.innerHTML == "-")
+ collapse(id);
+ else
+ expand(id);
+ return false;
+}
+
+function highlight(id) {
+ var elt = document.getElementById(id+"-def");
+ if (elt) elt.className = "py-highlight-hdr";
+ var elt = document.getElementById(id+"-expanded");
+ if (elt) elt.className = "py-highlight";
+ var elt = document.getElementById(id+"-collapsed");
+ if (elt) elt.className = "py-highlight";
+}
+
+function num_lines(s) {
+ var n = 1;
+ var pos = s.indexOf("\n");
+ while ( pos > 0) {
+ n += 1;
+ pos = s.indexOf("\n", pos+1);
+ }
+ return n;
+}
+
+// Collapse all blocks that mave more than `min_lines` lines.
+function collapse_all(min_lines) {
+ var elts = document.getElementsByTagName("div");
+ for (var i=0; i 0)
+ if (elt.id.substring(split, elt.id.length) == "-expanded")
+ if (num_lines(elt.innerHTML) > min_lines)
+ collapse(elt.id.substring(0, split));
+ }
+}
+
+function expandto(href) {
+ var start = href.indexOf("#")+1;
+ if (start != 0 && start != href.length) {
+ if (href.substring(start, href.length) != "-") {
+ collapse_all(4);
+ pos = href.indexOf(".", start);
+ while (pos != -1) {
+ var id = href.substring(start, pos);
+ expand(id);
+ pos = href.indexOf(".", pos+1);
+ }
+ var id = href.substring(start, href.length);
+ expand(id);
+ highlight(id);
+ }
+ }
+}
+
+function kill_doclink(id) {
+ var parent = document.getElementById(id);
+ parent.removeChild(parent.childNodes.item(0));
+}
+function auto_kill_doclink(ev) {
+ if (!ev) var ev = window.event;
+ if (!this.contains(ev.toElement)) {
+ var parent = document.getElementById(this.parentID);
+ parent.removeChild(parent.childNodes.item(0));
+ }
+}
+
+function doclink(id, name, targets_id) {
+ var elt = document.getElementById(id);
+
+ // If we already opened the box, then destroy it.
+ // (This case should never occur, but leave it in just in case.)
+ if (elt.childNodes.length > 1) {
+ elt.removeChild(elt.childNodes.item(0));
+ }
+ else {
+ // The outer box: relative + inline positioning.
+ var box1 = document.createElement("div");
+ box1.style.position = "relative";
+ box1.style.display = "inline";
+ box1.style.top = 0;
+ box1.style.left = 0;
+
+ // A shadow for fun
+ var shadow = document.createElement("div");
+ shadow.style.position = "absolute";
+ shadow.style.left = "-1.3em";
+ shadow.style.top = "-1.3em";
+ shadow.style.background = "#404040";
+
+ // The inner box: absolute positioning.
+ var box2 = document.createElement("div");
+ box2.style.position = "relative";
+ box2.style.border = "1px solid #a0a0a0";
+ box2.style.left = "-.2em";
+ box2.style.top = "-.2em";
+ box2.style.background = "white";
+ box2.style.padding = ".3em .4em .3em .4em";
+ box2.style.fontStyle = "normal";
+ box2.onmouseout=auto_kill_doclink;
+ box2.parentID = id;
+
+ // Get the targets
+ var targets_elt = document.getElementById(targets_id);
+ var targets = targets_elt.getAttribute("targets");
+ var links = "";
+ target_list = targets.split(",");
+ for (var i=0; i" +
+ target[0] + "";
+ }
+
+ // Put it all together.
+ elt.insertBefore(box1, elt.childNodes.item(0));
+ //box1.appendChild(box2);
+ box1.appendChild(shadow);
+ shadow.appendChild(box2);
+ box2.innerHTML =
+ "Which "+name+" do you want to see documentation for?" +
+ "
The python-fedex module is a light wrapper around Fedex's Web
+ Services SOAP API. Using the excellent suds SOAP
+ client, the Fedex requests and responses are trivial to work with.
+
What python-fedex is
+
+
+ A light wrapper around Fedex Web Services SOAP API.
+
+
+ Simple and easy to use.
+
+
+ Minimal by design.
+
+
+
What python-fedex is not
+
+
+ An abstraction layer. python-fedex only assembles the needed SOAP
+ calls and returns a SOAP response through suds. This is easy
+ enough to work with that no abstraction is needed. Doing so would
+ limit your use of the data.
+
+
+ Anything more than a light wrapper.
+
+
+
A note on completeness
+
python-fedex was created for use with various internal projects
+ over the years. Not all services are implemented but only those
+ needed at the time were implemented. If there is missing
+ functionality, please report an issue so that this module can be made more useful
+ to others. Likewise, feel free to submit patches and service
+ implementations as well if you would like to help.
+
Getting Started
+
The best place to get started is by viewing the examples in the
+ 'examples' directory. These should be very self-explanatory. For
+ further details, you may review the API here, or get support by
+ reading the instructions in the appropriately named section
+ below.
+
The services
+ module is also a good place to start looking at the different objects
+ used for issuing Fedex requests.
+
As a general tip, the best way to see which attributes are
+ available on WSDL objects is to simply print them, hitting their
+ __str__() method.
+
Fedex Documentation
+
If you are wondering what attributes or variables are present,
+ you'll want to refer to the Fedex Web Services documentation at
+ http://fedex.com/developer/. Complete specification documents are
+ there, which correspond very closely with what you'll be able to do
+ with python-fedex.
+
Getting Support
+
If you have any questions, problems, ideas, or patch submissions,
+ please visit our Github project and enter an issue in the Issue Tracker.
fedex.printers.unix: This module provides a label printing wrapper class for Unix-based
+ installations.
+
+
+
fedex.services: This module contains the wrappers around Fedex Web Service requests
+ which you will want to instantiate and use with a FedexConfig object supplying your static details.
+
+ 1"""
+ 2python-fedex API Documentation
+ 3==============================
+ 4The python-fedex module is a light wrapper around Fedex's Web Services SOAP API.
+ 5Using the excellent U{suds<https://fedorahosted.org/suds/>} SOAP client,
+ 6the Fedex requests and responses are trivial to work with.
+ 7
+ 8What python-fedex is
+ 9--------------------
+10 - A light wrapper around Fedex Web Services SOAP API.
+11 - Simple and easy to use.
+12 - Minimal by design.
+13
+14What python-fedex is not
+15------------------------
+16 - An abstraction layer. python-fedex only assembles the needed SOAP calls
+17 and returns a SOAP response through suds. This is easy enough to work with
+18 that no abstraction is needed. Doing so would limit your use of the data.
+19 - Anything more than a light wrapper.
+20
+21A note on completeness
+22----------------------
+23python-fedex was created for use with various internal projects over the years.
+24Not all services are implemented but only those needed at the time were implemented.
+25If there is missing functionality, please report an U{issue<http://code.google.com/p/python-fedex/issues/list>}
+26so that this module can be made more useful to others. Likewise, feel free to
+27submit patches and service implementations as well if you would like to help.
+28
+29Getting Started
+30---------------
+31The best place to get started is by viewing the examples in the 'examples'
+32directory. These should be very self-explanatory. For further details, you
+33may review the API here, or get support by reading the instructions in the
+34appropriately named section below.
+35
+36The L{services} module is also a good place to start looking at the different
+37objects used for issuing Fedex requests.
+38
+39As a general tip, the best way to see which attributes are available on WSDL
+40objects is to simply print them, hitting their __str__() method.
+41
+42Fedex Documentation
+43-------------------
+44If you are wondering what attributes or variables are present, you'll want to
+45refer to the Fedex Web Services documentation at http://fedex.com/developer/.
+46Complete specification documents are there, which correspond very closely with
+47what you'll be able to do with python-fedex.
+48
+49Getting Support
+50---------------
+51If you have any questions, problems, ideas, or patch submissions, please visit
+52our U{Github project<http://github.com/gtaylor/python-fedex/>} and enter
+53an issue in the U{Issue Tracker<http://github.com/gtaylor/python-fedex/issues>}.
+54"""
+55VERSION=__version__='2.2.0'
+56
+
The base_service module contains classes that form the low
+ level foundations of the Web Service API. Things that many different
+ kinds of requests have in common may be found here.
+
In particular, the FedexBaseService class handles most of the basic,
+ repetitive setup work that most requests do.
+ 1"""
+ 2The L{base_service} module contains classes that form the low level foundations
+ 3of the Web Service API. Things that many different kinds of requests have in
+ 4common may be found here.
+ 5
+ 6In particular, the L{FedexBaseService} class handles most of the basic,
+ 7repetitive setup work that most requests do.
+ 8"""
+ 9
+ 10importos
+ 11importlogging
+ 12
+ 13importsuds
+ 14fromsuds.clientimportClient
+ 15fromsuds.pluginimportMessagePlugin
+ 16
+ 17
+
72self.error_code=-1
+ 73self.value="suds encountered an error validating your data against this service's WSDL schema. " \
+ 74"Please double-check for missing or invalid values, filling all required fields."
+ 75try:
+ 76self.value+=' Details: {}'.format(fault)
+ 77exceptAttributeError:
+ 78pass
+
82"""
+ 83 This class is the master class for all Fedex request objects. It gets all
+ 84 of the common SOAP objects created via suds and populates them with
+ 85 values from a L{FedexConfig} object, along with keyword arguments
+ 86 via L{__init__}.
+ 87
+ 88 @note: This object should never be used directly, use one of the included
+ 89 sub-classes.
+ 90 """
+ 91
+
93"""
+ 94 This constructor should only be called by children of the class. As is
+ 95 such, only the optional keyword arguments caught by C{**kwargs} will
+ 96 be documented.
+ 97
+ 98 @type customer_transaction_id: L{str}
+ 99 @keyword customer_transaction_id: A user-specified identifier to
+100 differentiate this transaction from others. This value will be
+101 returned with the response from Fedex.
+102 """
+103
+104self.logger=logging.getLogger('fedex')
+105"""@ivar: Python logger instance with name 'fedex'."""
+106self.config_obj=config_obj
+107"""@ivar: The FedexConfig object to pull auth info from."""
+108
+109# If the config object is set to use the test server, point
+110# suds at the test server WSDL directory.
+111ifconfig_obj.use_test_server:
+112self.logger.info("Using test server.")
+113self.wsdl_path=os.path.join(config_obj.wsdl_path,
+114'test_server_wsdl',wsdl_name)
+115else:
+116self.logger.info("Using production server.")
+117self.wsdl_path=os.path.join(config_obj.wsdl_path,wsdl_name)
+118
+119self.client=Client('file:///%s'%self.wsdl_path.lstrip('/'),plugins=[GeneralSudsPlugin()])
+120# self.client.options.cache.clear() # Clear the cache, then re-init client when changing wsdl file.
+121
+122self.VersionId=None
+123"""@ivar: Holds details on the version numbers of the WSDL."""
+124self.WebAuthenticationDetail=None
+125"""@ivar: WSDL object that holds authentication info."""
+126self.ClientDetail=None
+127"""@ivar: WSDL object that holds client account details."""
+128self.response=None
+129"""@ivar: The response from Fedex. You will want to pick what you
+130 want out here here. This object does have a __str__() method,
+131 you'll want to print or log it to see what possible values
+132 you can pull."""
+133self.TransactionDetail=None
+134"""@ivar: Holds customer-specified transaction IDs."""
+135
+136self.__set_web_authentication_detail()
+137self.__set_client_detail(*args,**kwargs)
+138self.__set_version_id()
+139self.__set_transaction_detail(*args,**kwargs)
+140self._prepare_wsdl_objects()
+
143"""
+144 Sets up the WebAuthenticationDetail node. This is required for all
+145 requests.
+146 """
+147
+148# Start of the authentication stuff.
+149WebAuthenticationCredential=self.client.factory.create('WebAuthenticationCredential')
+150WebAuthenticationCredential.Key=self.config_obj.key
+151WebAuthenticationCredential.Password=self.config_obj.password
+152
+153# Encapsulates the auth credentials.
+154WebAuthenticationDetail=self.client.factory.create('WebAuthenticationDetail')
+155WebAuthenticationDetail.UserCredential=WebAuthenticationCredential
+156
+157# Set Default ParentCredential
+158ifhasattr(WebAuthenticationDetail,'ParentCredential'):
+159WebAuthenticationDetail.ParentCredential=WebAuthenticationCredential
+160
+161self.WebAuthenticationDetail=WebAuthenticationDetail
+
205"""
+206 Pulles the versioning info for the request from the child request.
+207 """
+208
+209VersionId=self.client.factory.create('VersionId')
+210VersionId.ServiceId=self._version_info['service_id']
+211VersionId.Major=self._version_info['major']
+212VersionId.Intermediate=self._version_info['intermediate']
+213VersionId.Minor=self._version_info['minor']
+214self.logger.debug(VersionId)
+215self.VersionId=VersionId
+
218"""
+219 This method should be over-ridden on each sub-class. It instantiates
+220 any of the required WSDL objects so the user can just print their
+221 __str__() methods and see what they need to fill in.
+222 """
+223
+224pass
+
227"""
+228 This checks the response for general Fedex errors that aren't related
+229 to any one WSDL.
+230 """
+231
+232ifself.response.HighestSeverity=="FAILURE":
+233fornotificationinself.response.Notifications:
+234ifnotification.Severity=="FAILURE":
+235raiseFedexFailure(notification.Code,
+236notification.Message)
+
239"""
+240 Override this in each service module to check for errors that are
+241 specific to that module. For example, invalid tracking numbers in
+242 a Tracking request.
+243 """
+244
+245ifself.response.HighestSeverity=="ERROR":
+246fornotificationinself.response.Notifications:
+247ifnotification.Severity=="ERROR":
+248raiseFedexError(notification.Code,
+249notification.Message)
+
259"""
+260 This method should be over-ridden on each sub-class. It assembles all required objects
+261 into the specific request object and calls send_request.
+262 """
+263
+264pass
+
267"""
+268 Sends the assembled request on the child object.
+269 @type send_function: function reference
+270 @keyword send_function: A function reference (passed without the
+271 parenthesis) to a function that will send the request. This
+272 allows for overriding the default function in cases such as
+273 validation requests.
+274 """
+275
+276# Send the request and get the response back.
+277try:
+278# If the user has overridden the send function, use theirs
+279# instead of the default.
+280ifsend_function:
+281# Follow the overridden function.
+282self.response=send_function()
+283else:
+284# Default scenario, business as usual.
+285self.response=self._assemble_and_send_request()
+286exceptsuds.WebFaultasfault:
+287# When this happens, throw an informative message reminding the
+288# user to check all required variables, making sure they are
+289# populated and valid
+290raiseSchemaValidationError(fault.fault)
+291
+292# Check the response for general Fedex errors/failures that aren't
+293# specific to any given WSDL/request.
+294self.__check_response_for_fedex_error()
+295# Check the response for errors specific to the particular request.
+296# This is handled by an overridden method on the child object.
+297self._check_response_for_request_errors()
+298
+299# Debug output.
+300self.logger.debug("== FEDEX QUERY RESULT ==")
+301self.logger.debug(self.response)
+
This class is the master class for all Fedex request objects. It gets
+ all of the common SOAP objects created via suds and populates them with
+ values from a FedexConfig object, along with keyword arguments via __init__.
+
+
+
Note:
+ This object should never be used directly, use one of the included
+ sub-classes.
+
This constructor should only be called by children of the class. As is
+ such, only the optional keyword arguments caught by **kwargs
+ will be documented.
+
+
Parameters:
+
+
customer_transaction_id (str) - A user-specified identifier to differentiate this transaction
+ from others. This value will be returned with the response from
+ Fedex.
Override this in each service module to check for errors that are
+ specific to that module. For example, invalid tracking numbers in a
+ Tracking request.
This method should be over-ridden on each sub-class. It instantiates
+ any of the required WSDL objects so the user can just print their
+ __str__() methods and see what they need to fill in.
send_function (function reference) - A function reference (passed without the parenthesis) to a
+ function that will send the request. This allows for overriding
+ the default function in cases such as validation requests.
+ The response from Fedex. You will want to pick what you want out here
+ here. This object does have a __str__() method, you'll want to print or
+ log it to see what possible values you can pull.
+
The config module
+ contains the FedexConfig class, which is passed to the Fedex API
+ calls. It stores useful information such as your Web Services account
+ numbers and keys.
+
It is strongly suggested that you create a single FedexConfig
+ object in your project and pass that to the various API calls, rather
+ than create new FedexConfig objects haphazardly. This is merely a design
+ suggestion, treat it as such.
+ 1"""
+ 2The L{config} module contains the L{FedexConfig} class, which is passed to
+ 3the Fedex API calls. It stores useful information such as your Web Services
+ 4account numbers and keys.
+ 5
+ 6It is strongly suggested that you create a single L{FedexConfig} object in
+ 7your project and pass that to the various API calls, rather than create new
+ 8L{FedexConfig} objects haphazardly. This is merely a design suggestion,
+ 9treat it as such.
+10"""
+11importos
+12
+13
+
15"""
+16 Base configuration class that is used for the different Fedex SOAP calls.
+17 These are generally passed to the Fedex request classes as arguments.
+18 You may instantiate a L{FedexConfig} object with the minimal C{key} and
+19 C{password} arguments and set the instance variables documented below
+20 at a later time if you must.
+21 """
+22
+
25"""
+26 @type key: L{str}
+27 @param key: Developer test key.
+28 @type password: L{str}
+29 @param password: The Fedex-generated password for your Web Systems
+30 account. This is generally emailed to you after registration.
+31 @type account_number: L{str}
+32 @keyword account_number: The account number sent to you by Fedex after
+33 registering for Web Services.
+34 @type meter_number: L{str}
+35 @keyword meter_number: The meter number sent to you by Fedex after
+36 registering for Web Services.
+37 @type freight_account_number: L{str}
+38 @keyword freight_account_number: The freight account number sent to you
+39 by Fedex after registering for Web Services.
+40 @type integrator_id: L{str}
+41 @keyword integrator_id: The integrator string sent to you by Fedex after
+42 registering for Web Services.
+43 @type wsdl_path: L{str}
+44 @keyword wsdl_path: In the event that you want to override the path to
+45 your WSDL directory, do so with this argument.
+46 @type use_test_server: L{bool}
+47 @keyword use_test_server: When this is True, test server WSDLs are used
+48 instead of the production server. You will also need to make sure
+49 that your L{FedexConfig} object has a production account number,
+50 meter number, authentication key, and password.
+51 """
+52self.key=key
+53"""@ivar: Developer test key."""
+54self.password=password
+55"""@ivar: Fedex Web Services password."""
+56self.account_number=account_number
+57"""@ivar: Web Services account number."""
+58self.meter_number=meter_number
+59"""@ivar: Web services meter number."""
+60self.freight_account_number=freight_account_number
+61"""@ivar: Web Services freight accountnumber."""
+62self.integrator_id=integrator_id
+63"""@ivar: Web services integrator ID."""
+64self.express_region_code=express_region_code
+65"""@ivar: Web services ExpressRegionCode"""
+66self.use_test_server=use_test_server
+67"""@ivar: When True, point to the test server."""
+68
+69# Allow overriding of the WDSL path.
+70ifwsdl_pathisNone:
+71self.wsdl_path=os.path.join(os.path.dirname(os.path.abspath(__file__)),
+72'wsdl')
+73else:# pragma: no cover
+74self.wsdl_path=wsdl_path
+
Base configuration class that is used for the different Fedex SOAP
+ calls. These are generally passed to the Fedex request classes as
+ arguments. You may instantiate a FedexConfig
+ object with the minimal key and password
+ arguments and set the instance variables documented below at a later time
+ if you must.
x.__init__(...) initializes x; see help(type(x)) for signature
+
+
Parameters:
+
+
key (str) - Developer test key.
+
password (str) - The Fedex-generated password for your Web Systems account. This
+ is generally emailed to you after registration.
+
account_number (str) - The account number sent to you by Fedex after registering for Web
+ Services.
+
meter_number (str) - The meter number sent to you by Fedex after registering for Web
+ Services.
+
freight_account_number (str) - The freight account number sent to you by Fedex after registering
+ for Web Services.
+
integrator_id (str) - The integrator string sent to you by Fedex after registering for
+ Web Services.
+
wsdl_path (str) - In the event that you want to override the path to your WSDL
+ directory, do so with this argument.
+
use_test_server (bool) - When this is True, test server WSDLs are used instead of the
+ production server. You will also need to make sure that your FedexConfig object has a production account
+ number, meter number, authentication key, and password.
Optional classes used for the convenient printing of FedEx labels from
+ FedexProcessShipmentRequest objects. Each printer class
+ is more or less the same, following the pattern seen below (unless
+ otherwise documented).:
+
+ from fedex.printers.unix import DirectDevicePrinter
+ # Where shipment is an existing L{FedexProcessShipmentRequest} object.
+ shipment.send_request()
+ device = DirectDevicePrinter(shipment)
+ device.print_label()
+
+ 1"""
+ 2Optional classes used for the convenient printing of FedEx labels from
+ 3L{FedexProcessShipmentRequest} objects. Each printer class is more or less
+ 4the same, following the pattern seen below (unless otherwise documented).::
+ 5 from fedex.printers.unix import DirectDevicePrinter
+ 6 # Where shipment is an existing L{FedexProcessShipmentRequest} object.
+ 7 shipment.send_request()
+ 8 device = DirectDevicePrinter(shipment)
+ 9 device.print_label()
+10"""
+11
+
This module provides a label printing wrapper class for Unix-based
+ installations. By "Unix", we mean Linux, Mac OS, BSD, and
+ various flavors of Unix.
+ 1"""
+ 2This module provides a label printing wrapper class for Unix-based
+ 3installations. By "Unix", we mean Linux, Mac OS, BSD, and various flavors
+ 4of Unix.
+ 5"""
+ 6
+ 7importbinascii
+ 8
+ 9
+
11"""
+12 This class pipes the label data directly through a /dev/* entry.
+13 Consequently, this is very Unix/Linux specific. It *MAY* work on Mac too.
+14 """
+15
+
17"""
+18 Instantiates from a shipment object. You may optionally specify
+19 a path to a /dev/ device. Defaults to /dev/ttyS0.
+20
+21 @type shipment: L{FedexProcessShipmentRequest}
+22 @param shipment: A Fedex ProcessShipmentRequest object to pull the
+23 printed label data from.
+24 """
+25
+26self.device=device
+27"""@ivar: A string with the path to the device to print to."""
+28self.shipment=shipment
+29"""@ivar: A reference to the L{FedexProcessShipmentRequest} to print."""
+
32"""
+33 Prints all of a shipment's labels, or optionally just one.
+34
+35 @type package_num: L{int}
+36 @param package_num: 0-based index of the package to print. This is
+37 only useful for shipments with more than one package.
+38 """
+39
+40ifpackage_num:
+41packages=[
+42self.shipment.response.CompletedShipmentDetail.CompletedPackageDetails[package_num]
+43]
+44else:
+45packages=self.shipment.response.CompletedShipmentDetail.CompletedPackageDetails
+46
+47forpackageinpackages:
+48label_binary=binascii.a2b_base64(package.Label.Parts[0].Image)
+49self._print_base64(label_binary)
+
52"""
+53 Pipe the binary directly to the label printer. Works under Linux
+54 without requiring PySerial. This is not typically something you
+55 should call directly, unless you have special needs.
+56
+57 @type base64_data: L{str}
+58 @param base64_data: The base64 encoded string for the label to print.
+59 """
+60
+61label_file=open(self.device,"w")
+62label_file.write(base64_data)
+63label_file.close()
+
Pipe the binary directly to the label printer. Works under Linux
+ without requiring PySerial. This is not typically something you should
+ call directly, unless you have special needs.
+
+
Parameters:
+
+
base64_data (str) - The base64 encoded string for the label to print.
This module contains the wrappers around Fedex Web Service requests
+ which you will want to instantiate and use with a FedexConfig
+ object supplying your static details. Each module here corresponds to a
+ Fedex WSDL.
+1"""
+2This module contains the wrappers around Fedex Web Service requests which you
+3will want to instantiate and use with a L{FedexConfig} object supplying
+4your static details. Each module here corresponds to a Fedex WSDL.
+5"""
+6
+
This package contains the shipping methods defined by Fedex's
+ AddressValidationService WSDL file. Each is encapsulated in a class for
+ easy access. For more details on each, refer to the respective class's
+ documentation.
+ 1"""
+ 2Address Validation Service Module
+ 3
+ 4This package contains the shipping methods defined by Fedex's
+ 5AddressValidationService WSDL file. Each is encapsulated in a class for
+ 6easy access. For more details on each, refer to the respective class's
+ 7documentation.
+ 8"""
+ 9
+10importdatetime
+11from..base_serviceimportFedexBaseService
+12
+13
+
15"""
+16 This class allows you validate anywhere from one to a hundred addresses
+17 in one go. Create AddressToValidate WSDL objects and add them to each
+18 instance of this request using add_address().
+19 """
+20
+
49"""
+50 Fires off the Fedex request.
+51
+52 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(),
+53 WHICH RESIDES ON FedexBaseService AND IS INHERITED.
+54 """
+55
+56# We get an exception like this when specifying an IntegratorId:
+57# suds.TypeNotFound: Type not found: 'IntegratorId'
+58# Setting it to None does not seem to appease it.
+59delself.ClientDetail.IntegratorId
+60self.logger.debug(self.WebAuthenticationDetail)
+61self.logger.debug(self.ClientDetail)
+62self.logger.debug(self.TransactionDetail)
+63self.logger.debug(self.VersionId)
+64# Fire off the query.
+65returnself.client.service.addressValidation(
+66WebAuthenticationDetail=self.WebAuthenticationDetail,
+67ClientDetail=self.ClientDetail,
+68TransactionDetail=self.TransactionDetail,
+69Version=self.VersionId,
+70InEffectAsOfTimestamp=datetime.datetime.now(),
+71AddressesToValidate=self.AddressesToValidate)
+
74"""
+75 Adds an address to self.AddressesToValidate.
+76
+77 @type address_item: WSDL object, type of AddressToValidate WSDL object.
+78 @keyword address_item: A AddressToValidate, created by
+79 calling create_wsdl_object_of_type('AddressToValidate') on
+80 this FedexAddressValidationRequest object.
+81 See examples/create_shipment.py for more details.
+82 """
+83
+84self.AddressesToValidate.append(address_item)
+
This class allows you validate anywhere from one to a hundred
+ addresses in one go. Create AddressToValidate WSDL objects and add them
+ to each instance of this request using add_address().
This constructor should only be called by children of the class. As is
+ such, only the optional keyword arguments caught by **kwargs
+ will be documented.
+
+
Parameters:
+
+
config_obj (FedexConfig) - A valid FedexConfig object.
address_item (WSDL object, type of AddressToValidate WSDL object.) - A AddressToValidate, created by calling
+ create_wsdl_object_of_type('AddressToValidate') on this
+ FedexAddressValidationRequest object. See
+ examples/create_shipment.py for more details.
This package contains the shipping methods defined by Fedex's
+ ValidationAvailabilityAndCommitmentService WSDL file. Each is
+ encapsulated in a class for easy access. For more details on each, refer
+ to the respective class's documentation.
+ 1"""
+ 2Service Availability and Commitment Module
+ 3
+ 4This package contains the shipping methods defined by Fedex's
+ 5ValidationAvailabilityAndCommitmentService WSDL file. Each is encapsulated in a class for
+ 6easy access. For more details on each, refer to the respective class's
+ 7documentation.
+ 8"""
+ 9
+ 10importdatetime
+ 11from..base_serviceimportFedexBaseService
+ 12
+ 13
+
20"""
+ 21 @type config_obj: L{FedexConfig}
+ 22 @param config_obj: A valid FedexConfig object.
+ 23 """
+ 24
+ 25self._config_obj=config_obj
+ 26# Holds version info for the VersionId SOAP object.
+ 27self._version_info={
+ 28'service_id':'vacs',
+ 29'major':'4',
+ 30'intermediate':'0',
+ 31'minor':'0'
+ 32}
+ 33
+ 34self.CarrierCode=None
+ 35"""ivar: Carrier Code Default to Fedex (FDXE), or can bbe FDXG."""
+ 36
+ 37self.Origin=None
+ 38"""@ivar: Holds Origin Address WSDL object."""
+ 39
+ 40self.Destination=None
+ 41"""@ivar: Holds Destination Address WSDL object."""
+ 42
+ 43self.ShipDate=None
+ 44"""@ivar: Ship Date date WSDL object."""
+ 45
+ 46self.Service=None
+ 47"""@ivar: Service type, if set to None will get all available service information."""
+ 48
+ 49self.Packaging=None
+ 50"""@ivar: Type of packaging to narrow down available shipping options or defaults to YOUR_PACKAGING."""
+ 51
+ 52# Call the parent FedexBaseService class for basic setup work.
+ 53# Shortened the name of the wsdl, otherwise suds did not load it properly.
+ 54# Suds throws the following error when using the long file name from FedEx:
+ 55#
+ 56# File "/Library/Python/2.7/site-packages/suds/wsdl.py", line 878, in resolve
+ 57# raise Exception("binding '%s', not-found" % p.binding)
+ 58# Exception: binding 'ns:ValidationAvailabilityAndCommitmentServiceSoapBinding', not-found
+ 59
+ 60super(FedexAvailabilityCommitmentRequest,self).__init__(
+ 61self._config_obj,'AvailabilityAndCommitmentService_v4.wsdl',*args,**kwargs)
+
64"""
+ 65 Create the data structure and get it ready for the WSDL request.
+ 66 """
+ 67self.CarrierCode='FDXE'
+ 68self.Origin=self.Destination=self.client.factory.create('Address')
+ 69self.ShipDate=datetime.date.today().isoformat()
+ 70self.Service=None
+ 71self.Packaging='YOUR_PACKAGING'
+
74"""
+ 75 Fires off the Fedex request.
+ 76
+ 77 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(),
+ 78 WHICH RESIDES ON FedexBaseService AND IS INHERITED.
+ 79 """
+ 80
+ 81# We get an exception like this when specifying an IntegratorId:
+ 82# suds.TypeNotFound: Type not found: 'IntegratorId'
+ 83# Setting it to None does not seem to appease it.
+ 84delself.ClientDetail.IntegratorId
+ 85self.logger.debug(self.WebAuthenticationDetail)
+ 86self.logger.debug(self.ClientDetail)
+ 87self.logger.debug(self.TransactionDetail)
+ 88self.logger.debug(self.VersionId)
+ 89# Fire off the query.
+ 90returnself.client.service.serviceAvailability(
+ 91WebAuthenticationDetail=self.WebAuthenticationDetail,
+ 92ClientDetail=self.ClientDetail,
+ 93TransactionDetail=self.TransactionDetail,
+ 94Version=self.VersionId,
+ 95Origin=self.Origin,
+ 96Destination=self.Destination,
+ 97ShipDate=self.ShipDate,
+ 98CarrierCode=self.CarrierCode,
+ 99Service=self.Service,
+100Packaging=self.Packaging)
+
This constructor should only be called by children of the class. As is
+ such, only the optional keyword arguments caught by **kwargs
+ will be documented.
+
+
Parameters:
+
+
config_obj (FedexConfig) - A valid FedexConfig object.
This package contains the shipping methods defined by Fedex's
+ CountryService WSDL file. Each is encapsulated in a class for easy
+ access. For more details on each, refer to the respective class's
+ documentation.
+ 1"""
+ 2Country Service Module
+ 3
+ 4This package contains the shipping methods defined by Fedex's
+ 5CountryService WSDL file. Each is encapsulated in a class for
+ 6easy access. For more details on each, refer to the respective class's
+ 7documentation.
+ 8"""
+ 9
+10importdatetime
+11from..base_serviceimportFedexBaseService
+12
+13
+
15"""
+16 This class allows you validate an address.
+17 https://www.fedex.com/us/developer/WebHelp/ws/2015/html/WebServicesHelp/WSDVG/47_Country_Service.htm
+18 """
+19
+
54"""
+55 Create the data structure and get it ready for the WSDL request.
+56 """
+57self.CarrierCode='FDXE'
+58self.RoutingCode='FDSD'
+59self.Address=self.client.factory.create('Address')
+60self.ShipDateTime=datetime.datetime.now().isoformat()
+
63"""
+64 Fires off the Fedex request.
+65
+66 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(),
+67 WHICH RESIDES ON FedexBaseService AND IS INHERITED.
+68 """
+69
+70# We get an exception like this when specifying an IntegratorId:
+71# suds.TypeNotFound: Type not found: 'IntegratorId'
+72# Setting it to None does not seem to appease it.
+73delself.ClientDetail.IntegratorId
+74self.logger.debug(self.WebAuthenticationDetail)
+75self.logger.debug(self.ClientDetail)
+76self.logger.debug(self.TransactionDetail)
+77self.logger.debug(self.VersionId)
+78# Fire off the query.
+79returnself.client.service.validatePostal(
+80WebAuthenticationDetail=self.WebAuthenticationDetail,
+81ClientDetail=self.ClientDetail,
+82TransactionDetail=self.TransactionDetail,
+83Version=self.VersionId,
+84Address=self.Address,
+85ShipDateTime=self.ShipDateTime,
+86CarrierCode=self.CarrierCode,
+87CheckForMismatch=self.CheckForMismatch,
+88RoutingCode=self.RoutingCode)
+
This constructor should only be called by children of the class. As is
+ such, only the optional keyword arguments caught by **kwargs
+ will be documented.
+
+
Parameters:
+
+
config_obj (FedexConfig) - A valid FedexConfig object.
+ 1"""
+ 2Package Movement Information Service
+ 3
+ 4This package contains classes to check service availability, route, and postal
+ 5codes. Defined by the PackageMovementInformationService WSDL file.
+ 6"""
+ 7importlogging
+ 8from..base_serviceimportFedexBaseService,FedexError
+ 9
+ 10
+
32"""
+ 33 Sets up an inquiry request. The optional keyword args
+ 34 detailed on L{FedexBaseService} apply here as well.
+ 35
+ 36 @type config_obj: L{FedexConfig}
+ 37 @param config_obj: A valid FedexConfig object
+ 38 @param postal_code: a valid postal code
+ 39 @param country_code: ISO country code to which the postal code belongs to.
+ 40 """
+ 41self._config_obj=config_obj
+ 42
+ 43# Holds version info for the VersionId SOAP object.
+ 44self._version_info={'service_id':'pmis','major':'4',
+ 45'intermediate':'0','minor':'0'}
+ 46self.PostalCode=postal_code
+ 47self.CountryCode=country_code
+ 48
+ 49# Call the parent FedexBaseService class for basic setup work.
+ 50super(PostalCodeInquiryRequest,self).__init__(self._config_obj,
+ 51'PackageMovementInformationService_v4.wsdl',
+ 52*args,**kwargs)
+
55"""
+ 56 Checks the response to see if there were any errors specific to
+ 57 this WSDL.
+ 58 """
+ 59ifself.response.HighestSeverity=="ERROR":
+ 60fornotificationinself.response.Notifications:# pragma: no cover
+ 61ifnotification.Severity=="ERROR":
+ 62if"Postal Code Not Found"innotification.Message:
+ 63raiseFedexPostalCodeNotFound(notification.Code,
+ 64notification.Message)
+ 65
+ 66elif"Invalid Postal Code Format"inself.response.Notifications:
+ 67raiseFedexInvalidPostalCodeFormat(notification.Code,
+ 68notification.Message)
+ 69else:
+ 70raiseFedexError(notification.Code,
+ 71notification.Message)
+
81"""
+ 82 Fires off the Fedex request.
+ 83
+ 84 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(), WHICH RESIDES
+ 85 ON FedexBaseService AND IS INHERITED.
+ 86 """
+ 87client=self.client
+ 88
+ 89# We get an exception like this when specifying an IntegratorId:
+ 90# suds.TypeNotFound: Type not found: 'IntegratorId'
+ 91# Setting it to None does not seem to appease it.
+ 92
+ 93delself.ClientDetail.IntegratorId
+ 94
+ 95# Fire off the query.
+ 96response=client.service.postalCodeInquiry(WebAuthenticationDetail=self.WebAuthenticationDetail,
+ 97ClientDetail=self.ClientDetail,
+ 98TransactionDetail=self.TransactionDetail,
+ 99Version=self.VersionId,
+100PostalCode=self.PostalCode,
+101CountryCode=self.CountryCode,
+102CarrierCode=self.CarrierCode)
+103
+104returnresponse
+
This package contains classes to request pre-ship rating information
+ and to determine estimated or courtesy billing quotes. Time in Transit
+ can be returned with the rates if it is specified in the request.
+ 1"""
+ 2Rate Service Module
+ 3
+ 4This package contains classes to request pre-ship rating information and to
+ 5determine estimated or courtesy billing quotes. Time in Transit can be
+ 6returned with the rates if it is specified in the request.
+ 7"""
+ 8
+ 9importdatetime
+ 10from..base_serviceimportFedexBaseService
+ 11
+ 12
+
14"""
+ 15 This class allows you to get the shipping charges for a particular address.
+ 16 You will need to populate the data structures in self.RequestedShipment,
+ 17 then send the request.
+ 18 """
+ 19
+
44"""
+ 45 This is the data that will be used to create your shipment. Create
+ 46 the data structure and get it ready for the WSDL request.
+ 47 """
+ 48
+ 49# Default behavior is to not request transit information
+ 50self.ReturnTransitAndCommit=False
+ 51
+ 52# This is the primary data structure for processShipment requests.
+ 53self.RequestedShipment=self.client.factory.create('RequestedShipment')
+ 54self.RequestedShipment.ShipTimestamp=datetime.datetime.now()
+ 55
+ 56# Defaults for TotalWeight wsdl object.
+ 57total_weight=self.client.factory.create('Weight')
+ 58# Start at nothing.
+ 59total_weight.Value=0.0
+ 60# Default to pounds.
+ 61total_weight.Units='LB'
+ 62# This is the total weight of the entire shipment. Shipments may
+ 63# contain more than one package.
+ 64self.RequestedShipment.TotalWeight=total_weight
+ 65
+ 66# This is the top level data structure for Shipper information.
+ 67shipper=self.client.factory.create('Party')
+ 68shipper.Address=self.client.factory.create('Address')
+ 69shipper.Contact=self.client.factory.create('Contact')
+ 70
+ 71# Link the ShipperParty to our master data structure.
+ 72self.RequestedShipment.Shipper=shipper
+ 73
+ 74# This is the top level data structure for Recipient information.
+ 75recipient_party=self.client.factory.create('Party')
+ 76recipient_party.Contact=self.client.factory.create('Contact')
+ 77recipient_party.Address=self.client.factory.create('Address')
+ 78# Link the RecipientParty object to our master data structure.
+ 79self.RequestedShipment.Recipient=recipient_party
+ 80
+ 81# Make sender responsible for payment by default.
+ 82self.RequestedShipment.ShippingChargesPayment=self.create_wsdl_object_of_type('Payment')
+ 83self.RequestedShipment.ShippingChargesPayment.PaymentType='SENDER'
+ 84
+ 85# Start with no packages, user must add them.
+ 86self.RequestedShipment.PackageCount=0
+ 87self.RequestedShipment.RequestedPackageLineItems=[]
+ 88
+ 89# This is good to review if you'd like to see what the data structure
+ 90# looks like.
+ 91self.logger.debug(self.RequestedShipment)
+
94"""
+ 95 Fires off the Fedex request.
+ 96
+ 97 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(),
+ 98 WHICH RESIDES ON FedexBaseService AND IS INHERITED.
+ 99 """
+100
+101# Fire off the query.
+102returnself.client.service.getRates(
+103WebAuthenticationDetail=self.WebAuthenticationDetail,
+104ClientDetail=self.ClientDetail,
+105TransactionDetail=self.TransactionDetail,
+106Version=self.VersionId,
+107RequestedShipment=self.RequestedShipment,
+108ReturnTransitAndCommit=self.ReturnTransitAndCommit)
+
111"""
+112 Adds a package to the ship request.
+113
+114 @type package_item: WSDL object, type of RequestedPackageLineItem
+115 WSDL object.
+116 @keyword package_item: A RequestedPackageLineItem, created by
+117 calling create_wsdl_object_of_type('RequestedPackageLineItem') on
+118 this ShipmentRequest object. See examples/create_shipment.py for
+119 more details.
+120 """
+121
+122self.RequestedShipment.RequestedPackageLineItems.append(package_item)
+123package_weight=package_item.Weight.Value
+124self.RequestedShipment.TotalWeight.Value+=package_weight
+125self.RequestedShipment.PackageCount+=1
+
This class allows you to get the shipping charges for a particular
+ address. You will need to populate the data structures in
+ self.RequestedShipment, then send the request.
package_item (WSDL object, type of RequestedPackageLineItem WSDL object.) - A RequestedPackageLineItem, created by calling
+ create_wsdl_object_of_type('RequestedPackageLineItem') on this
+ ShipmentRequest object. See examples/create_shipment.py for more
+ details.
This package contains the shipping methods defined by Fedex's
+ ShipService WSDL file. Each is encapsulated in a class for easy access.
+ For more details on each, refer to the respective class's
+ documentation.
+ 1"""
+ 2Ship Service Module
+ 3
+ 4This package contains the shipping methods defined by Fedex's
+ 5ShipService WSDL file. Each is encapsulated in a class for easy access.
+ 6For more details on each, refer to the respective class's documentation.
+ 7"""
+ 8
+ 9importdatetime
+ 10from..base_serviceimportFedexBaseService
+ 11
+ 12
+
14"""
+ 15 This class allows you to process (create) a new FedEx shipment. You will
+ 16 need to populate the data structures in self.RequestedShipment, then
+ 17 send the request. Label printing is supported and very configurable,
+ 18 returning an ASCII representation with the response as well.
+ 19 """
+ 20
+
45"""
+ 46 This is the data that will be used to create your shipment. Create
+ 47 the data structure and get it ready for the WSDL request.
+ 48 """
+ 49
+ 50# This is the primary data structure for processShipment requests.
+ 51self.RequestedShipment=self.client.factory.create('RequestedShipment')
+ 52self.RequestedShipment.ShipTimestamp=datetime.datetime.now()
+ 53
+ 54# Defaults for TotalWeight wsdl object.
+ 55total_weight=self.client.factory.create('Weight')
+ 56# Start at nothing.
+ 57total_weight.Value=0.0
+ 58# Default to pounds.
+ 59total_weight.Units='LB'
+ 60# This is the total weight of the entire shipment. Shipments may
+ 61# contain more than one package.
+ 62self.RequestedShipment.TotalWeight=total_weight
+ 63
+ 64# This is the top level data structure Shipper Party information.
+ 65shipper_party=self.client.factory.create('Party')
+ 66shipper_party.Address=self.client.factory.create('Address')
+ 67shipper_party.Contact=self.client.factory.create('Contact')
+ 68
+ 69# Link the Shipper Party to our master data structure.
+ 70self.RequestedShipment.Shipper=shipper_party
+ 71
+ 72# This is the top level data structure for RecipientParty information.
+ 73recipient_party=self.client.factory.create('Party')
+ 74recipient_party.Contact=self.client.factory.create('Contact')
+ 75recipient_party.Address=self.client.factory.create('Address')
+ 76
+ 77# Link the RecipientParty object to our master data structure.
+ 78self.RequestedShipment.Recipient=recipient_party
+ 79
+ 80payor=self.client.factory.create('Payor')
+ 81# Grab the account number from the FedexConfig object by default.
+ 82# Assume US.
+ 83payor.ResponsibleParty=self.client.factory.create('Party')
+ 84payor.ResponsibleParty.Address=self.client.factory.create('Address')
+ 85payor.ResponsibleParty.Address.CountryCode='US'
+ 86
+ 87# ShippingChargesPayment WSDL object default values.
+ 88shipping_charges_payment=self.client.factory.create('Payment')
+ 89shipping_charges_payment.Payor=payor
+ 90shipping_charges_payment.PaymentType='SENDER'
+ 91self.RequestedShipment.ShippingChargesPayment=shipping_charges_payment
+ 92
+ 93self.RequestedShipment.LabelSpecification=self.client.factory.create('LabelSpecification')
+ 94
+ 95# NONE, PREFERRED or LIST
+ 96self.RequestedShipment.RateRequestTypes=['PREFERRED']
+ 97
+ 98# Start with no packages, user must add them.
+ 99self.RequestedShipment.PackageCount=0
+100self.RequestedShipment.RequestedPackageLineItems=[]
+101
+102# This is good to review if you'd like to see what the data structure
+103# looks like.
+104self.logger.debug(self.RequestedShipment)
+
107"""
+108 This is very similar to just sending the shipment via the typical
+109 send_request() function, but this doesn't create a shipment. It is
+110 used to make sure "good" values are given by the user or the
+111 application using the library.
+112 """
+113
+114self.send_request(send_function=self._assemble_and_send_validation_request)
+
117"""
+118 Fires off the Fedex shipment validation request.
+119
+120 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL
+121 send_validation_request(), WHICH RESIDES ON FedexBaseService
+122 AND IS INHERITED.
+123 """
+124
+125# Fire off the query.
+126returnself.client.service.validateShipment(
+127WebAuthenticationDetail=self.WebAuthenticationDetail,
+128ClientDetail=self.ClientDetail,
+129TransactionDetail=self.TransactionDetail,
+130Version=self.VersionId,
+131RequestedShipment=self.RequestedShipment)
+
134"""
+135 Fires off the Fedex request.
+136
+137 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(),
+138 WHICH RESIDES ON FedexBaseService AND IS INHERITED.
+139 """
+140
+141# Fire off the query.
+142returnself.client.service.processShipment(
+143WebAuthenticationDetail=self.WebAuthenticationDetail,
+144ClientDetail=self.ClientDetail,
+145TransactionDetail=self.TransactionDetail,
+146Version=self.VersionId,
+147RequestedShipment=self.RequestedShipment)
+
150"""
+151 Adds a package to the ship request.
+152
+153 @type package_item: WSDL object, type of RequestedPackageLineItem
+154 WSDL object.
+155 @keyword package_item: A RequestedPackageLineItem, created by
+156 calling create_wsdl_object_of_type('RequestedPackageLineItem') on
+157 this ShipmentRequest object. See examples/create_shipment.py for
+158 more details.
+159 """
+160
+161self.RequestedShipment.RequestedPackageLineItems.append(package_item)
+162package_weight=package_item.Weight.Value
+163self.RequestedShipment.TotalWeight.Value+=package_weight
+164self.RequestedShipment.PackageCount+=1
+
173"""
+174 Deletes a shipment via a tracking number.
+175 """
+176
+177self._config_obj=config_obj
+178
+179# Holds version info for the VersionId SOAP object.
+180self._version_info={'service_id':'ship','major':'17',
+181'intermediate':'0','minor':'0'}
+182self.DeletionControlType=None
+183"""@ivar: Holds the DeletrionControlType WSDL object."""
+184self.TrackingId=None
+185"""@ivar: Holds the TrackingId WSDL object."""
+186# Call the parent FedexBaseService class for basic setup work.
+187super(FedexDeleteShipmentRequest,self).__init__(self._config_obj,
+188'ShipService_v17.wsdl',
+189*args,**kwargs)
+
192"""
+193 Preps the WSDL data structures for the user.
+194 """
+195
+196self.DeletionControlType=self.client.factory.create('DeletionControlType')
+197self.TrackingId=self.client.factory.create('TrackingId')
+198self.TrackingId.TrackingIdType=self.client.factory.create('TrackingIdType')
+
201"""
+202 Fires off the Fedex request.
+203
+204 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(), WHICH RESIDES
+205 ON FedexBaseService AND IS INHERITED.
+206 """
+207
+208client=self.client
+209# Fire off the query.
+210returnclient.service.deleteShipment(
+211WebAuthenticationDetail=self.WebAuthenticationDetail,
+212ClientDetail=self.ClientDetail,
+213TransactionDetail=self.TransactionDetail,
+214Version=self.VersionId,
+215ShipTimestamp=datetime.datetime.now(),
+216TrackingId=self.TrackingId,
+217DeletionControl=self.DeletionControlType)
+
customer_transaction_id - A user-specified identifier to differentiate this transaction
+ from others. This value will be returned with the response from
+ Fedex.
This class allows you to process (create) a new FedEx shipment. You
+ will need to populate the data structures in self.RequestedShipment, then
+ send the request. Label printing is supported and very configurable,
+ returning an ASCII representation with the response as well.
send_validation_request(self)
+ This is very similar to just sending the shipment via the typical
+ send_request() function, but this doesn't create a shipment.
This is very similar to just sending the shipment via the typical
+ send_request() function, but this doesn't create a shipment. It is used
+ to make sure "good" values are given by the user or the
+ application using the library.
package_item (WSDL object, type of RequestedPackageLineItem WSDL object.) - A RequestedPackageLineItem, created by calling
+ create_wsdl_object_of_type('RequestedPackageLineItem') on this
+ ShipmentRequest object. See examples/create_shipment.py for more
+ details.
This package contains the shipment tracking methods defined by Fedex's
+ TrackService WSDL file. Each is encapsulated in a class for easy access.
+ For more details on each, refer to the respective class's
+ documentation.
+ 1"""
+ 2Tracking Service Module
+ 3
+ 4This package contains the shipment tracking methods defined by Fedex's
+ 5TrackService WSDL file. Each is encapsulated in a class for easy access.
+ 6For more details on each, refer to the respective class's documentation.
+ 7"""
+ 8
+ 9from..base_serviceimportFedexBaseService,FedexError
+ 10
+ 11
+
21"""
+ 22 This class allows you to track shipments by providing a tracking
+ 23 number or other identifying features. By default, you
+ 24 can simply pass a tracking number to the constructor. If you would like
+ 25 to query shipments based on something other than tracking number, you will
+ 26 want to read the documentation for the L{__init__} method.
+ 27 Particularly, the tracking_value and package_identifier arguments.
+ 28 """
+ 29
+
61"""
+ 62 This sets the package identifier information. This may be a tracking
+ 63 number or a few different things as per the Fedex spec.
+ 64 """
+ 65
+ 66self.SelectionDetails=self.client.factory.create('TrackSelectionDetail')
+ 67
+ 68# Default to Fedex
+ 69self.SelectionDetails.CarrierCode='FDXE'
+ 70
+ 71track_package_id=self.client.factory.create('TrackPackageIdentifier')
+ 72
+ 73# Default to tracking number.
+ 74track_package_id.Type='TRACKING_NUMBER_OR_DOORTAG'
+ 75
+ 76self.SelectionDetails.PackageIdentifier=track_package_id
+
79"""
+ 80 Checks the response to see if there were any errors specific to
+ 81 this WSDL.
+ 82 """
+ 83ifself.response.HighestSeverity=="ERROR":# pragma: no cover
+ 84fornotificationinself.response.Notifications:
+ 85ifnotification.Severity=="ERROR":
+ 86if"Invalid tracking number"innotification.Message:
+ 87raiseFedexInvalidTrackingNumber(
+ 88notification.Code,notification.Message)
+ 89else:
+ 90raiseFedexError(notification.Code,notification.Message)
+
93"""
+ 94 Fires off the Fedex request.
+ 95
+ 96 @warning: NEVER CALL THIS METHOD DIRECTLY. CALL send_request(), WHICH RESIDES
+ 97 ON FedexBaseService AND IS INHERITED.
+ 98 """
+ 99
+100client=self.client
+101# Fire off the query.
+102returnclient.service.track(
+103WebAuthenticationDetail=self.WebAuthenticationDetail,
+104ClientDetail=self.ClientDetail,
+105TransactionDetail=self.TransactionDetail,
+106Version=self.VersionId,
+107SelectionDetails=self.SelectionDetails,
+108ProcessingOptions=self.ProcessingOptions)
+
This class allows you to track shipments by providing a tracking
+ number or other identifying features. By default, you can simply pass a
+ tracking number to the constructor. If you would like to query shipments
+ based on something other than tracking number, you will want to read the
+ documentation for the __init__ method. Particularly, the tracking_value and
+ package_identifier arguments.
This document contains the API (Application Programming Interface)
+documentation for this project. Documentation for the Python
+objects defined by the project is divided into separate pages for each
+package, module, and class. The API documentation also includes two
+pages containing information about the project as a whole: a trees
+page, and an index page.
+
+
Object Documentation
+
+
Each Package Documentation page contains:
+
+
A description of the package.
+
A list of the modules and sub-packages contained by the
+ package.
+
A summary of the classes defined by the package.
+
A summary of the functions defined by the package.
+
A summary of the variables defined by the package.
+
A detailed description of each function defined by the
+ package.
+
A detailed description of each variable defined by the
+ package.
+
+
+
Each Module Documentation page contains:
+
+
A description of the module.
+
A summary of the classes defined by the module.
+
A summary of the functions defined by the module.
+
A summary of the variables defined by the module.
+
A detailed description of each function defined by the
+ module.
+
A detailed description of each variable defined by the
+ module.
+
+
+
Each Class Documentation page contains:
+
+
A class inheritance diagram.
+
A list of known subclasses.
+
A description of the class.
+
A summary of the methods defined by the class.
+
A summary of the instance variables defined by the class.
+
A summary of the class (static) variables defined by the
+ class.
+
A detailed description of each method defined by the
+ class.
+
A detailed description of each instance variable defined by the
+ class.
+
A detailed description of each class (static) variable defined
+ by the class.
+
+
+
Project Documentation
+
+
The Trees page contains the module and class hierarchies:
+
+
The module hierarchy lists every package and module, with
+ modules grouped into packages. At the top level, and within each
+ package, modules and sub-packages are listed alphabetically.
+
The class hierarchy lists every class, grouped by base
+ class. If a class has more than one base class, then it will be
+ listed under each base class. At the top level, and under each base
+ class, classes are listed alphabetically.
+
+
+
The Index page contains indices of terms and
+ identifiers:
+
+
The term index lists every term indexed by any object's
+ documentation. For each term, the index provides links to each
+ place where the term is indexed.
+
The identifier index lists the (short) name of every package,
+ module, class, method, function, variable, and parameter. For each
+ identifier, the index provides a short description, and a link to
+ its documentation.
+
+
+
The Table of Contents
+
+
The table of contents occupies the two frames on the left side of
+the window. The upper-left frame displays the project
+contents, and the lower-left frame displays the module
+contents:
+
+
+
+
+ Project Contents...
+
+ API Documentation Frame
+
+
+
+
+ Module Contents ...
+
+
+
+
+
The project contents frame contains a list of all packages
+and modules that are defined by the project. Clicking on an entry
+will display its contents in the module contents frame. Clicking on a
+special entry, labeled "Everything," will display the contents of
+the entire project.
+
+
The module contents frame contains a list of every
+submodule, class, type, exception, function, and variable defined by a
+module or package. Clicking on an entry will display its
+documentation in the API documentation frame. Clicking on the name of
+the module, at the top of the frame, will display the documentation
+for the module itself.
+
+
The "frames" and "no frames" buttons below the top
+navigation bar can be used to control whether the table of contents is
+displayed or not.
+
+
The Navigation Bar
+
+
A navigation bar is located at the top and bottom of every page.
+It indicates what type of page you are currently viewing, and allows
+you to go to related pages. The following table describes the labels
+on the navigation bar. Note that not some labels (such as
+[Parent]) are not displayed on all pages.
+
+
+
+
Label
+
Highlighted when...
+
Links to...
+
+
[Parent]
+
(never highlighted)
+
the parent of the current package
+
[Package]
+
viewing a package
+
the package containing the current object
+
+
[Module]
+
viewing a module
+
the module containing the current object
+
+
[Class]
+
viewing a class
+
the class containing the current object
+
[Trees]
+
viewing the trees page
+
the trees page
+
[Index]
+
viewing the index page
+
the index page
+
[Help]
+
viewing the help page
+
the help page
+
+
+
The "show private" and "hide private" buttons below
+the top navigation bar can be used to control whether documentation
+for private objects is displayed. Private objects are usually defined
+as objects whose (short) names begin with a single underscore, but do
+not end with an underscore. For example, "_x",
+"__pprint", and "epydoc.epytext._tokenize"
+are private objects; but "re.sub",
+"__init__", and "type_" are not. However,
+if a module defines the "__all__" variable, then its
+contents are used to decide which objects are private.
+
+
A timestamp below the bottom navigation bar indicates when each
+page was last updated.
fedex.printers.unix: This module provides a label printing wrapper class for Unix-based
+ installations.
+
+
+
fedex.services: This module contains the wrappers around Fedex Web Service requests
+ which you will want to instantiate and use with a FedexConfig object supplying your static details.
+
When javascript is enabled, this page will redirect URLs of
+the form redirect.html#dotted.name to the
+documentation for the object with the given fully-qualified
+dotted name.