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 

现在,让我们了解项目所需的库。

  1. Extraction
  2. Graphene
  3. Flask-graphql
  4. 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、descriptionfeed

模式

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)  

服务器

现在,我们已经编写了模式,可以使用flaskflask-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:5000http://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" }]
        }
      ]
    }
  }
}

还有许多基于自省的查询可用,虽然编写起来可能有些复杂,但它们为工具构建者提供了巨大的潜力。

标签: Tkinter教程, Tkinter安装, Tkinter库, Tkinter入门, Tkinter学习, Tkinter入门教程, Tkinter, Tkinter进阶, Tkinter指南, Tkinter学习指南, Tkinter进阶教程, Tkinter编程