Python教程-Python中的Graphene
Python被认为是最受欢迎的通用编程语言之一,因为它易于使用且简单。此外,GraphQL,一种用于应用程序编程接口和服务器运行时的声明性查询语言,与Python非常搭配。然而,目前很少有全面的学习材料可用,提供了GraphQL与Python的逐步使用指南。
Graphene是用Python等编程语言创建GraphQL端点的最佳库之一。它具有出色的灵活性,包含了针对Django、SQLAlchemy和MongoDB的ORM的相对完整的辅助库。它相对容易实现一些简单的功能。但是,Graphene的文档还有很大的改进空间。通过文档,您可以轻松入门GraphQL,但要创建坚实的、适用于生产的、功能强大的应用就需要更多工作。
在以下教程中,我们将重点讨论如何使用Graphene库在Python中使用GraphQL。
但在深入讨论之前,让我们简要讨论教程的目标和要求。
目标
我们将构建一个基于网络爬虫服务的项目。我们将使用提取库来实现这个项目。
这个网络爬虫服务将以以下方式提交客户端请求:
{
website(url: "https://www.javatiku.com/python-tutorial") {
title
image
}
}
服务器的响应将是:
{
"data": {
"website": {
"title": "Learn Python Tutorial - javatiku",
"image": "https://static.javatiku.com/images/logo/jtp_logo",
}
}
}
每个网站还将包括一个描述字段。
设置环境
假设我们已经在本地安装了Python 3,让我们首先为依赖项创建一个虚拟环境。为了创建一个虚拟环境,我们可以按照以下方式安装virtualenv:
语法:
$ pip install virtualenv
$ virtualenv env
输出:
created virtual environment CPython3.9.0.final.0-64 in 45108ms
creator CPython3Windows(dest=D:\Python\env, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\Mango\AppData\Local\pypa\virtualenv)
added seed packages: pip==21.2.2, setuptools==57.4.0, wheel==0.36.2
activators BashActivator,BatchActivator,FishActivator,PowerShellActivator,PythonActivator
现在,让我们激活虚拟环境。
激活虚拟环境的方式在Windows、MacOS和Linux上有所不同。
对于Windows:
语法:
$ env\Scripts\activate
对于MacOS / Linux:
语法:
$ source env/bin/activate
现在,让我们了解项目所需的库。
- Extraction
- Graphene
- Flask-graphql
- Requests
我们可以逐个安装它们,使用以下示例中的pip安装器:
语法:
$ pip install extraction
$ pip install graphene
$ pip install flask-graphql
$ pip install requests
或者,我们可以将它们作为一组安装,如下所示:
语法:
$ pip install extraction graphene flask-graphql requests
爬取和提取
在我们开始使用GraphQL之前,让我们简要了解从网站爬取和提取数据的以下代码片段。
示例:
# importing the required libraries
import graphene
import extraction
import requests
# defining the function for extraction
def extract(myurl):
myhtml = requests.get(myurl).text
extrctd = extraction.Extractor().extract(myhtml, source_url = myurl)
print(extrctd)
# calling the function
extract('https://www.javatiku.com/python-tutorial')
解释:
在上面的代码片段中,我们导入所需的库并定义了一个名为extract()的提取函数。
在函数内部,我们使用requests模块从URL请求详细信息,并将这些详细信息存储在名为myhtml的变量中。然后,我们使用提取模块的Extractor()函数从用户提取所需的数据,并将其打印出来。
最后,我们调用extract()函数,指定要从中提取数据的URL。
我们可以观察到,每个提取的对象都生成不同部分的可用数据,如title、url、image、description和feed。
模式
GraphQL模式存在于每个GraphQL API的基础上。它有助于描述所暴露API的类型、字段和对象。我们使用Graphene库来将模式描述为Python中的一个对象。
我们可以以非常简单的方式编写一个描述提取的网站的模式,如下所示:
示例:
# importing the graphene library
import graphene
# defining a class
class my_Website(graphene.ObjectType):
my_url = graphene.String(required = True)
my_title = graphene.String()
my_description = graphene.String()
my_image = graphene.String()
解释:
在上面的代码片段中,我们导入了graphene库并定义了一个名为my_Website的类,该类继承了graphene库的ObjectType类。这个ObjectType充当了用于定义模式中字段之间关系的构建块。在类内部,我们定义了不同的字段,并使用graphene库的String()来描述字段的类型;然而,每个字段都可以是我们定义的另一个对象,或者是多个其他内容,如列表、标量、枚举等。
一个令人惊讶的事实是,我们还需要编写一个描述我们将用来检索这些对象的查询的模式:
示例:
# importing the graphene library
import graphene
# defining the class
class my_Query(graphene.ObjectType):
website1 = graphene.Field(my_Website, my_url = graphene.String())
# defining the function
def resolv_website(self, info, my_url):
extrctd = extract(my_url)
return my_Website(my_urlmy_url = my_url,
my_title = extrctd.title,
my_description = extrctd.description,
my_image = extrctd.image,
)
解释:
在上面的代码片段中,website1是一个我们可以对其进行查询的对象类型,my_url是我们将传递给解析函数的参数,然后website1对象通过每个请求调用resolv_website函数。
最后一步是创建一个graphene.Schema的实例,我们将在服务器上使用它来描述我们创建的新API。让我们考虑以下代码片段:
示例:
my_schema = graphene.Schema(query = my_Query)
完成了这些步骤,我们已经成功创建了项目的模式。
完整的代码如下所示:
文件:my_schema.py
# importing the required libraries
import graphene
import extraction
import requests
# defining the function for extraction
def extract(my_url):
myhtml = requests.get(my_url).text
extrctd = extraction.Extractor().extract(myhtml, source_url = my_url)
print(extrctd)
return extrctd
# defining the class
class my_Website(graphene.ObjectType):
my_url = graphene.String(required = True)
my_title = graphene.String()
my_description = graphene.String()
my_image = graphene.String()
# defining the class
class my_Query(graphene.ObjectType):
website1 = graphene.Field(my_Website, my_url = graphene.String())
# defining the function
def resolv_website(self, info, my_url):
extrctd = extract(my_url)
return my_Website(my_urlmy_url = my_url,
my_title = extrctd.title,
my_description = extrctd.description,
my_image = extrctd.image,
)
my_schema = graphene.Schema(query = my_Query)
服务器
现在,我们已经编写了模式,可以使用flask和flask-graphql的帮助来通过HTTP提供它。
让我们考虑以下代码片段,以创建服务器。
文件:my_server.py
# importing the required library
from flask import Flask
from flask_graphql import GraphQLView
import my_schema
# using the Flask() function to create app
my_app = Flask(__name__)
# setting URL rules
my_app.add_url_rule(
'/',
view_func = GraphQLView.as_view('graphql', schema = my_schema, graphiql = True)
)
my_app.run()
解释:
在上面的代码片段中,我们导入了所需的库,以及我们之前创建的名为my_schema的文件。然后,我们使用Flask()函数指定参数name创建应用程序。我们还使用add_url_rule()函数为URL添加不同规则,其中我们指定了不同的参数,并在最后使用run()函数来执行应用程序。
现在,我们可以使用以下语法运行服务器:
语法:
$ python my_server.py
一旦输入上述语法,服务器将在localhost:5000
或http://127.0.0.1:5000/
上开始运行。
以下是相应的输出:
输出:
Serving Flask app "my_server" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
客户端
尽管存在专门的GraphQL客户端,用于执行新API的API请求,但我们可以继续使用我们习惯的HTTP客户端,例如在以下示例中使用requests。
文件:my_client.py
# importing the requests library
import requests
# defining the query
my_query = """
{
website(url: "https://www.javatiku.com/python-tutorial") {
title
image
description
}
}
"""
# defining the response
my_response = requests.post("http://127.0.0.1:5000/", params = {'query': my_query})
print(my_response.text)
输出:
{
"data": {
"website": {
"title": "Learn Python Tutorial - javatiku",
"image": "https://static.javatiku.com/images/logo/jtp_logo",
"description": "Learn Python Tutorial for beginners and profession"
}
}
}
解释:
在上面的代码片段中,我们导入requests库并定义了一个名为my_query的查询,将发送到服务器。然后,我们定义了一个名为my_response的变量,它将以响应的形式存储从服务器返回的数据。最后,我们将响应打印给用户。
用户还可以自定义my_query变量的内容,以检索不同的字段,甚至可以使用别名等内容,以一次检索多个对象。
自省
GraphQL的服务器支持自省是其最强大的方面之一。自省允许人类和自动化工具都能够了解可用的对象和操作。
一个很好的例子是,当我们运行我们构建的示例时,我们可以导航到http://127.0.0.1:5000
并使用GraphiQL直接测试新API。http://127.0.0.1:5000
并使用GraphiQL直接测试新API。
这些功能不仅限于GraphiQL,我们也可以使用相同的查询界面来集成自省,以查询新API。让我们考虑一个简单的例子,其中我们询问示例服务公开的可用查询:
{
__type(name: "Query") {
fields {
name
args {
name
}
}
}
}
服务器的响应将是:
{
"data": {
"__type": {
"fields": [
{
"name": "website",
"args": [{ "name": "url" }]
}
]
}
}
}
还有许多基于自省的查询可用,虽然编写起来可能有些复杂,但它们为工具构建者提供了巨大的潜力。