-
Notifications
You must be signed in to change notification settings - Fork 4
Plumage is a module, available for Pyton or .Net (C#, VisualBasic .Net, C++/CLI) to allow easy access to the U.S. Patent and Trademark Office's Trademark Status & Document Retrieval (TSDR) system.
Plumage uses the USPTO's TSDR Data API. Beginning October 2, 2020, the USPTO requires that you register and obtain an API key to use the API, including via Plumage. This requirement is imposed by the USPTO, not by Plumage, although Plumage includes support for the API key.
The documentation below covers both the Python implementation (Plumage-py) and the .NET implmentation (Plumage-dotnet, written in C#). The .NET implmentation is intneded to support any .NET langage. For VisualBasic .NET and C++/CLI, see the Basic examples and adjust accordingly. F# support has not been tested, but is believed to work.
The phrase "None
/null
" when used below refers to None
in Plumage-py and null
in Plumage-dotnet.
The module defines the following items:
class plumage.TSDRReq
The class that is used to initiate a TSDR request to the USPTO server. After invoking a TSDR call, it includes a TSDRMap object that provides information about the specified trademark registration or application. See section TSDRReq for a description.
class plumage.TSDRMap
The class that encapsulates the parsed information from a TSDR query. See section TSDRMap for a description of its contents.
To use Plumage, first create a TSDRReq
object as follows.
Plumage-py:
t = plumage.TSDRReq()
Plumage-dotnet (C#; see Basic examples for other .NET languages):
Plumage.TSDRReq t = new Plumage.TSDRReq();
The resulting TSDRReq
object t
can then be used to obtain data from the PTO. Typically, the only methods needed are SetAPIKey (to specify the API key used by TSDR to validate the request); getTSDRInfo (to actually make the TSDR request); and possibly setPTOFormat (if you need ZIP or image data), SetIntervalTime (to change the length of pauses between TSDR calls if fetching ZIP files); and GetMetainfo (to get information, such as release-level, about Plumage). Other methods are provided to provide for more specific control, but normally will not be needed.
TSDRReq provides the following methods.
t.getTSDRInfo(identifier[, tmtype])
- Call TSDR to get information associated with the trademark record indicated and provide a TSDRMap object with dictionaries of data about the mark
- identifier: a string of digits identifying the number of trademark record to be retrieved.
-
tmtype: a one-character string indicating what type of trademark record is requested:
- 's': the
identifier
is a string of eight digits identifying the application serial number of the record to be retrieved. For example, to obtain information on application ser. no 75/181,334, usegetTSDRInfo("75181334", "s")
. - 'r': the
identifier
is a string of seven digits identifying the registration number of the record to be retrieved. For example, to obtain information on registration no. 2,564,831, usegetTSDRInfo("2564831", "r")
.
- 's': the
- If
tmtype
is not specified, identifier is the name of a local file that will be read instead of making a call to TSDR. This option is normally used only for development and testing. -
t.getTSDRInfo()
sets the following fields:XMLData
,XMLDataIsValid
,CSVData
,CSVDataIsValid
,TSDRData
,TSDRDataIsValid
,ErrorCode
andErrorMessage
. In addition, ifsetPTOFormat("ZIP")
was specified, it also setsZipData
, as well asImageThumb
andImageFull
if data for those images is present in the ZIP file provided by the USPTO. - If there are errors, not all fields may be set. The fields
XMLDataIsValid
,CSVDataIsValid
andTSDRDataIsValid
may be used to determine which data fields have been reliably set. -
getTSDRInfo
is the standard way of using Plumage; Other then a one-time call tosetAPIKey
,getTSDRInfo
will nearly always be the only method you will need to call after creating theTSDRReq
object. - For those interested in the details,
t.getTSDRInfo()
is equivalent to the following pseudocode:
t.getXMLData(identifier, tmtype) # Fetch the XML from the PTO
if t.XMLDataIsValid
t.getCSVData() # Parse the XML into key-value comma-separated values
if t.CSVDataIsValid
t.getTSDRData() # Convert the key-value pairs to dictionaties
t.getXMLData(identifier[, tmtype])
- Only call TSDR to get the XML or ZIP file associated with the trademark record indicated; no TSDRMap is provided
- identifier: a string of digits identifying the number of trademark record to be retrieved.
-
tmtype: a one-character string indicating what type of trademark record is requested:
- 's': the
identifier
is a string of eight digits identifying the application serial number of the record to be retrieved. For example, to obtain information on application ser. no 75/181,334, usegetTSDRInfo("75181334", "s")
. - 'r': the
identifier
is a string of seven digits identifying the registration number of the record to be retrieved. For example, to obtain information on registration no. 2,564,831, usegetTSDRInfo("2564831", "r")
.
- 's': the
- If
tmtype
is not specified, identifier is the name of a local file that will be read instead of making a call to TSDR. This option is normally used only for development and testing. -
getXMLData
sets the following fields:XMLData
,XMLDataIsValid
,ErrorCode
andErrorMessage
. In addition, ifsetPTOFormat("ZIP")
was specified, it also setsZipData
, as well asImageThumb
andImageFull
if data for those images is present in the ZIP file provided by the USPTO. -
getXMLData
is usually not called directly. Generally, you should usegetTSDRInfo
instead. You might want to usegetXMLData
if, for example, you want only the XML data or the trademark image; or if you need to modify the XML data prior to its parsing.
t.getCSVData()
- Parse the XML previously obtained via
getXMLData
into key-value pairs expressed as comma-separated values. -
getCSVData
requires thatgetXMLData
have been previously called, that theXMLData
field contains valid PTO-formatted XML, and thatXMLDataIsValid
be set toTrue
-
getCSVData
sets the following fields:CSVData
,CSVDataIsValid
,ErrorCode
andErrorMessage
. -
getCSVData
is usually not called directly.
t.getTSDRData()
- Transform the
CSVData
key-value pairs into aTSDRData
object. -
getTSDRData
requires thatgetCSVData
have been previously called, that theCSVData
field consists of valid CSV-formatted key-value pairs, and thatCSVDataIsValid
be set toTrue
-
getTSDRData
sets the following fields:TSDRData
,TSDRDataIsValid
,ErrorCode
andErrorMessage
. -
getTSDRData
is usually not called directly.
t.reset()
- Reset the TSDRReq object
t
to an initial state. All values previously set, whether by a TDSRReqsetXXXX
method or by calling TSDR, are cleared. Callingt.reset()
is equivalent to the following sequence:t.resetAPIKey()
t.resetXSLT()
t.resetPTOFormat()
t.resetXMLData()
t.setAPIKey(key)
- key: The 16-character API key obtained from the USPTO
- Specify the API key TSDR will use to validate the request. Under current USPTO poilicy, calls to TSDR will be rejected unless the API key is set prior to the call.
t.resetAPIKey()
- Reset the API key, i.e. as is no
setAPIKey
had ever been called. Under current USPTO policy, subsequent calls to TSDR will be rejected.
t.setPTOFormat(format_name)
- format_name: a string specifying the format in which TSDR is to return data. Three values are supported:
- If not set, "ST96" is assumed.
- Note that the USPTO imposes tighter limits on ZIP file retrievals (4/minute) than straight XML (whether ST.66 or ST.96) retrievals (60/minute). Unless you require access to image data, it is generally better to stay with the default ST.96.
t.resetPTOFormat()
- Reset the the format in which TSDR is to return data, i.e., to the default ST.96 schema.
t.setXSLT(xslt_template)
- xslt_template: a string of XSLT used to parse PTO-provided XML into key-pair sets. If not set, Plumage will determine which of the appropriate XSLT templates, provided as part of Plumage, should be used be used.
- This method may be useful if you need to access some data that Plumage's pre-supplied XSLT templates do not extract from the PTO XML. It enables you to roll-your-own XSLT if the pre-supplied templates are insufficient for your needs. It can also be used to substitute replacement transforms if the PTO changes XML data formats and the supplied transforms no longer work correctly.
t.resetXSLT()
- Reset the XSLT used to parse the XML returned by TSDR, if previously set. Plumage will use one of the XSLT templates provided as part of Plumage.
t.resetCSVData()
- Reset the CSV data, if any, previously parsed from XML obtained from TSDR, as well as any data derived from or associated with it. Specifically, resetCSVData does the following:
- The field
CSVData
is set toNone
/null
- The field
CSVDataIsValid
is set toFalse
; - resetTSDRData() is called to perform further action to clear the TSDRMap derived from the parsed CSV data, and associated data.
- The field
t.resetTSDRData()
- Resets the
TSDRData
field to an empty TSDRMap object:- The fields
TSDRSingle
andTSDRMulti
are set toNone
/null
; - The field
TSDRMapIsValid
is set toFalse
.
- The fields
t.resetXMLData()
- Reset the data (XML and/or ZIP file), if any, previously obtained from TSDR, as well as any data derived from or associated with it. Specifically resetXMLData does the following:
- The fields
XMLData
,ZipData
,ImageFull
,ImageThumb
,ErrorCode
andErrorCode
are set toNone
/null
; - The field
XMLDataIsValid
is set toFalse
; - resetCSVData() is called to perform further action to clear any CSV data derived from the XML data.
- The fields
t.SetIntervalTime(interval)
- Sets the amount of time that Plumage will ensure passes between TSDR calls.
- interval is a floating-point number or integer, in seconds
- If you use
setPTOFormat("ZIP")
to request zip files, you should also useSetIntervalTime(15)
to specify a 15-second interval, because the PTO limits ZIP fetches to 4/minute. - Plumage will ensure that the specified amount of time has elapsed between calls to TSDR, to ensure that a sequence of calls stays within PTO-imposed limits. It will minimise the pause to the amount of time needed, or eliminate it entirely. For example, suppose a program need to present trademark image files to a user, which requires
setPTOFormat("ZIP")
, You useSetIntervalTime(15)
to indicate that calls to TSDR should be saparated by 15 seconds. Suppose your program usesgetTSDRInfo
and then displays the fetched image, and the user takes five seconds to review the image before the program continues with the next TSDR fetch. Plumage will wait only 10 seconds, not the full fifteen seconds; the five seconds that elapsed while the image was reviewed by the user is part of the time elapsed between calls. If the user spent more than fifteen seconds, Plumage will not pause at all, since the full fifteen-second interval would have elapsed without requiring additional pause.
t.GetIntervalTime()
- Return the current value of the required interval between TSDR calls, in seconds (Python: type
float
; .NET: typedouble
).
t.ResetIntervalTime()
- Reset the value of the required interval between TSDR calls tp the default value (1.0 seconds)
The TSDRReq object t
includes several data members. The one most often used is t.TSDRData, which contains the data retrieved from TSDR. The following data members exist:
t.CSVData
- A
string
containing key/value pairs from TSDR, represented as comma-separated values, derived from XMLData. CSVData The string consists of a series of lines, each consisting of a key and its corresponding value. The key is an alphanumeric string, and the value is a string surrounded by double-quotes. The key and value are separated by a comma, with no spaces on the line, other than within the quote marks. Some examples:
RegistrationNumber,"2564831"
ApplicationNumber,"75181334"
MarkVerbalElementText,"MONTY PYTHON'S FLYING CIRCUS"
ApplicationDate,"1996-10-15"
ApplicantName,"Python (Monty) Pictures Ltd."
In the case of recurring fields, a given set of fields is immediately preceded by the key 'BeginRepeatedField' and a value indicating the type pf field being repeated; and immediately followed by the key 'EndRepeatedField' and the same value as for 'BeginRepeatedField'. For example, each one of a series of MarkEvents will appear as follows:
BeginRepeatedField,"MarkEvent"
RawMarkEventDate,"2002-02-05-05:00"
MarkEventDate,"2002-02-05"
MarkEventDescription,"PUBLISHED FOR OPPOSITION"
MarkEventEntryNumber,"19"
EndRepeatedField,"MarkEvent"
The format of this data is intended to allow it to be loaded into most programs that accept comma-separated-value data, e.g. the Open Document Foundation's LibreOffice or Microsoft Excel. However, its primary use is as an intermediate format transformed from XML, before being converted to a native dictionary. (I would appreciate bug reports if any incompatibilities with CSV-supporting programs are found, however.)
t.CSVDataIsValid
- A boolean value indicating whether the CSVData field was reliably created.
t.ErrorCode
- A short
string
containing a code indicating cause of error, if any; orNone
/null
if no error condition exists. It is intended to be interrogated by the invoking program. This field is discussed in more detail in Errors and exceptions.
t.ErrorMessage
- A longer
string
containing a human-readable description of error, if any; orNone
/null
if no error condition exists. It is intended to provide a meaningful description of the error condition. This field is discussed in more detail in Errors and exceptions.
t.ImageFull
- A binary representation of the full-size image of the mark, if any, in the format provided by TSDR; or
None
/null
if no image data is present - The data is represented as type
bytes
(Python) orbyte[]
array (.NET) . -
ImageFull is set only if the TSDR data was obtained with
setPTOFormat("zip")
. It is the contents of themarkImage.jpg
member of the retrieved Zip file. - Empirical tests indicate that TSDR provides this data in PNG format (despite the zip file member having a ".jpg" suffix).
t.ImageThumb
- A binary representation of the thumbnail-size image of the mark, if any, in the format provided by TSDR; or
None
/null
if no image data is present - The data is represented as type
bytes
(Python) orbyte[]
array (.NET) . -
ImageThumb is set only if the TSDR data was obtained with
setPTOFormat("zip")
. It is the contents of themarkThumbnailImage.jpg
member of the retrieved Zip file. - Empirical tests indicate that TSDR provides this data in JPEG format.
t.TSDRData
- a TSDRMap object containing data about the reported trademark registration or application. See TSDRMap .
t.XMLData
- A string with the XML pertaining to the reported trademark registration or application, as provided by TSDR.
t.XMLDataIsValid
- A boolean value indicating whether the XMLData field was reliably created.
t.ZipData
- A binary representation of the Zip file returned by TSDR, if any, in the format provided by TSDR; or
None
/null
if no Zip data is present. This field is set only if the TSDR data was obtained withsetPTOFormat("zip")
.
The TSDRMap object contains the data associated with the trademark regsitration or application for which TSDR is queried.
TSDRMapIsValid
- A boolean value indicating whether the TSDRSingle and TSDRMulti fields was reliably created.
TSDRSingle
- TSDRSingle is a dictionary of attributes that at any one time consists of only one single value for a particular trademark. For example, when an trademark application is filed, the USPTO assigns an application serial number to the application. There is only one application number. The key "ApplicationNumber" has a correponding value, which is a string containing the application serial number of the trademark bout which TSDR is being queried.
- In Python, TSDRSingle is a dictionary, each key of which is a
string
, and each corresponding value of which is anotherstring
. In .Net, the same format is used; it is formally declared asDictionary<string, string>
.
TSDRMulti
- TSDRMulti is a dictionary of lists of dictionaries, each of which consists of key-value pairs. TSDRMulti is used where there are (or could be) multiple instances of the same attribute. For example, a trademark may have more than one class identifying the types of goods and services associated with it. This means that there is no one "class" associated with the mark, and the assocaited class(es) cannot necessarily be be represented by a single value.
- In Python, TSDRMulti is a dictionary, each key of which is a string, and each value of which is a list of dictionaries. Each of those dictionaries represents one of the multiple values that are associated with the mark.
- In .Net, the same format is used; it is formally declared as
Dictionary<string, List<Dictionary<string, string>>>
. - By convention, every top-level key in TSDRMulti ends with the characters "List". As of Plumage 1.4. TSDRMulti contains the following keys:
MarkEventList
,ApplicantList
,InternationalClassDescriptionList
,DomesticClassDescriptionList
FirstUseDateList
andAssignmentList
.
The TSDRMap object, with detail on both TSDRSingle and TSDRMulti, is detailed at TSDRData contents.
For a graphic representation of a typical TSDRSingle and TSDRMulti, see the example in the documentation for TSDR2JSON, an open-source program that uses Plumage to display information about a particular mark in JSON format.