• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lfoppiano / streamlit-pdf-viewer / 9047196931

11 May 2024 11:44PM UTC coverage: 73.684% (-0.7%) from 74.359%
9047196931

Pull #49

github

lfoppiano
Harmonise how the width is collected, update tests
Pull Request #49: Fix scaling and display high PDF in high resolution

2 of 2 new or added lines in 1 file covered. (100.0%)

6 existing lines in 2 files now uncovered.

56 of 76 relevant lines covered (73.68%)

8.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.68
/streamlit_pdf_viewer/__init__.py
1
import base64
12✔
2
import os
12✔
3
from pathlib import Path
12✔
4
from typing import Union, List, Optional
12✔
5

6
import streamlit.components.v1 as components
12✔
7
import json
12✔
8

9
_RELEASE = True
12✔
10
RENDERING_EMBED = "legacy_embed"
12✔
11
RENDERING_IFRAME = "legacy_iframe"
12✔
12
RENDERING_UNWRAP = "unwrap"
12✔
13

14
if not _RELEASE:
12✔
15
    _component_func = components.declare_component(
×
16
        "streamlit_pdf_viewer",
17
        url="http://localhost:3001",
18
    )
19
else:
20
    parent_dir = os.path.dirname(os.path.abspath(__file__))
12✔
21
    build_dir = os.path.join(parent_dir, "frontend/dist")
12✔
22
    _component_func = components.declare_component(
12✔
23
        "streamlit_pdf_viewer",
24
        path=build_dir
25
    )
26

27

28
def pdf_viewer(input: Union[str, Path, bytes], 
12✔
29
               width: int = None,
30
               height: int = None, 
31
               key=None,
32
               annotations: list = (),
33
               pages_vertical_spacing: int = 2,
34
               annotation_outline_size: int = 1,
35
               rendering: str = RENDERING_UNWRAP,
36
               pages_to_render: List[int] = ()
37
               ):
38
    """
39
    pdf_viewer function to display a PDF file in a Streamlit app.
40

41
    :param input: The source of the PDF file. Accepts a file path, URL, or binary data.
42
    :param width: Width of the PDF viewer in pixels. Defaults to 700 pixels.
43
    :param height: Height of the PDF viewer in pixels. If not provided, the viewer show the whole content.
44
    :param key: An optional key that uniquely identifies this component. Used to preserve state in Streamlit apps.
45
    :param annotations: A list of annotations to be overlaid on the PDF. Each annotation should be a dictionary.
46
    :param pages_vertical_spacing: The vertical space (in pixels) between each page of the PDF. Defaults to 2 pixels.
47
    :param annotation_outline_size: Size of the outline around each annotation in pixels. Defaults to 1 pixel.
48
    :param rendering: Type of rendering. The default is "unwrap", which unwrap the PDF. Other values are
49
    :param pages_to_render: Optional list of page numbers to render. If None, all pages are rendered. This allows for selective rendering of pages in the PDF.
50
    "legacy_iframe" and "legacy_embed" which uses the legacy approach for showing PDF document with streamlit.
51
    These methods enable the default pdf viewer of Firefox/Chrome/Edge that contains additional features we are still
52
    working to implement for the "unwrap" method.
53

54
    The function reads the PDF file (from a file path, URL, or binary data), encodes it in base64,
55
    and uses a Streamlit component to render it in the app. It supports optional annotations and adjustable margins.
56

57
    Returns the value of the selected component (if any).
58
    """
59

60
    # Validate width and height parameters
61
    if width is not None and not isinstance(width, int):
12✔
62
        raise TypeError("Width must be an integer")
×
63
    if height is not None and not isinstance(height, int):
12✔
64
        raise TypeError("Height must be an integer or None")
×
65
    if not all(isinstance(page, int) for page in pages_to_render):
12✔
66
        raise TypeError("pages_to_render must be a list of integers")
×
67

68
    if type(input) is not bytes:
12✔
69
        with open(input, 'rb') as fo:
12✔
70
            binary = fo.read()
12✔
71
    else:
72
        binary = input
×
73
        
74
    if rendering == RENDERING_IFRAME or rendering == RENDERING_EMBED:
12✔
75
        if height is None: 
12✔
76
            height = "100%"
12✔
77

78
    base64_pdf = base64.b64encode(binary).decode('utf-8')
12✔
79
    component_value = _component_func(
12✔
80
        binary=base64_pdf,
81
        width=width,
82
        height=height,
83
        key=key,
84
        default=0,
85
        annotations=annotations,
86
        pages_vertical_spacing=pages_vertical_spacing,
87
        annotation_outline_size=annotation_outline_size,
88
        rendering=rendering,
89
        pages_to_render=pages_to_render
90
    )
91
    return component_value
12✔
92

93

94
if not _RELEASE:
12✔
UNCOV
95
    with open("resources/test.pdf", 'rb') as fo:
×
UNCOV
96
        binary = fo.read()
×
97

98
    with open("resources/annotations.json", 'rb') as fo:
×
UNCOV
99
        annotations = json.loads(fo.read())
×
100

101
    viewer = pdf_viewer(
×
102
        binary,
103
        # height=700,
104
        width=800,
105
        annotations=annotations
106
    )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc