Пример #1
0
    def expiration(self) -> Optional[Expiration]:
        """Calculates expiration data from which the expiration date can be calculated. See
        help information for the resulting Expiration model.
        """
        if "PCT" in self.appl_id:
            raise NotImplementedError(
                "Expiration date not supported for PCT Applications")
        if not self.patent_number:
            return None
        expiration_data = dict()
        term_parents = [
            p for p in self.parent_continuity if p.relationship not in [
                "Claims Priority from Provisional Application",
                "is a Reissue of"
            ]
        ]
        if term_parents:
            term_parent = sorted(term_parents,
                                 key=lambda x: x.parent_app_filing_date)[0]
            relationship = term_parent.relationship
            parent_filing_date = term_parent.parent_app_filing_date
            parent_appl_id = term_parent.parent_appl_id
        else:
            relationship = "self"
            parent_appl_id = self.appl_id
            parent_filing_date = self.app_filing_date

        expiration_data["parent_appl_id"] = parent_appl_id
        expiration_data["parent_app_filing_date"] = parent_filing_date
        expiration_data["parent_relationship"] = relationship
        expiration_data["initial_term"] = parent_filing_date + relativedelta(
            years=20)  # type: ignore
        expiration_data[
            "pta_or_pte"] = self.pta_pte_summary.total_days if self.pta_pte_summary else 0  # type: ignore
        expiration_data[
            "extended_term"] = expiration_data["initial_term"] + relativedelta(
                days=expiration_data["pta_or_pte"])  # type: ignore

        transactions = self.transactions
        try:
            disclaimer = next(t for t in transactions if t.code == "DIST")
            expiration_data["terminal_disclaimer_filed"] = True
        except StopIteration:
            expiration_data["terminal_disclaimer_filed"] = False

        return Expiration(**expiration_data)  # type: ignore

        assignments = one_to_many("patent_client.uspto.assignment.Assignment",
                                  appl_id="appl_id")
        """Related Assignments from the Assignments API"""
        trials = one_to_many("patent_client.uspto.ptab.PtabProceeding",
                             appl_id="appl_id")
        """Related PtabProceedings for this application"""
Пример #2
0
class InpadocPriorityClaim(Inpadoc):
    children = one_to_many(
        "patent_client.epo.inpadoc.model.Inpadoc", priority_claim="num"
    )
    biblio = one_to_one(
        "patent_client.epo.inpadoc.model.InpadocBiblio", application="num"
    )
Пример #3
0
class PtabProceeding(Model):
    """A PTAB Proceeding - e.g. IPR/CBM/DER Trial, Patent Appeal, Interference, etc.

    All fields are query-able. Date ranges can be formed by inserting "from" or "to" on a query
    for a date range.

    """

    __manager__ = "patent_client.uspto.ptab.manager.PtabProceedingManager"
    subproceeding_type_category: str
    proceeding_number: str
    proceeding_status_category: str
    proceeding_type_category: str

    # Party Information
    appl_id: str = field(repr=False)
    respondent_party_name: str = field(default=None)
    petitioner_counsel_name: Optional[str] = field(default=None, repr=False)
    petitioner_party_name: Optional[str] = field(default=None, repr=False)
    respondent_counsel_name: Optional[str] = field(default=None, repr=False)
    respondent_patent_owner_name: Optional[str] = field(default=None,
                                                        repr=False)

    # Application Information
    inventor: Optional[str] = field(default=None, repr=False)
    patent_number: Optional[str] = field(default=None, repr=False)
    respondent_technology_center_number: Optional[str] = field(default=None,
                                                               repr=False)
    respondent_grant_date: Optional[datetime.date] = field(default=None,
                                                           repr=False)
    accorded_filing_date: Optional[datetime.date] = field(default=None,
                                                          repr=False)
    decision_date: Optional[datetime.date] = field(default=None, repr=False)
    institution_decision_date: Optional[datetime.date] = field(default=None,
                                                               repr=False)
    proceeding_filing_date: Optional[datetime.date] = field(default=None,
                                                            repr=False)

    documents = one_to_many("patent_client.uspto.ptab.PtabDocument",
                            proceeding_number="proceeding_number")
    """Documents associated with the Proceeding"""
    decisions = one_to_many("patent_client.uspto.ptab.PtabDecision",
                            proceeding_number="proceeding_number")
    """Decisions associated with the Proceeding"""
    us_application = one_to_one("patent_client.uspto.peds.Application",
                                appl_id="appl_id")
    """The US Application provided by PEDS associated with the Proceeding"""
