Beispiel #1
0
    def _gen_report(self, embedded: bool, title: str,
                    headline: str) -> t.Tuple[str, t.List[Path]]:
        """Build XML report document"""
        # convert Blocks to XML
        s = BuilderState(embedded)
        _s = self.top_block.to_xml(s)
        assert len(_s.elements) == 1

        # add main structure and Meta
        report_doc: Element = E.Report(
            E.Meta(
                E.Author("Anonymous"),  # TODO - get username from config?
                E.CreatedOn(timestamp()),
                E.Title(title),
                E.Headline(headline),
            ),
            E.Main(*_s.elements),
            version="1",
        )
        report_doc.set("{http://www.w3.org/XML/1998/namespace}id",
                       f"_{uuid.uuid4().hex}")

        # post_process and validate
        processed_report_doc = local_post_transform(
            report_doc, embedded="true()" if embedded else "false()")
        validate_report_doc(xml_doc=processed_report_doc)

        # convert to string
        report_str = etree.tounicode(processed_report_doc, pretty_print=True)
        log.debug("Built Report")
        log.info(report_str)
        return (report_str, _s.attachments)
Beispiel #2
0
    def write(self, report_doc: str, path: str, report_type: ReportType,
              name: str, author: t.Optional[str]):
        # create template on demand
        if not self.template:
            self._setup_template()

        url = "https://datapane.com/create-workspace/"
        display_msg(
            text=
            f"Report saved to {path}. To host and share securely, create a free private workspace at {url}",
            md=
            f"Report saved to {path}. To host and share securely, [create a free private workspace]({url})",
        )

        # TODO(obsolete)
        # self._display_msg()

        # template.html inlines the report doc with backticks so we need to escape any inside the doc
        report_doc_esc = report_doc.replace("`", r"\`")
        r = self.template.render(
            report_doc=report_doc_esc,
            report_type=report_type,
            report_name=name,
            report_author=author,
            report_date=timestamp(),
            html_header=DEFAULT_HTML_HEADER,
            dp_logo=self.logo,
        )
        Path(path).write_text(r, encoding="utf-8")
Beispiel #3
0
    def _to_xml(self,
                embedded: bool,
                title: str = "Title",
                description: str = "Description",
                author: str = "Anonymous") -> t.Tuple[Element, t.List[Path]]:
        """Build XML report document"""
        # convert Pages to XML
        s = BuilderState(embedded)
        _s = reduce(lambda _s, p: p._to_xml(_s), self.pages, s)

        # add main structure
        report_doc: Element = E.Report(
            E.Internal(),
            E.Main(*_s.elements),
            version="1",
        )

        # add optional Meta
        if embedded:
            meta = E.Meta(
                E.Author(c.config.username or author),
                E.CreatedOn(timestamp()),
                E.Title(title),
                E.Description(description),
                E.Type(self.report_type.value),
            )
            report_doc.insert(0, meta)
        return (report_doc, _s.attachments)
Beispiel #4
0
    def _gen_report(self,
                    embedded: bool,
                    title: str,
                    description: str = "Description",
                    author: str = "Anonymous") -> t.Tuple[str, t.List[Path]]:
        """Build XML report document"""
        # convert Pages to XML
        s = BuilderState(embedded)
        _s = reduce(lambda _s, p: p._to_xml(_s), self.pages, s)

        # add main structure and Meta
        report_doc: Element = E.Report(
            E.Meta(
                E.Author(author),  # TODO - get username from config?
                E.CreatedOn(timestamp()),
                E.Title(title),
                E.Description(description),
            ),
            E.Main(*_s.elements, type=self.report_type.value),
            version="1",
        )
        report_doc.set("{http://www.w3.org/XML/1998/namespace}id",
                       f"_{uuid.uuid4().hex}")

        # post_process and validate
        processed_report_doc = local_post_transform(
            report_doc, embedded="true()" if embedded else "false()")
        validate_report_doc(xml_doc=processed_report_doc)

        # check for any unsupported local features, e.g. DataTable
        # NOTE - we could eventually have different validators for local and published reports
        if embedded:
            uses_datatable: bool = processed_report_doc.xpath(
                "boolean(/Report/Main//DataTable)")
            if uses_datatable:
                raise UnsupportedFeature(
                    "DataTable component not supported when saving locally, please publish to a Datapane Server or use dp.Table"
                )

        # convert to string
        report_str = etree.tounicode(processed_report_doc, pretty_print=True)
        log.debug("Built Report")
        log.debug(report_str)
        return (report_str, _s.attachments)
Beispiel #5
0
    def write(self, report_doc: str, path: str, report_type: ReportType, name: str, author: t.Optional[str]):

        # create template on demand
        if not self.template:
            self._setup_template()

        self._display_msg()

        # template.html inlines the report doc with backticks so we need to escape any inside the doc
        report_doc_esc = report_doc.replace("`", r"\`")
        r = self.template.render(
            report_doc=report_doc_esc,
            report_type=report_type,
            report_name=name,
            report_author=author,
            report_date=timestamp(),
            dp_logo=self.logo,
        )
        Path(path).write_text(r, encoding="utf-8")