Friday, October 1, 2021

TestDriven.io: Django REST Framework Views - ViewSets

This article takes a deep dive into Django REST Framework's most powerful view, ViewSets.

from Planet Python
via read more

Real Python: The Real Python Podcast – Episode #80: Make Your Python App Interactive With a Text User Interface (TUI)

Have you wanted to create a Python application that goes further than a command-line interface? You would like it to have a friendly interface but don't want to make a GUI (Graphical User Interface) or web application. Maybe a TUI (Text User Interface)would be a perfect fit for the project. This week on the show, we have Will McGugan to talk about his projects Textual and Rich.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]



from Planet Python
via read more

Stack Abuse: Create a Stunning PDF Flyer in Python with borb

The Portable Document Format (PDF) is not a WYSIWYG (What You See is What You Get) format. It was developed to be platform-agnostic, independent of the underlying operating system and rendering engines.

To achieve this, PDF was constructed to be interacted with via something more like a programming language, and relies on a series of instructions and operations to achieve a result. In fact, PDF is based on a scripting language - PostScript, which was the first device-independent Page Description Language.

In this guide, we'll be using borb - a Python library dedicated to reading, manipulating and generating PDF documents. It offers both a low-level model (allowing you access to the exact coordinates and layout if you choose to use those) and a high-level model (where you can delegate the precise calculations of margins, positions, etc to a layout manager).

In this guide, we'll take a look at how to generate a flyer containing custom graphics (represented by PDF operators).

Installing borb

borb can be downloaded from source on GitHub, or installed via pip:

$ pip install borb

What We’ll Be Making

It's oftentimes easier to make a sketch, and work towards it, rather than building blind, so feel free to sketch out a flyer on a piece of paper you have lying around, and letting that creativity flow unto the canvas.

We'll be making a flyer like this, to promote a supposed product belonging to a supposed company:

Example Flyer Image

Creating a PDF Document with borb

Building a PDF document in borb typically follows the same couple of steps:

  • Creating an empty Document
  • Creating an empty Page and appending it to the Document
  • Setting a PageLayout on the Page
  • Adding content to the PageLayout
  • Persisting the Document

Let's see what that looks like in code:

from borb.pdf.document import Document
from borb.pdf.page.page import Page
from borb.pdf.canvas.layout.page_layout.multi_column_layout import SingleColumnLayout
from borb.pdf.canvas.layout.page_layout.page_layout import PageLayout
from borb.pdf.pdf import PDF

def main():
  # Create empty Document
  pdf = Document()

  # Create empty Page
  page = Page()

  # Add Page to Document
  pdf.append_page(page)

  # Create PageLayout
  layout: PageLayout = SingleColumnLayout(page)

  # Future content-rendering-code to be inserted here
  
  # Attempt to store PDF
  with open("output.pdf", "wb") as pdf_file_handle:
      PDF.dumps(pdf_file_handle, pdf)
  
if __name__ == '__main__':
  main()

Creating a PDF Flyer with borb

Now that we have an empty canvas to work from, let's add the basic content. We'll start by adding the title, such as "Your Company":

# New imports
from borb.pdf.canvas.layout.text.paragraph import Paragraph  
from borb.pdf.canvas.color.color import HexColor  
from decimal import Decimal  
  
# Contact information
layout.add(
  Paragraph("Your Company", 
            font_color=HexColor("#6d64e8"), 
            font_size=Decimal(20)
    )
)

The next step is adding the QR-code and the contact information. In order to easily present this content side by side, we're going to be using a Table.