Пример #4
0
class ITCInvestigation(Model):
    __manager__ = "patent_client.usitc.manager.ITCInvestigationManager"
    number: str
    phase: str
    status: str
    title: str
    type: str
    docket_number: str = dc.field(default=None)
    documents = one_to_many("patent_client.ITCDocument",
                            investigation_number="number")
Пример #5
0
class PublishedApplication(Publication):
    __manager__ = "patent_client.uspto.fulltext.published_application.manager.PublishedApplicationManager"
    forward_citations = one_to_many(
        "patent_client.uspto.fulltext.patent.model.Patent",
        referenced_by="publication_number",
    )
    images = one_to_one(
        "patent_client.uspto.fulltext.published_application.model.PublishedApplicationImage",
        publication_number="publication_number",
    )

    def __repr__(self):
        return f"{self.__class__.__name__}(publication_number={self.publication_number}, publication_date={self.publication_date.isoformat()}, title={self.title})"
Пример #6
0
class ITCDocument(Model):
    __manager__ = "patent_client.usitc.manager.ITCDocumentManager"
    id: int
    investigation_number: str
    type: str
    title: str
    security: str
    filing_party: str
    filed_by: str
    filed_on_behalf_of: str
    action_jacket_control_number: str
    memorandum_control_number: str
    date: dt.date
    last_modified: dt.date

    investigation = one_to_one("patent_client.ITCInvestigation",
                               investigation_number="investigation_number")
    attachments = one_to_many("patent_client.ITCAttachment", document_id="id")
