34,79 €
Python is the language of choice for millions of developers worldwide that builds great web services in RESTful architecture. This second edition of Hands-On RESTful Python Web Services will cover the best tools you can use to build engaging web services.
This book shows you how to develop RESTful APIs using the most popular Python frameworks and all the necessary stacks with Python, combined with related libraries and tools. You’ll learn to incorporate all new features of Python 3.7, Flask 1.0.2, Django 2.1, Tornado 5.1, and also a new framework, Pyramid. As you advance through the chapters, you will get to grips with each of these frameworks to build various web services, and be shown use cases and best practices covering when to use a particular framework.
You’ll then successfully develop RESTful APIs with all frameworks and understand how each framework processes HTTP requests and routes URLs. You’ll also discover best practices for validation, serialization, and deserialization. In the concluding chapters, you will take advantage of specific features available in certain frameworks such as integrated ORMs, built-in authorization and authentication, and work with asynchronous code. At the end of each framework, you will write tests for RESTful APIs and improve code coverage.
By the end of the book, you will have gained a deep understanding of the stacks needed to build RESTful web services.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 603
Veröffentlichungsjahr: 2018
Copyright © 2018 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author(s), nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Aaron LazarAcquisition Editor: Reshma RamanContent Development Editor: Rohit SinghTechnical Editor: Gaurav GalaCopy Editor: Safis EditingProject Coordinator: Vaidehi SawantProofreader: Safis EditingIndexer: Priyanka DhadkeGraphics: Alishon MendonsaProduction Coordinator: Shraddha Falebhai
First published: October 2016 Second edition: December 2018
Production reference: 1221218
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78953-222-7
www.packtpub.com
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and, as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Gaston C. Hillar is Italian and has been working with computers since he was 8 years old. Gaston has a Bachelor's degree in computer science (graduated with honors) and an MBA.
Currently, Gaston is an independent IT consultant and a freelance author who is always looking for new adventures anywhere in the world.
He was a senior contributing editor at Dr. Dobb's, and has written more than a hundred articles on software development topics. He has received the prestigious Intel® Black Belt Software Developer award eight times. He has written many articles about Java for Oracle Java Magazine.
Gaston was also a former Microsoft MVP in technical computing. He lives with his wife, Vanesa, and his two sons, Kevin and Brandon.
Norbert Máté is a web developer who started his career back in 2008. His first programming language as a professional web developer was PHP, before moving on to JavaScript/Node.js and Python/Django/Django Rest Framework. He is passionate about software architecture, design patterns, and clean code. Norbert has reviewed other Django books, including Django RESTful Web Services.
Sanjeev Jaiswal is a Computer Graduate from CUSAT with 9 years of industrial experience. He uses Perl, Python, AWS, and GNU/Linux for his day-to-day activities. He is currently working on projects involving penetration testing, source code review, and security design and implementations in AWS and cloud security projects. He is currently learning about DevSecOps and security automation as well. Sanjeev loves teaching engineering students and IT professionals. He has been teaching in his leisure time for the last 8 years. He has written Instant PageSpeed Optimization and co-authored Learning Django Web Development for Packt Publishing.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
Hands-On RESTful Python Web Services Second Edition
Dedication
About Packt
Why subscribe?
Packt.com
Contributors
About the author
About the reviewers
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Conventions used
Reader feedback
Customer support
Get in touch
Errata
Reviews
Piracy
Questions
Developing RESTful APIs and Microservices with Flask 1.0.2
Designing a RESTful API to interact with a simple data source
Understanding the tasks performed by each HTTP method
Understanding microservices
Working with lightweight virtual environments
Setting up a virtual environment with Flask and Flask-RESTful
Declaring status codes for the responses with an enumerable
Creating the model
Using a dictionary as a repository
Configuring output fields
Working with resourceful routing on top of Flask pluggable views
Configuring resource routing and endpoints
Making HTTP requests to the Flask API
Working with the curl and httpie command-line tools
Working with GUI tools – Postman and others
Consuming the API with other programming languages
Test your knowledge
Summary
Working with Models, SQLAlchemy, and Hyperlinked APIs in Flask
Designing a RESTful API to interact with a PostgreSQL 10.5 database
Understanding the tasks performed by each HTTP method
Installing packages with the requirements.txt file to simplify our common tasks
Creating the database
Configuring the database
Creating models with their relationships
Creating schemas to validate, serialize, and deserialize models
Combining blueprints with resourceful routing
Understanding and configuring resourceful routing
Registering the blueprint and running migrations
Verifying the contents of the PostgreSQL database
Creating and retrieving related resources
Test your knowledge
Summary
Improving Our API and Adding Authentication to it with Flask
Improving unique constraints in the models
Understanding the differences between the PUT and the PATCH methods
Updating fields for a resource with the PATCH method
Coding a generic pagination class
Adding pagination features
Understanding the steps to add authentication and permissions
Adding a user model
Creating schemas to validate, serialize, and deserialize users
Adding authentication to resources
Creating resource classes to handle users
Running migrations to generate the user table
Composing requests with the necessary authentication
Test your knowledge
Summary
Testing and Deploying an API in a Microservice with Flask
Setting up unit tests with pytest
Creating a database for testing
Creating fixtures to perform setup and teardown tasks for running clean tests
Writing the first round of unit tests
Running unit tests with pytest and checking testing coverage
Improving testing coverage
Understanding strategies for deployments and scalability
Test your knowledge
Summary
Developing RESTful APIs with Django 2.1
Designing a RESTful API to interact with a simple SQLite database
Understanding the tasks performed by each HTTP method
Setting up the virtual environment with Django REST framework
Creating the models
Managing serialization and deserialization
Understanding status codes for the responses
Writing API views
Making HTTP requests to the Django API
Working with command-line tools - curl and httpie
Working with GUI tools - Postman and others
Test your knowledge
Summary
Working with Class-Based Views and Hyperlinked APIs in Django 2.1
Using model serializers to eliminate duplicate code
Working with wrappers to write API views
Using the default parsing and rendering options and moving beyond JSON
Browsing the API
Designing a RESTful API to interact with a complex PostgreSQL 10.5 database
Understanding the tasks performed by each HTTP method
Declaring relationships with the models
Installing packages with the requirements.txt file to work with PostgreSQL
Configuring the database
Running migrations
Verifying the contents of the PostgreSQL database
Managing serialization and deserialization with relationships and hyperlinks
Creating class-based views and using generic classes
Taking advantage of generic class-based views
Working with endpoints for the API
Browsing an API with relationships
Creating and retrieving related resources
Test your knowledge
Summary
Improving Our API and Adding Authentication to it with Django
Adding unique constraints to the models
Updating a single field for a resource with the PATCH method
Taking advantage of pagination
Customizing pagination classes
Understanding authentication, permissions, and throttling
Adding security-related data to the models
Creating a customized permission class for object-level permissions
Persisting the user that makes a request and configuring permission policies
Setting a default value for a new required field in migrations
Composing requests with the necessary authentication
Browsing the API with authentication credentials
Test your knowledge
Summary
Throttling, Filtering, Testing, and Deploying an API with Django 2.1
Installing packages with the requirements.txt file to work with filters, throttling, and tests
Understanding filtering, searching, and ordering classes
Configuring filtering, searching, and ordering for views
Executing HTTP requests to test filtering, searching, and ordering
Filtering, searching and ordering in the Browsable API
Understanding throttling classes and goals
Configuring throttling policies
Executing HTTP requests to test throttling policies
Setting up unit tests with pytest
Writing the first round of unit tests
Running unit tests with pytest
Improving testing coverage
Running Django RESTful APIs on the cloud
Test your knowledge
Summary
Developing RESTful APIs with Pyramid 1.10
Designing a RESTful API to interact with a simple data source
Setting up the virtual environment with Pyramid 1.10
Creating a new Pyramid project based on a template
Creating the model
Using a dictionary as a repository
Creating a Marshmallow schema to validate, serialize, and deserialize the model
Working with view callables and view configurations
Understanding and configuring view handlers
Making HTTP requests to the API with command-line tools
Test your knowledge
Summary
Developing RESTful APIs with Tornado 5.1.1
Designing a RESTful API to interact with slow sensors and actuators
Understanding the tasks performed by each HTTP method
Setting up a virtual environment with Tornado 5.1.1
Creating classes that represent a drone
Writing request handlers
Mapping URL patterns to request handlers
Making HTTP requests to the Tornado API
Working with command-line tools - curl and httpie
Working with GUI tools - Postman and others
Test your knowledge
Summary
Working with Asynchronous Code, Testing, and Deploying an API with Tornado
Understanding synchronous and asynchronous execution
Refactoring code to take advantage of asynchronous decorators
Mapping URL patterns to asynchronous request handlers
Making HTTP requests to the Tornado non-blocking API
Setting up unit tests with pytest
Writing the first round of unit tests
Running unit tests with pytest and checking testing coverage
Improving testing coverage
Understanding strategies for deploying Tornado APIs to the cloud
Test your knowledge
Summary
Assessment
Chapter 1
Chapter 2
Chapter 3
Chapter 4
Chapter 5
Chapter 6
Chapter 7
Chapter 8
Chapter 9
Chapter 10
Chapter 11
Other Books You May Enjoy
Leave a review - let other readers know what you think
REST (short for REpresentational State Transfer) is the architectural style that is driving modern web development and mobile app development. In fact, developing and interacting with RESTful web services is a required skill in any modern software development job. Sometimes, you have to interact with an existing API and in other cases, you have to design a RESTful API from scratch and make it work with JSON (short for JavaScript Object Notation).
Python is one of the most popular programming languages. Python 3.6 and 3.7 are the most modern versions of Python. Python is open source and multiplatform, and you can use it to develop any kind of application, from websites to extremely complex scientific computing applications. There is always a Python package that makes things easier for you to avoid reinventing the wheel and solve the problems faster. The most important and popular cloud computing providers make it easy to work with Python and its related web frameworks. Thus, Python is an ideal choice for developing RESTful web services. This book covers all the things you need to know to select the most appropriate Python web framework and develop a RESTful API from scratch.
You will work with the latest versions of the four most popular Python web frameworks that make it easy to develop RESTful web services: Flask, Django, Pyramid, and Tornado. Each web framework has its advantages and disadvantages. You will work with examples that represent appropriate cases for each of these web frameworks, in combination with additional Python packages that will simplify the most common tasks. You will learn how to use different tools to test and develop high-quality, consistent, and scalable RESTful web services.
You will write unit tests and improve test coverage for the RESTful web services that you will develop throughout the book. You won't just run the sample code; you will also make sure that you write tests for your RESTful API. You will always write modern Python code and you will take advantage of features introduced in the latest Python versions.
This book will allow you to learn how to take advantage of many packages that will simplify the most common tasks related to RESTful web services. You will be able to start creating your own RESTful APIs for any domain in any of the covered web frameworks in Python 3.6, 3.7, or greater.
This book is for web developers who have a working knowledge of Python and would like to build amazing web services by taking advantage of the various frameworks of Python. You should have some knowledge of RESTful APIs.
Chapter 1, Developing RESTful APIs and Microservices with Flask 1.0.2, begins working with Flask and its Flask-RESTful extension. We will create a RESTful Web API that performs CRUD (short for Create, Read, Update, and Delete) operations on a simple list.
Chapter 2, Working with Models, SQLAlchemy, and Hyperlinked APIs in Flask, expands the capabilities of the RESTful API that we started in the previous chapter. We will use SQLAlchemy as our ORM to work with a PostgreSQL database and we will take advantage of advanced features included in Flask and Flask-RESTful that will allow us to easily organize code for complex APIs, such as models and blueprints.
Chapter 3, Improving Our API and Adding Authentication to it with Flask, improves the RESTful API in many ways. We will add user-friendly error messages when resources aren't unique. We will test how to update single or multiple fields with the PATCH method and we will create our own generic pagination class. Then, we will start working with authentication and permissions. We will add a user model and update the database. We will make many changes in the different pieces of code to achieve a specific security goal, and we will take advantage of Flask-HTTPAuth and passlib to use HTTP authentication in our API.
Chapter 4, Testing and Deploying an API in a Microservice with Flask, explains how to set up a testing environment. We will install pytest and the necessary plugins to make it easy to discover and execute unit tests, and we will create a new database to be used for testing. We will write a first round of unit tests, measure test coverage, and then write additional unit tests to improve test coverage. Finally, we will learn many considerations for deployment, scalability, and the execution of a Flask RESTful API within a microservice on the cloud.
Chapter 5, Developing RESTful APIs with Django 2.1, shows how to start working with Django and Django REST Framework, and we will create a RESTful Web API that performs CRUD operations on a simple SQLite database.
Chapter 6, Working with Class-Based Views and Hyperlinked APIs in Django 2.1, expands the capabilities of the RESTful API that we started in the previous chapter. We will change the ORM settings to work with a more powerful PostgreSQL 10.5 database and we will take advantage of advanced features included in Django REST Framework that allow us to reduce boilerplate code for complex APIs, such as class-based views.
Chapter 7, Improving Our API and Adding Authentication to it with Django, improves the RESTful API that we started in the previous chapter. We will add unique constraints to the model and update the database. We will make it easy to update single fields with the PATCH method and we will take advantage of pagination. We will start working with authentication, permissions, and throttling.
Chapter 8, Throttling, Filtering, Testing, and Deploying an API with Django 2.1, takes advantage of many features included in Django REST Framework to define throttling policies. We will use filtering, searching, and ordering classes to make it easy to configure filters, search queries, and the desired order for the results in HTTP requests. We will use the Browsable API feature to test these new features included in our API. We will write a first round of unit tests, run them with pytest, and then write additional unit tests to improve test coverage. Finally, we will learn many considerations for running Django RESTful APIs on the cloud.
Chapter 9, Developing RESTful APIs with Pyramid 1.10, works with Pyramid combined with other useful packages to create a RESTful Web API. We will design a RESTful API to interact with a simple data source. We will define the requirements for our API and we will understand the tasks performed by each HTTP method. We will create the class that represents a surfboard metric and we will use marshmallow to validate, serialize, and deserialize the model. We will write functions to process the different HTTP request methods and we will configure the view handlers.
Chapter 10, Developing RESTful APIs with Tornado 5.1.1, works with Tornado to create a RESTful Web API. We will design a RESTful API to interact with slow sensors and actuators. We will define the requirements for our API and we will understand the tasks performed by each HTTP method. We will create the classes that represent a drone and write code to simulate slow I/O operations that are called for each HTTP request method. We will write classes that represent request handlers and process the different HTTP requests and configure the URL patterns to route URLs to request handlers and their methods.
Chapter 11, Working with Asynchronous Code, Testing, and Deploying an API with Tornado, explains the difference between synchronous and asynchronous execution. We will create a new version of the RESTful API that takes advantage of the non-blocking features in Tornado combined with asynchronous execution. We will improve scalability for our existing API and we will make it possible to start executing other requests while waiting for the slow I/O operations with sensors and actuators. Then, we will set up a testing environment. We will install pytest to make it easy to discover and execute unit tests. We will write a first round of unit tests, measure test coverage, and then write additional unit tests to improve test coverage.
In order to work with the different samples for Python 3.6 and Python 3.7, you will need a computer with an Intel Core i3 or higher CPU and at least 4GB of RAM. You can work with any of the following operating systems:
Windows 7 or greater (Windows 8, Windows 8.1, or Windows 10)
Windows Server 2012 or greater (Windows Server 2016 or Windows Server 2019)
macOS Mountain Lion or greater
Any Linux version capable of running Python 3.7.1 and any modern browser with JavaScript support
You will need Python 3.7.1 or greater installed on your computer.
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packt.com
.
Select the
SUPPORT
tab.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-RESTful-Python-Web-Services-Second-Edition. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/9781789532227_ColorImages.pdf.
In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "We can include other contexts through the use of the include directive."
A block of code is set as follows:
html, body, #map { height: 100%; margin: 0; padding: 0}
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
[default]exten => s,1,Dial(Zap/1|30)exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)
Any command-line input or output is written as follows:
# cp /usr/src/asterisk-addons/configs/cdr_mysql.conf.sample
/etc/asterisk/cdr_mysql.conf
Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "Clicking the Next button moves you to the next screen."
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at [email protected] with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
In this chapter, we will start our journey toward RESTful Web APIs with Python 3.7 and four different web frameworks. Python is one of the most popular and versatile programming languages. There are thousands of Python packages, and these allow you to extend Python capabilities to any kind of domain you can imagine, such as web development, Internet of Things (IoT), artificial intelligence, machine learning, and scientific computing. We can work with many different web frameworks and packages to easily build simple and complex RESTful Web APIs with Python, and we can combine these frameworks with other Python packages.
We can leverage our existing knowledge of Python and all of its packages to code the different pieces of our RESTful Web APIs and their ecosystem. We can use the object-oriented features to create code that is easier to maintain, understand, and reuse. We can use all the packages that we are already comfortable with to interact with databases, web services, and different APIs. Python makes it easy for us to create RESTful Web APIs. In addition, lightweight frameworks, such as Flask, are ideal candidates for creating microservices that provide RESTful APIs. We don't need to learn another programming language; we can use the one we already know and love.
In this chapter, we will start working with Flask 1.0.2 and its Flask-RESTful extension, and we will create a RESTful Web API that performs CRUD (short for Create, Read, Update, and Delete) operations on a simple list. We will establish the baseline to develop microservices that provide a RESTful API with Flask. We will look at the following topics:
Design a RESTful API that performs CRUD operations in Flask with the Flask-RESTful extension
Understand the tasks performed by each HTTP method
Understand microservices
Work with lightweight virtual environments
Set up the virtual environment with Flask and its Flask-RESTful extension
Declare status codes for the responses with an enumerable
Create the model
Use a dictionary as a repository
Configure output fields
Work with resourceful routing on top of Flask pluggable views
Configure resource routing and endpoints
Make HTTP requests to the Flask API
Work with command-line tools to interact with the Flask API
Work with GUI tools to interact with the Flask API
Consume the API with other programming languages
Imagine that we have to configure the notification messages to be displayed in an OLED (short for Organic Light Emitting Diode) display wired to an IoT device. The IoT device is capable of running Python 3.7.1, Flask 1.0.2, and other Python packages. There is a team writing code that retrieves string messages that represent notifications from a dictionary and displays them in the OLED display wired to the IoT device. We have to start working on a mobile app and a website that has to interact with a RESTful API to perform CRUD operations with string messages that represent notifications.
We don't need an ORM (short for Object-Relational Mapping) because we won't persist the notifications on a database. We will just work with an in-memory dictionary as our data source. It is one of the requirements we have for this RESTful API. In this case, the RESTful Web Service will be running on the IoT device; that is, we will run the Flask development service on the IoT device.
We have chosen Flask because it is an extremely lightweight framework, we don't need to configure an ORM, and we want to start running the RESTful API on the IoT device as soon as possible to allow all the teams to interact with it. We consider that there will be a website that will be coded with Flask too, and therefore, we want to use the same web micro-framework to power the website and the RESTful Web Service. In addition, Flask is an appropriate choice to create a microservice that can run our RESTful API on the cloud.
There are many extensions available for Flask that make it easier to perform specific tasks with the Flask micro-framework. We will take advantage of Flask-RESTful, an extension that will allow us to encourage best practices while building our RESTful API. In this case, we will work with a Python dictionary as the data source. As previously explained, we will work with more complex data sources in forthcoming examples.
First, we must specify the requirements for our main resource—a notification. We need the following attributes or fields for a notification:
An integer identifier.
A string message.
A
TTL
(short for
Time to Live
), that is, a duration in seconds that will indicate the time the notification message has to be displayed on the OLED display.
A creation date and time. The timestamp will be added automatically when adding a new notification to the collection.
A notification category description, such as
Warning
or
Information
.
An integer counter that indicates the times when the notification message has been displayed on the OLED display.
A Boolean value that indicates whether the notification message was displayed at least once on the OLED display.
The following table shows the HTTP verbs, the scope, and the semantics for the methods that our first version of the API must support. Each method is composed of an HTTP verb and a scope, and all the methods have a well-defined meaning for all notifications and collections. In our API, each notification has its own unique URL:
HTTP verb
Scope
Semantics
GET
Collection of notifications
Retrieve all the stored notifications in the collection.
GET
Notification
Retrieve a single notification.
POST
Collection of notifications
Create a new notification in the collection.
PATCH
Notification
Update one or more fields for an existing notification.
DELETE
Notification
Delete an existing notification.
Let's consider that http://localhost:5000/service/notifications/ is the URL for the collection of notifications. If we add a number to the previous URL, we identify a specific notification whose ID is equal to the specified numeric value. For example, http://localhost:5000/service/notifications/5 identifies the notification whose ID is equal to 5.
We have to compose and send an HTTP request with the following HTTP verb (POST) and request URL (http://localhost:5000/service/notifications/) to create a new notification. In addition, we have to provide the JSON key-value pairs with the field names and the values to create the new notification. As a result of the request, the service will validate the values provided for the fields, making sure that it is a valid notification and persists it in the in-memory notifications dictionary. The service will return a 201 Created status code and a JSON body with the recently added notification serialized to JSON, including the assigned ID that was automatically generated by the service to the notification object:
POST http://localhost:5000/service/notifications/
We have to compose and send an HTTP request with the following HTTP verb (GET) and request URL (http://localhost:5000/service/notifications/{id}) to retrieve the notification whose ID matches the specified numeric value in the place where {id} is written. For example, if we use the http://localhost:5000/service/notifications/23 request URL, the service will retrieve the notification whose ID matches 23 from the dictionary. If a notification is found, the service will serialize the notification object into JSON and return a 200 OK status code and a JSON body with the serialized notification object. If no notification matches the specified ID or primary key, the service will return just a 404 Not Found status:
GET http://localhost:5000/service/notifications/{id}
We have to compose and send an HTTP request with the following HTTP verb (PATCH) and request URL (http://localhost:5000/service/notifications/{id}) to update one or more fields for the notification whose ID matches the specified numeric value in the place where {id} is written. In addition, we have to provide the JSON key-value pairs with the field names to be updated and their new values. As a result of the request, the service will validate the values provided for the fields, update these fields on the notification that matches the specified ID, and update the notification in the dictionary if it is a valid notification. The service will return a 200 OK status code and a JSON body with the recently updated notification serialized to JSON. If we provide invalid data for the fields to be updated, the service will return a 400 Bad Request status code. If the service doesn't find a notification with the specified ID, the service will return just a 404 Not Found status:
PATCH http://localhost:5000/service/notifications/{id}
We have to compose and send an HTTP request with the following HTTP verb (DELETE) and request URL (http://localhost:5000/service/notifications/{id}) to remove the notification whose ID matches the specified numeric value in the place where {id} is written. For example, if we use the http://localhost:5000/service/notifications/27 request URL, the service will delete the notification whose ID matches 27. As a result of the request, the service will retrieve a notification with the specified ID from the dictionary. If a notification is found, the service will ask the dictionary to delete the entry associated with this notification object and the service will return a 204 No Content status code. If no notification matches the specified ID, the service will return just a 404 Not Found status.
DELETE http://localhost:5000/service/notifications/{id}
In the last few years, many large and complex applications started shifting from a monolithic architecture to a microservices architecture. Instead of working with large and extremely complex web services, the microservices architecture proposes developing a collection of smaller, loosely-coupled services to implement all the features required by complex applications in a way that enables and simplifies continuous delivery.
RESTful APIs are essential pieces of the microservices architecture, and Python is extremely popular when shifting to this architecture. Each microservice can encapsulate a RESTful API that fulfills a specific and limited purpose. The microservice is self-contained, it is easy to maintain, and it helps to support continuous delivery.
As happens with any architecture, there are several ways to implement the microservices architecture. We will learn to encapsulate a RESTful API developed with Flask and Python into a microservice. This way, we will be able to leverage our skills by developing RESTful APIs and using them as the essential pieces to build self-contained and easy-to-maintain microservices.
Throughout this book, we will be working with different frameworks, packages, and libraries to create RESTful Web APIs and microservices, and therefore, it is convenient to work with Python virtual environments to isolate each development environment. Python 3.3 introduced lightweight virtual environments and they were improved in subsequent Python versions. We will work with these virtual environments and, therefore, you will need Python 3.7.1 or higher. You can read more about the PEP 405 Python virtual environment, which introduced the venv module, at https://www.python.org/dev/peps/pep-0405. All the examples for this book were tested on Python 3.7.1 on Linux, macOS, and Windows.
Each virtual environment we create with venv is an isolated environment and it will have its own independent set of installed Python packages in its site directories (folders). When we create a virtual environment with venv in Python 3.7 or higher, pip is included in the new virtual environment. Notice that the instructions provided are compatible with Python 3.7.1 or greater. The following commands assume that you have Python 3.7.1 installed on Linux, macOS, or Windows.
First, we have to select the target folder or directory for our lightweight virtual environment. The following is the path we will use in the example for Linux and macOS:
~/HillarPythonREST2/Flask01
The target folder for the virtual environment will be the HillarPythonREST2/Flask01 folder within our home directory. For example, if our home directory in macOS or Linux is /Users/gaston, the virtual environment will be created within /Users/gaston/HillarPythonREST2/Flask01. You can replace the specified path with your desired path in each command.
The following is the path we will use in the example for Windows:
%USERPROFILE%\HillarPythonREST2\Flask01
The target folder for the virtual environment will be the HillarPythonREST2\Flask01 folder within our user profile folder. For example, if our user profile folder is C:\Users\gaston, the virtual environment will be created within C:\Users\gaston\HillarPythonREST2\Flask01. Of course, you can replace the specified path with your desired path in each command.
In Windows PowerShell, the previous path would be:
$env:userprofile\HillarPythonREST2\Flask01
Now, we have to use the -m option, followed by the venv module name and the desired path, to make Python run this module as a script and create a virtual environment in the specified path. The instructions vary depending on the platform in which we are creating the virtual environment. Thus, make sure you follow the instructions for your operating system.
Open a Terminal in Linux or macOS and execute the following command to create a virtual environment:
python3 -m venv ~/HillarPythonREST2/Flask01
In Windows, in the Command Prompt, execute the following command to create a virtual environment:
python -m venv %USERPROFILE%\HillarPythonREST2\Flask01
In case you want to work with Windows PowerShell, execute the following command to create a virtual environment:
python -m venv $env:userprofile\HillarPythonREST2\Flask01
The previous commands don't produce any output. Any of the previous scripts created the specified target folder and installed pip by invoking ensurepip because we didn't specify the --without-pip option.
Now, we will analyze the directory structure for a virtual environment. The specified target folder has a new directory tree that contains Python executable files and other files that indicate it is a PEP 405 virtual environment.
In the root directory for the virtual environment, the pyenv.cfg configuration file specifies different options for the virtual environment and its existence is an indicator that we are in the root folder for a virtual environment. In Linux and macOS, the folder will have the following main subfolders:
bin
include
lib
lib/python3.7
lib/python3.7/site-packages
The following diagram shows the folders and files in the directory trees generated for the Flask01 virtual environment in macOS:
In Windows, the folder will have the following main subfolders:
Include
Lib
Lib\site-packages
Scripts
The directory trees for the virtual environment in each platform are the same as the layout of the Python installation in these platforms.
The following diagram shows the main folders in the directory trees generated for the virtual environment in Windows:
Now that we have created a virtual environment, we will run a platform-specific script to activate it. After we activate the virtual environment, we will install packages that will only be available in this virtual environment. This way, we will work with an isolated environment in which all the packages we install won't affect our main Python environment.
Run the following command in the Terminal in Linux or macOS. Notice that the results of this command will be accurate if you don't start a shell different to than the default shell in the Terminal session. In case you have doubts, check your Terminal configuration and preferences:
echo $SHELL
The command will display the name of the shell you are using in the Terminal. In macOS, the default is /bin/bash, and this means you are working with the bash shell. Depending on the shell, you must run a different command to activate the virtual environment in Linux or macOS.
If your Terminal is configured to use the bash shell in Linux or macOS, run the following command to activate the virtual environment. The command also works for the zsh shell:
source ~/HillarPythonREST2/Flask01/bin/activate
If your Terminal is configured to use either the csh or tcsh shell, run the following command to activate the virtual environment:
source ~/HillarPythonREST2/Flask01/bin/activate.csh
If your Terminal is configured to use the fish shell, run the following command to activate the virtual environment:
source ~/HillarPythonREST2/Flask01/bin/activate.fish
After you activate the virtual environment, the Command Prompt will display the virtual environment root folder name, enclosed in parentheses as a prefix of the default prompt, to remind us that we are working in the virtual environment. In this case, we will see (Flask01) as a prefix for the Command Prompt because the root folder for the activated virtual environment is Flask01.
The following screenshot shows the virtual environment activated in a macOS High Sierra Terminal with a bash shell, after executing the commands shown previously:
As we can see from the previous screenshot, the prompt changed from Gastons-MacBook-Pro:~ gaston$ to (Flask01) Gastons-MacBook-Pro:~ gaston$ following activation of the virtual environment.
In Windows, you can run either a batch file in the Command Prompt or a Windows PowerShell script to activate the virtual environment.
If you prefer the Command Prompt, run the following command in the Windows command line to activate the virtual environment:
%USERPROFILE%\HillarPythonREST2\Flask01\Scripts\activate.bat
The following screenshot shows the virtual environment activated in a Windows 10 Command Prompt, after executing the commands shown previously:
As we can see from the previous screenshot, the prompt changed from C:\Users\gaston\AppData\Local\Programs\Python\Python36 to (Flask01) C:\Users\gaston\AppData\Local\Programs\Python\Python36 following activation of the virtual environment.
If you prefer Windows PowerShell, launch it and run the following commands to activate the virtual environment. Notice that you must have script execution enabled in Windows PowerShell to be able to run the script:
cd $env:USERPROFILE
HillarPythonREST2\Flask01\Scripts\Activate.ps1
The following screenshot shows the virtual environment activated in the Windows 10 PowerShell, after executing the commands shown previously:
It is extremely easy to deactivate a virtual environment generated by means of the process explained previously. Deactivation will remove all the changes made in the environment variables and will change the prompt back to its default message.
In macOS or Linux, just type deactivate and press Enter.
In the Windows Command Prompt, you have to run the deactivate.bat batch file included in the Scripts folder. In our example, the full path for this file is %USERPROFILE%\HillarPythonREST2\Flask01\Scripts\deactivate.bat.
In Windows PowerShell, you have to run the Deactivate.ps1 script in the Scripts folder.
Now, we will create a notification_fields
