使用Python Dependency Injector构建Flask应用的完整教程

使用Python Dependency Injector构建Flask应用的完整教程

python-dependency-injector Dependency injection framework for Python python-dependency-injector 项目地址: https://gitcode.com/gh_mirrors/py/python-dependency-injector

前言

在现代Web应用开发中,依赖注入(Dependency Injection)是一种重要的设计模式,它可以帮助我们创建松耦合、可测试和可维护的代码。本教程将展示如何使用Python Dependency Injector库来构建一个遵循依赖注入原则的Flask应用。

项目概述

我们将构建一个名为"CodeHub Navigator"的Web应用,它可以帮助用户搜索代码托管平台上的代码仓库。这个应用将具有以下功能:

  1. 用户可以在首页输入搜索关键词
  2. 应用会调用API进行搜索
  3. 返回搜索结果页面,显示匹配的仓库信息
  4. 每个仓库显示:仓库名称、所有者信息和最新提交记录

环境准备

首先,我们需要设置开发环境:

# 创建项目目录
mkdir chnav-flask-tutorial
cd chnav-flask-tutorial

# 创建并激活虚拟环境
python3 -m venv venv
source venv/bin/activate

项目结构

我们的项目将采用以下结构:

./
├── codehubnavigator/
│   ├── __init__.py
│   ├── application.py
│   ├── containers.py
│   └── views.py
├── venv/
└── requirements.txt

安装依赖

在requirements.txt中添加以下依赖:

dependency-injector
flask

然后安装它们:

pip install -r requirements.txt

创建基础应用

让我们从创建一个最简单的Flask应用开始。

视图层

在views.py中添加基本视图:

"""Views module."""

def index():
    return "Hello, World!"

容器配置

containers.py将管理我们的依赖关系:

"""Containers module."""

from dependency_injector import containers

class Container(containers.DeclarativeContainer):
    pass

应用工厂

application.py创建Flask应用实例:

"""Application module."""

from flask import Flask
from .containers import Container
from . import views

def create_app() -> Flask:
    container = Container()
    
    app = Flask(__name__)
    app.container = container
    app.add_url_rule("/", "index", views.index)
    
    return app

运行应用

设置环境变量并运行:

export FLASK_APP=codehubnavigator.application
export FLASK_ENV=development
flask run

访问http://127.0.0.1:5000/应该能看到"Hello, World!"。

美化界面

让我们使用Bootstrap来美化界面。

添加Bootstrap依赖

更新requirements.txt:

dependency-injector
flask
bootstrap-flask

安装新依赖:

pip install -r requirements.txt

修改应用工厂

更新application.py以初始化Bootstrap:

from flask_bootstrap import Bootstrap

def create_app() -> Flask:
    # ...之前的代码...
    
    bootstrap = Bootstrap()
    bootstrap.init_app(app)
    
    return app

添加模板

创建templates目录和两个模板文件:

base.html - 基础布局模板:

<!doctype html>
<html lang="en">
<head>
    {% block head %}
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {% block styles %}
        {{ bootstrap.load_css() }}
    {% endblock %}
    <title>{% block title %}{% endblock %}</title>
    {% endblock %}
</head>
<body>
    {% block content %}{% endblock %}
    {% block scripts %}
        {{ bootstrap.load_js() }}
    {% endblock %}
</body>
</html>

index.html - 首页模板:

{% extends "base.html" %}

{% block title %}CodeHub Navigator{% endblock %}

{% block content %}
<div class="container">
    <h1>CodeHub Navigator</h1>
    <!-- 搜索表单和结果表格 -->
</div>
{% endblock %}

更新视图

修改views.py以渲染模板:

from flask import render_template

def index():
    return render_template("index.html")

集成API

现在让我们添加与API的集成。

添加PyGithub依赖

更新requirements.txt:

dependency-injector
flask
bootstrap-flask
pygithub
pyyaml

安装新依赖:

pip install -r requirements.txt

配置容器

更新containers.py:

from dependency_injector import containers, providers
from github import Github

class Container(containers.DeclarativeContainer):
    config = providers.Configuration(yaml_files=["config.yml"])
    
    github_client = providers.Factory(
        Github,
        login_or_token=config.github.auth_token,
        timeout=config.github.request_timeout,
    )

添加配置文件

创建config.yml:

github:
  request_timeout: 10

设置API令牌

更新application.py以从环境变量获取令牌:

def create_app() -> Flask:
    container = Container()
    container.config.github.auth_token.from_env("API_TOKEN")
    # ...其余代码...

设置环境变量:

export API_TOKEN=your_api_token_here

实现搜索服务

创建一个服务类来处理搜索逻辑。

services.py:

from github import Github, Repository, Commit

class SearchService:
    def __init__(self, github_client: Github):
        self._github_client = github_client
    
    def search_repositories(self, query, limit):
        repositories = self._github_client.search_repositories(
            query=query,
            **{"in": "name"},
        )
        return [self._format_repo(repo) for repo in repositories[:limit]]
    
    def _format_repo(self, repository: Repository):
        # 格式化仓库信息
        pass
    
    def _format_commit(self, commit: Commit):
        # 格式化提交信息
        pass

更新容器

将SearchService添加到容器中:

from . import services

class Container(containers.DeclarativeContainer):
    # ...之前的配置...
    
    search_service = providers.Factory(
        services.SearchService,
        github_client=github_client,
    )

完成视图层

最后,更新视图以使用搜索服务:

from dependency_injector.wiring import inject, Provide
from .services import SearchService
from .containers import Container

@inject
def index(
    search_service: SearchService = Provide[Container.search_service],
):
    query = request.args.get("query", "Dependency Injector")
    limit = request.args.get("limit", 10, int)
    
    repositories = search_service.search_repositories(query, limit)
    
    return render_template(
        "index.html",
        query=query,
        limit=limit,
        repositories=repositories,
    )

总结

通过本教程,我们完成了以下工作:

  1. 创建了一个基本的Flask应用结构
  2. 使用Dependency Injector管理依赖关系
  3. 集成了Bootstrap前端框架
  4. 实现了与API的交互
  5. 构建了完整的搜索功能

这个项目展示了如何在Flask应用中有效地使用依赖注入模式,使代码更加模块化、可测试和可维护。

python-dependency-injector Dependency injection framework for Python python-dependency-injector 项目地址: https://gitcode.com/gh_mirrors/py/python-dependency-injector

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

舒蝶文Marcia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值