Пример #7
0
class USApplication(Model):
    """
    US Application
    ==============
    This object wraps a US Application obtained from the Patent Examination Data System (https://peds.uspto.gov)
    
    -------------------------
    To Fetch a US Application
    -------------------------
    The main way to create a US Application is by querying the US Application manager at USApplication.objects

        USApplication.objects.filter(query) -> obtains multiple matching applications
        USApplication.objects.get(query) -> obtains a single matching application, errors if more than one is retreived

    The query can either be a single number, which is treated like an application number, or a keyword argument:
    
        USApplication.objects.get("15123456") -> Retreives US Application # 15123456
        USApplication.objects.get(patent_number="6103599") -> Retreives the US Application which issued as US Patent 6103599

    All arguments can be specified multiple times:
    
        USApplication.objects.get("15123456", "15123457") -> Retreives US Applications 15123456 and 15123457
        USApplication.objects.get(patent_number=['6103599', '6103600']) -> Retreives the US Applications which issued as US Patents 6103599 and 6103600

    NOTE: All keyword arguments are repeated by placing them in a list, but application numbers can be repeated as non-keyword arguments

    Date queries are made as strings in ISO format - YYYY-MM-DD (e.g. 2019-02-01 for Feb. 1, 2019)
    
    The complete list of available query fields is at USApplication.objects.fields

    --------------
    Using the Data
    --------------
    Data retreived from the US Patent Examination Data System is populated as attributes on the US Application object.
    A complete list of available fields is at USApplication.attrs. All the data can be retreived as a Python dictionary
    by calling USApplication.dict()

    There are also several composite data types available from a US Application, including:

        app.transaction_history -> list of transactions (filings, USPTO actions, etc.) involving the application
        app.children -> list of child applications
        app.parents -> list of parent applications
        app.pta_pte_history -> Patent Term Adjustment / Extension Event History
        app.pta_pte_summary -> Patent Term Adjustment / Extension Results, including total term extension
        app.correspondent -> Contact information for prosecuting law firm
        app.attorneys -> List of attorneys authorized to take action in the case
        app.expiration -> Patent Expiration Data (earliest non-provisional US parent + 20 years + extension and a flag for the presnce of a Terminal Disclaimer)

    Each of these also attaches data as attributes to the objects, and implements a .dict() method.

    ------------
    Related Data
    ------------
    A US Application is also linked to other resources avaialble through patent_client, including:
    
        app.trials -> list of PTAB trials involving this application
        app.inpadoc -> list to corresponding INPADOC objects (1 for each publication)
            HINT: inpadoc family can be found at app.inpadoc[0].family
        app.assignments -> list of assignments that mention this application

    Also, related US Applications can be obtained through their relationship:

    app.children[0].application -> a new USApplication object for the first child. 

    """
    objects = USApplicationManager()
    trials = one_to_many("patent_client.PtabTrial",
                         patent_number="patent_number")
    inpadoc = one_to_many("patent_client.Inpadoc", number="appl_id")
    assignments = one_to_many("patent_client.Assignment", appl_id="appl_id")
    attrs = [
        'appl_id', 'applicants', 'app_filing_date', 'app_exam_name',
        'inventors', 'app_early_pub_number', 'app_early_pub_date',
        'app_location', 'app_grp_art_number', 'patent_number',
        'patent_issue_date', 'app_status', 'app_status_date', 'patent_title',
        'app_attr_dock_number', 'first_inventor_file', 'app_type',
        'app_cust_number', 'app_cls_sub_cls', 'corr_addr_cust_no',
        'app_entity_status', 'app_confr_number', 'transaction_history',
        'children', 'parents', 'foreign_priority_applications',
        'pta_pte_history', 'pta_pte_summary', 'correspondent', 'attorneys'
    ]

    @property
    def publication(self):
        if self.patent_number:
            return "US" + self.patent_number
        else:
            return self.app_early_pub_number

    @property
    def expiration(self):
        expiration_data = dict()
        term_parents = [
            p for p in self.parents if p.relationship not in [
                'Claims Priority from Provisional Application',
                'is a Reissue of'
            ]
        ]
        if term_parents:
            term_parent = sorted(term_parents, key=lambda x: x.filing_date)[0]
        else:
            term_parent = self

        expiration_data['parent_appl_id'] = term_parent.appl_id
        expiration_data['parent_app_filing_date'] = term_parent.app_filing_date
        expiration_data['parent_relationship'] = getattr(
            term_parent, 'relationship', 'self')
        expiration_data[
            '20_year_term'] = term_parent.app_filing_date + relativedelta(
                years=20)
        expiration_data['pta_or_pte'] = self.pta_pte_summary.total_days
        expiration_data['extended_term'] = expiration_data[
            '20_year_term'] + relativedelta(days=expiration_data['pta_or_pte'])

        transactions = self.transaction_history
        try:
            disclaimer = next(t for t in transactions if t.code == 'DIST')
            expiration_data['terminal_disclaimer_filed'] = True
        except StopIteration:
            expiration_data['terminal_disclaimer_filed'] = False

        return expiration_data

    @property
    def transaction_history(self):
        return list(
            sorted((Transaction(d)
                    for d in self.data.get('transactions', list())),
                   key=lambda x: x.date))

    @property
    def children(self):
        return [
            Relationship(d, base_app=self)
            for d in self.data.get('child_continuity', list())
        ]

    @property
    def parents(self):
        return [
            Relationship(d, base_app=self)
            for d in self.data.get('parent_continuity', list())
        ]

    @property
    def foreign_priority_applications(self):
        return [
            ForeignPriority(d)
            for d in self.data.get('foreign_priority', list())
        ]

    @property
    def pta_pte_history(self):
        return list(
            sorted((PtaPteHistory(d)
                    for d in self.data.get('pta_pte_tran_history', list())),
                   key=lambda x: x.number))

    @property
    def pta_pte_summary(self):
        return PtaPteSummary(self.data)

    @property
    def correspondent(self):
        return Correspondent(self.data)

    @property
    def attorneys(self):
        return list(Attorney(d) for d in self.data.get('attrny_addr', list()))

    def __repr__(self):
        return f"<USApplication(appl_id={self.appl_id})>"