We also need the coordinates of the QR-code (we'll be adding something special to it later on). So let's start by declaring that first:

# New imports
from borb.pdf.canvas.layout.image.barcode import Barcode, BarcodeType  
from borb.pdf.canvas.layout.layout_element import LayoutElement
  
# Code to generate a QR code LayoutElement
qr_code: LayoutElement = Barcode(
    data="https://www.borbpdf.com",
    width=Decimal(64),
    height=Decimal(64),
    type=BarcodeType.QR,
)

Now we can build and add our Table:

 # New imports
from borb.pdf.canvas.layout.table.flexible_column_width_table import FlexibleColumnWidthTable
  
layout.add(
    FlexibleColumnWidthTable(number_of_columns=2, number_of_rows=1)
    .add(qr_code)
    .add(
        Paragraph(
            """
            500 South Buena Vista Street
            Burbank CA
            91521-0991 USA
            """,
            padding_top=Decimal(12),
            respect_newlines_in_text=True,
            font_color=HexColor("#666666"),
            font_size=Decimal(10),
        )
    )
    .no_borders()
)

Let's run that code and see what the generated PDF looks like. I find that the best way of tweaking the little UI/UX details.

creating a pdf document with borb

Looking good! The QR-code is situated right under the company's name, contains the right contact information and actually encodes the contact data we've provided.

Next we're going to add a remote go-to annotation. That's just PDF-talk for "a clickable link that takes you outside the PDF".

We're going to make sure the entire QR-code is actually a link that takes the reader to our website. That way, if they have the printed version of this PDF they can simply scan the QR code. If they have the digital version, they can click the QR code.

This is a simple addition, but makes navigation on the user-end a more pleasant experience:

page.append_remote_go_to_annotation(
  qr_code.get_bounding_box(), uri="https://www.borbpdf.com"
)

Adding Product Information

We can now add the next title and subtitle(s), pertaining to a product we're creating a flyer for:

# Title
layout.add(
    Paragraph(
        "Productbrochure", font_color=HexColor("#283592"), font_size=Decimal(34)
    )
)

# Subtitle
layout.add(
    Paragraph(
        "September 4th, 2021",
        font_color=HexColor("#e01b84"),
        font_size=Decimal(11),
    )
)

And similarly, we'll add the product overview title, and some dummy text:

# product overview
layout.add(
    Paragraph(
        "Product Overview", font_color=HexColor("000000"), font_size=Decimal(21)
    )
)

layout.add(
   Paragraph(
        """
        Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. 
        Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. 
        A small river named Duden flows by their place and supplies it with the necessary regelialia.
        """
    )
)

layout.add(
    Paragraph(
        """
        It is a paradisematic country, in which roasted parts of sentences fly into your mouth. 
        Even the all-powerful Pointing has no control about the blind texts it is an almost unorthographic life. 
        One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar.
        """,
        margin_bottom=Decimal(12)
    )
)

Note: Pay attention to the last Paragraph where we explictly added a bottom margin. That's just a small visual tweak to ensure there's a bit more room between that Paragraph and the next piece of content, which will be an image.

When we run this code, we should get something like this:

adding information

Finally, we can add the product information. We could have an Image alongside a list of some of the features of the product. So again, we can use a Table to achieve the side-by-side look.

Oftentimes, there's a title above the list of features, so we're going to have a Table with 2 columns (image and features) and 2 rows (one for the title, and one for the features).

Since the table is being used not as a table, but rather just to achieve the side-by-side look, we won't be adding a border to the table:

# New imports
from borb.pdf.canvas.layout.image.image import Image
from borb.pdf.canvas.layout.table.table import TableCell  
from borb.pdf.canvas.layout.table.fixed_column_width_table import FixedColumnWidthTable
from borb.pdf.canvas.layout.list.unordered_list import UnorderedList
  
# Table with image and key features
layout.add(
    FixedColumnWidthTable(
        number_of_rows=2,
        number_of_columns=2,
        column_widths=[Decimal(0.3), Decimal(0.7)],
    )
    .add(
        TableCell(
            Image(
                  "https://www.att.com/catalog/en/skus/images/apple-iphone%2012-purple-450x350.png",
                width=Decimal(128),
                height=Decimal(128),
            ),
            row_span=2,
        )
    )
    .add(
        Paragraph(
            "Key Features",
            font_color=HexColor("e01b84"),
            font="Helvetica-Bold",
            padding_bottom=Decimal(10),
        )
    )
    .add(
        UnorderedList()
        .add(Paragraph("Nam aliquet ex eget felis lobortis aliquet sit amet ut risus."))
        .add(Paragraph("Maecenas sit amet odio ut erat tincidunt consectetur accumsan ut nunc."))
        .add(Paragraph("Phasellus eget magna et justo malesuada fringilla."))
        .add(Paragraph("Maecenas vitae dui ac nisi aliquam malesuada in consequat sapien."))
    )
    .no_borders()
)

Again, we've added a padding_bottom in some cells of the Table just to provide some extra space. The resulting PDF is almost finished:

The final steps remaining are adding the artwork in the top-right corner, and in the footer.

Using the Shape object in borb

borb can render any Shape to the Page. Shape represents an arbitrary sequence of points (represented as typing.Tuple[Decimal, Decimal]) all of which form a continuous line. This means that you can get quite creative with the shapes you want to create.

We'll start by defining a method that renders the triangles and squares in the upper right corner of the Page:

# New imports
from borb.pdf.canvas.geometry.rectangle import Rectangle
from borb.pdf.canvas.layout.image.shape import Shape
from borb.pdf.page.page_size import PageSize
import typing
import random
  
  
def add_gray_artwork_upper_right_corner(page: Page) -> None:
  """
  This method will add a gray artwork of squares and triangles in the upper right corner
  of the given Page
  """
    grays: typing.List[HexColor] = [
        HexColor("A9A9A9"),
        HexColor("D3D3D3"),
        HexColor("DCDCDC"),
        HexColor("E0E0E0"),
        HexColor("E8E8E8"),
        HexColor("F0F0F0"),
    ]
    ps: typing.Tuple[Decimal, Decimal] = PageSize.A4_PORTRAIT.value
    N: int = 4
    M: Decimal = Decimal(32)
    
    # Draw triangles
    for i in range(0, N):
        x: Decimal = ps[0] - N * M + i * M
        y: Decimal = ps[1] - (i + 1) * M
        rg: HexColor = random.choice(grays)
        Shape(
            points=[(x + M, y), (x + M, y + M), (x, y + M)],
            stroke_color=rg,
            fill_color=rg,
        ).layout(page, Rectangle(x, y, M, M))
        
    # Draw squares
    for i in range(0, N - 1):
        for j in range(0, N - 1):
            if j > i:
                continue
            x: Decimal = ps[0] - (N - 1) * M + i * M
            y: Decimal = ps[1] - (j + 1) * M
            rg: HexColor = random.choice(grays)
            Shape(
                points=[(x, y), (x + M, y), (x + M, y + M), (x, y + M)],
                stroke_color=rg,
                fill_color=rg,
            ).layout(page, Rectangle(x, y, M, M))

We can now call this method in the main method, and give our PDF some extra pazzaz:

Similarly, we could add some graphics to the bottom of the page:

  • A line to separate the footer from the main content of the page
  • A small geometric element to balance the geometric graphic atop the page

Let's write another method to do all of that:

from borb.pdf.canvas.line_art.line_art_factory import LineArtFactory

def add_colored_artwork_bottom_right_corner(page: Page) -> None:
  """
  This method will add a blue/purple artwork of lines 
  and squares to the bottom right corner
  of the given Page
  """
    ps: typing.Tuple[Decimal, Decimal] = PageSize.A4_PORTRAIT.value
    
    # Square
    Shape(
      points=[
          (ps[0] - 32, 40),
          (ps[0], 40),
          (ps[0], 40 + 32),
          (ps[0] - 32, 40 + 32),
      ],
      stroke_color=HexColor("d53067"),
      fill_color=HexColor("d53067"),
    ).layout(page, Rectangle(ps[0] - 32, 40, 32, 32))
    
    # Square
    Shape(
      points=[
          (ps[0] - 64, 40),
          (ps[0] - 32, 40),
          (ps[0] - 32, 40 + 32),
          (ps[0] - 64, 40 + 32),
      ],
      stroke_color=HexColor("eb3f79"),
      fill_color=HexColor("eb3f79"),
    ).layout(page, Rectangle(ps[0] - 64, 40, 32, 32))
    
    # Triangle
    Shape(
      points=[
          (ps[0] - 96, 40),
          (ps[0] - 64, 40),
          (ps[0] - 64, 40 + 32),
      ],
      stroke_color=HexColor("e01b84"),
      fill_color=HexColor("e01b84"),
    ).layout(page, Rectangle(ps[0] - 96, 40, 32, 32))
        
    # Line
    r: Rectangle = Rectangle(Decimal(0), Decimal(32), ps[0], Decimal(8))
    Shape(
      points=LineArtFactory.rectangle(r),
      stroke_color=HexColor("283592"),
      fill_color=HexColor("283592"),
    ).layout(page, r)

Again, we can call this method from the main method. The resulting page should look like this:

Conclusion

In this guide we've taken a look at some of the basic building blocks of PDF documents using borb. We've configured padding and margin, as well as font-size and font-color. We've also generated graphics using the Shape object, and a working clickable QR-code.

With these building blocks, we've created a flyer for a supposed product of an imaginary company, automating the process of creating interactive PDF documents.



from Planet Python
via read more

The Real Python Podcast – Episode #80: Make Your Python App Interactive With a Text User Interface (TUI)

Have you wanted to create a Python application that goes further than a command-line interface? You would like it to have a friendly interface but don't want to make a GUI (Graphical User Interface) or web application. Maybe a TUI (Text User Interface)would be a perfect fit for the project. This week on the show, we have Will McGugan to talk about his projects Textual and Rich.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]



from Real Python
read more

Tryton News: Newsletter October 2021

Here are the latest improvements in preparation for the upcoming 6.2 release.

Changes for the User

The sale module currently provides reporting that displays relevant data grouped by products, categories etc. We now also have a general report that is not grouped but just displays totals.

We now support products without a list price.

The user will be warned if they try to post an invoice with a date in the future.

The web client now has a button to fold/unfold the selected records of a tree.

The dunning records now store their own age.

New Modules

The Product Image Attribute Module adds attributes to product images.

Changes for the System Administrator

The errors that are raised during non-interactive operations (like scheduled tasks or queued jobs) are now listed in the administration entry. These error can be processed by a user, and once solved the task or the job is submitted again.

The trytond-stat command displays the node name on which the process is running. This is useful when the directory that contains the stat socket is shared between multiple machines.

On first login the configuration wizard now has a step that makes it easy to activate modules on the system.

Changes for the Developer

The MPTT behavior has been improved to avoid a full rebuild when creating nested records. It now does a classic update for each level.

The ModelStorage class now has a count() method that returns an estimate of the number of records stored. It uses caching and random invalidation to minimize the cost.

We now use str instead of repr when constructing the warning keys. This allows the same key to be constructed using proteus.

The method remove_forbidden_chars has been added to the tools as it is used by many modules.

The ModelSQL.search method optimizes some queries by using a UNION of sub-queries when clauses contain straight columns of the table and columns of a joined table. In these cases the database can use indexes.

The context can normally only be modified with the Transaction.set_context context manager. In order to enforce this behavior, the context is now an ImmutableDict.

The title of emails generated from a report no longer contain the name of the record from which the report is generated.

The value of the Dict field is an ImmutableDict but the values must also be immutable. So we now use a tuple instead of list.

The server now uses the bigdecimal type from XML-RPC.

For performance reasons we use __slots__ for the classes registered in the Pool. But as this can be broken when one class does not define it we added a generic test which ensures that all the classes in the Pool have __slots__ defined.

When proteus is configured to use XML-RPC, it authenticates on each request. This is slow as we are using a slow hashing method for security and to protect against brute-force attacks. Now proteus can be configured to use a session with XML-RPC.

The grouping option to format numeric widget can be configured on the view.

We unified the way we set email From headers. Tryton now sets the Reply-To and On-Behalf-Of headers when needed.

1 post - 1 participant

Read full topic



from Planet Python
via read more

Mike Driscoll: The Indie Python Extravaganza Book Bundle

I am joining some of my fellow indie content creators to create a FREE Python book bundle for the month of October 2021!

The Indie Python Extravaganza!

A collection of books that will help you to improve your knowledge of the Python programming language one page at a time. Join four indie authors in a journey from the basics of Python to the structure of production-ready systems, going through the core features of the language, some intermediate projects and a deep dive into regular expressions.

In this bundle, Mike will teach you the basics of Python with Python 101. Sundeep will then take the lead and help you to put your knowledge into practice with Practice Python Projects. Learn what NOT to do when writing your Python programs with Rodrigo in his Pydon'ts book! If you need to learn regular expressions, Sundeep has again your back with his Python re(gex)? book, and when you are ready to start working on production code, you'll have Clean Architectures in Python to help you!

The Indie Python Extravaganza

This bundle is only available for FREE for the month of October, 2021.

Only available on Leanpub!

Here is more information about the books in this bundle:

Python 101

2nd edition

by Mike Driscoll

Learn how to write Python and beyond. You will not only learn the syntax of Python, but you will also create prototype applications and binaries that you can share with your family and friends.

 

Practice Python Projects

Beginner to Intermediate level projects inspired by real-world use cases

by Sundeep Agarwal

Know Python basics but don't know what to do next? Take the next step in your programming journey with real world inspired Python projects.

 

Pydon'ts

Write elegant Python code

by Rodrigo Girão Serrão

Python has so many libraries that people often forget to take their time to learn about all the really interesting and useful features that Python offers.

The Pydon'ts teach you these core features of Python, with plenty of code examples to show you how these features are used in real code in the real world.

Want to master Python? Start here ????.

 

Python re(gex)?

A magical tool for text processing

by Sundeep Agarwal

Scripting and automation tasks often need to extract particular portions of text from input data or modify them from one format to another.

This book will help you learn Python Regular Expressions, a mini-programming language for all sorts of text processing needs.

 

Clean Architectures in Python

A practical approach to better software design

by Leonardo Giordani

What is a good software architecture? Why should we bother structuring the code and spending time testing it? If you like spending hours debugging your programs or staying late at the office to recover from a buggy deploy in production this book is definitely NOT for you!

(Photo by Alfons Morales on Unsplash)

The post The Indie Python Extravaganza Book Bundle appeared first on Mouse Vs Python.



from Planet Python
via read more

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...