Пример #8
0
class Assignment(Model):
    """
    Assignments
    ===========
    This object wraps the USPTO Assignment API (https://assignments.uspto.gov)

    ----------------------
    To Fetch an Assignment
    ----------------------
    The main way to create an Assignment is by querying the Assignment manager at Assignment.objects

    Assignment.objects.filter(query) -> obtains multiple matching applications
    Assignment.objects.get(query) -> obtains a single matching application, errors if more than one is retreived

    The query can either be a single number, which is treated as a reel/frame number (e.g. "123-1321"), or a keyword.
    Available query types are: 
        patent_number, 
        appl_id (application #), 
        app_early_pub_number (publication #), 
        assignee,
        assignor,
        pct_number (PCT application #),
        correspondent,
        reel_frame

    --------------
    Using the Data
    --------------
    An Assignment object has the following properties:
        id (reel/frame #)
        attorney_dock_num
        conveyance_text
        last_update_date
        page_count
        recorded_date
        correspondent
        assignees
        assignors
        properties

    Additionally, the original assignment document can be downloaded to the working directory by calling:

    assignment.download()
    
    ------------
    Related Data
    ------------
    An Assignment is also linked to other resources available through patent_client. 
    A list of all assigned applications is available at:

    assignment.us_applications

    Additionally, each property entry in properties links to the corresponding application at:

    assignment.properties[0].us_application


    """

    primary_key = "reel_frame"
    attrs = [
        "id",
        "attorney_dock_num",
        "conveyance_text",
        "last_update_date",
        "page_count",
        "recorded_date",
        "correspondent",
        "assignors",
        "assignees",
        "properties",
        "image_url",
    ]
    objects = AssignmentManager()
    us_applications = one_to_many("patent_client.USApplication",
                                  appl_id="appl_num")

    def __repr__(self):
        return f"<Assignment(id={self.id})>"

    @property
    def properties(self):
        data = self.data
        properties = list()
        if isinstance(data['appl_num'], list):
            for i in range(len(data["appl_num"])):
                properties.append({
                    "appl_id":
                    data["appl_num"][i],
                    "app_filing_date":
                    data["filing_date"][i],
                    "patent_number":
                    data["pat_num"][i],
                    "pct_number":
                    data["pct_num"][i],
                    "intl_publ_date":
                    datetime.datetime.strptime(data["intl_publ_date"][i],
                                               "%Y-%m-%d").date()
                    if data["intl_publ_date"][i] else None,
                    "intl_reg_num":
                    data["intl_reg_num"][i],
                    "app_early_pub_date":
                    datetime.datetime.strptime(data["publ_date"][i],
                                               "%Y-%m-%d").date()
                    if data["publ_date"][i] else None,
                    "app_early_pub_number":
                    data["publ_num"][i],
                    "patent_issue_date":
                    data["issue_date"][i],
                    "patent_title":
                    data["invention_title"][i],
                    "patent_title_lang":
                    data["invention_title_lang"][i],
                    "inventors":
                    data["inventors"][i],
                })
        else:
            properties.append({
                "appl_id":
                data["appl_num"],
                "app_filing_date":
                data["filing_date"],
                "patent_number":
                data["pat_num"],
                "pct_number":
                data["pct_num"],
                "intl_publ_date":
                data["intl_publ_date"] if data["intl_publ_date"] else None,
                "intl_reg_num":
                data["intl_reg_num"],
                "app_early_pub_date":
                data["publ_date"] if data["publ_date"] else None,
                "app_early_pub_number":
                data["publ_num"],
                "patent_issue_date":
                data["issue_date"],
                "patent_title":
                data["invention_title"],
                "patent_title_lang":
                data["invention_title_lang"],
                "inventors":
                data["inventors"],
            })

        return [Property(p) for p in properties]

    @property
    def correspondent(self):
        data = self.data
        correspondent_keys = filter(lambda x: "corr_" in x and "size" not in x,
                                    data.keys())
        return repartition({k: data[k] for k in correspondent_keys})[0]

    @property
    def assignees(self):
        data = self.data
        assignee_keys = filter(
            lambda x: "pat_assignee_" in x and "size" not in x, data.keys())
        return repartition({k: data[k] for k in assignee_keys})

    @property
    def assignors(self):
        data = self.data
        assignor_keys = filter(
            lambda x: "pat_assignor_" in x and "size" not in x, data.keys())
        return repartition({k: data[k] for k in assignor_keys})

    def download(self):
        response = session.get(self.image_url, stream=True)
        with open(f"{self.id}.pdf", "wb") as f:
            f.write(response.raw.read())
Пример #9
0
class USApplication(Model):
    __manager__ = "patent_client.uspto.peds.manager.USApplicationManager"
    appl_id: str = field(compare=True)
    patent_title: Optional[str] = None
    app_status: Optional[str] = field(default=None, repr=True)
    inventors: Optional[List[str]] = field(default=None, repr=False)
    app_filing_date: Optional[datetime.date] = field(default=None, repr=False)
    app_location: Optional[str] = field(default=None, repr=False)
    first_inventor_file: Optional[str] = field(default=None, repr=False)
    app_type: Optional[str] = field(default=None, repr=False)
    app_entity_status: Optional[str] = field(default=None, repr=False)
    app_confr_number: Optional[str] = field(default=None, repr=False)
    applicants: List[Applicant] = field(default_factory=list, repr=False)
    app_status_date: Optional[datetime.date] = field(default=None, repr=False)
    app_cls_sub_cls: Optional[str] = field(default=None, repr=False)
    app_grp_art_number: Optional[str] = field(default=None, repr=False)
    corr_addr_cust_no: Optional[str] = field(default=None, repr=False)
    app_cust_number: Optional[str] = field(default=None, repr=False)
    app_attr_dock_number: Optional[str] = field(default=None, repr=False)
    patent_number: Optional[str] = field(default=None, repr=False)
    patent_issue_date: Optional[datetime.date] = field(default=None,
                                                       repr=False)
    app_early_pub_number: Optional[str] = field(default=None, repr=False)
    app_early_pub_date: Optional[datetime.date] = field(default=None,
                                                        repr=False)
    app_exam_name: Optional[str] = field(default=None, repr=False)
    wipo_early_pub_number: Optional[str] = field(default=None, repr=False)
    wipo_early_pub_date: Optional[datetime.date] = field(default=None,
                                                         repr=False)

    transactions: List[Transaction] = field(default_factory=list, repr=False)
    child_continuity: ListManager[Relationship] = field(
        default_factory=ListManager.empty, repr=False)
    parent_continuity: ListManager[Relationship] = field(
        default_factory=ListManager.empty, repr=False)
    pta_pte_tran_history: List[PtaPteHistory] = field(default_factory=list,
                                                      repr=False)
    pta_pte_summary: Optional[PtaPteSummary] = field(default=None, repr=False)
    correspondent: Optional[Correspondent] = field(default=None, repr=False)
    attorneys: List[Attorney] = field(default_factory=list, repr=False)
    foreign_priority: List[ForeignPriority] = field(default_factory=list,
                                                    repr=False)

    documents = one_to_many("patent_client.uspto.peds.model.Document",
                            appl_id="appl_id")

    @property
    def continuity(self) -> QuerySet:
        """Returns a complete set of parents, self, and children"""
        return QuerySet([
            self.child_continuity.values_list("child", flat=True),
            [
                self,
            ],
            self.parent_continuity.values_list("parent", flat=True),
        ])

    def __hash__(self):
        return hash(self.appl_id)

    @property
    def kind(self) -> str:
        """Differentiates provisional, PCT, and nonprovisional applications"""
        if "PCT" in self.appl_id:
            return "PCT"
        if self.appl_id[0] == "6":
            return "Provisional"
        return "Nonprovisional"

    @property
    def priority_date(self) -> datetime.date:
        """Attempts to return the priority date of the application, calculated as
        the earliest application filing date among the application's parents, or
        its own filing date if it has no parents
        """
        if not self.parent_continuity:
            return self.app_filing_date
        else:
            return sorted(p.parent_app_filing_date
                          for p in self.parent_continuity)[0]

    @property
    def expiration(self) -> Optional[Expiration]:
        """Calculates expiration data from which the expiration date can be calculated. See
        help information for the resulting Expiration model.
        """
        if "PCT" in self.appl_id:
            raise NotImplementedError(
                "Expiration date not supported for PCT Applications")
        if not self.patent_number:
            return None
        expiration_data = dict()
        term_parents = [
            p for p in self.parent_continuity if p.relationship not in [
                "Claims Priority from Provisional Application",
                "is a Reissue of"
            ]
        ]
        if term_parents:
            term_parent = sorted(term_parents,
                                 key=lambda x: x.parent_app_filing_date)[0]
            relationship = term_parent.relationship
            parent_filing_date = term_parent.parent_app_filing_date
            parent_appl_id = term_parent.parent_appl_id
        else:
            relationship = "self"
            parent_appl_id = self.appl_id
            parent_filing_date = self.app_filing_date

        expiration_data["parent_appl_id"] = parent_appl_id
        expiration_data["parent_app_filing_date"] = parent_filing_date
        expiration_data["parent_relationship"] = relationship
        expiration_data["initial_term"] = parent_filing_date + relativedelta(
            years=20)  # type: ignore
        expiration_data[
            "pta_or_pte"] = self.pta_pte_summary.total_days if self.pta_pte_summary else 0  # type: ignore
        expiration_data[
            "extended_term"] = expiration_data["initial_term"] + relativedelta(
                days=expiration_data["pta_or_pte"])  # type: ignore

        transactions = self.transactions
        try:
            disclaimer = next(t for t in transactions if t.code == "DIST")
            expiration_data["terminal_disclaimer_filed"] = True
        except StopIteration:
            expiration_data["terminal_disclaimer_filed"] = False

        return Expiration(**expiration_data)  # type: ignore

    assignments = one_to_many("patent_client.uspto.assignment.Assignment",
                              appl_id="appl_id")
    """Related Assignments from the Assignments API"""
    trials = one_to_many("patent_client.uspto.ptab.PtabProceeding",
                         appl_id="appl_id")
    """Related PtabProceedings for this application"""
    patent = one_to_one("patent_client.uspto.fulltext.Patent",
                        publication_number="patent_number")
    """Fulltext Patent - If Available"""

    @property
    def publication_number(self):
        return self.app_early_pub_number[2:-2]

    publication = one_to_one(
        "patent_client.uspto.fulltext.PublishedApplication",
        publication_number="publication_number",
    )
Пример #10
0
class PtabTrial(Model):
    """
    Ptab Trial
    ==========
    This object wraps the PTAB's public API (https://ptabdata.uspto.gov)

    ---------------------
    To Fetch a PTAB Trial
    ---------------------

    The main way to create a PtabTrial is by querying the PtabTrial manager at PtabTrial.objects

        PtabTrial.objects.filter(query) -> obtains multiple matching applications
        PtabTrial.objects.get(query) -> obtains a single matching application, errors if more than one is retreived

    The query can either be a single number, which is treated as a trial number, or a keyword argument:

        PtabTrial.objects.get('IPR2016-00831') -> Retreives a single trial
        PtabTrial.objects.filter(patent_number='6103599') -> retreives all PTAB trials involving US Patent Number 6103599

    A complete list of query fields is available at PtabTrial.objects.query_fields

    --------------
    Using the Data
    --------------
    A PtabTrial object has the following attributes:

        trial_number
        application_number
        patent_number
        petitioner_party_name
        patent_owner_name
        inventor_name
        prosecution_status
        filing_date
        accorded_filing_date
        institution_decision_date
        last_modified_datetime

    A PtabTrial also has access to the related documents, available at trial.documents

    ------------
    Related Data
    ------------
    A PtabTrial is also linked to other resources avaialble through patent_client, including:
        
        trial.us_application -> application which granted as the challenged patent

    """

    objects = PtabTrialManager()
    attrs = [
        "trial_number",
        "application_number",
        "patent_number",
        "petitioner_party_name",
        "patent_owner_name",
        "inventor_name",
        "prosecution_status",
        "filing_date",
        "accorded_filing_date",
        "institution_decision_date",
        "last_modified_datetime",
        "documents",
    ]

    us_application = one_to_one(
        "patent_client.USApplication", appl_id="application_number"
    )
    documents = one_to_many("patent_client.PtabDocument", trial_number="trial_number")

    def __repr__(self):
        return f"<PtabTrial(trial_number={self.trial_number})>"