aiohttp 后端的 Reactjs 前端示例

dem*_*ica 5 reactjs aiohttp

您好,我构建了一个 aiohttp 应用程序,它作为运行定期任务的自治系统运行,并返回 json 和文本响应以获取操作状态,并支持使用各种 GET、PUT 和 POST 请求接收任务触发器。

例如。我已经实现了一个 GET 请求,用于检索当前正在运行的任务列表作为 json 响应

我想使用 Reactjs UI 作为前端来消耗我的 aiohttp 应用程序的请求。这个 React 应用程序就像 aiohttp 应用程序的管理面板。

我看到这里有两种架构选择 -

选项1。将 React 应用程序嵌入到 aiohttp 应用程序的代码库中,并让 aiohttp/gunicorn 将整个项目作为一台服务器提供服务

选项2。将 aiohttp 后端与 React 前端分开

我不想让 aiohttp 为 React 应用程序提供静态文件和 html,而是想通过在单独的 Docker 容器上运行 ReactJS 应用程序来实现关注点的逻辑分离,并具有以下预期行为

  1. 如果 aiohttp API 端点已关闭且 React 应用程序已启动 -

React 应用程序在 UI 组件中显示“后端不可用”,这些组件依赖于 aiohttp 后端实现的 API 并从中提取数据

  1. 如果aiohttp和react都启动了,react应用程序应该能够定期调用它需要的各种aiohttp处理程序,用数据填充UI组件并显示响应式UI

这也将有助于 React 前端与我的堆栈中的其他 REST API(例如 docker)集成,这样我就可以为我的整个堆栈构建一个完整的管理界面

我无法找到一个简洁的示例来帮助我为此类应用程序实现具有延迟加载的反应前端(还需要了解是否可以使其与 aiohttp 应用程序调用反应应用程序以避免轮询的推送请求一起使用)

我是 JS 世界的新手,但在 python、asyncio 和 aiohttp 上做了很多工作

问题 -

  1. 我是否选择了一个可靠的选项(选项 2)?是否存在一些可以通过选项 1 避免的已知/常见问题?

  2. 请帮助我提供一个简单的分步示例或工作代码存储库,说明如何为我的应用程序构建 React 前端,而无需过多更改我的 aiohttp 处理程序

  3. 我是否可以向我的 aiohttp 应用程序添加功能,以便它可以调用 React 应用程序来提交状态更新,而不是等待 React 应用程序在下一次轮询中调用 UI

我确信这些问题暴露了我对这些东西如何工作的无知程度。非常感谢任何帮助

dem*_*ica 4

沉默的反对者吃了我的问题,所以这是我用来作为权宜之计的东西,直到我弄清楚事情。即使-1旅掌握了这个,至少也会对从google过来的人有所帮助。

我发现这个项目 - https://github.com/aio-libs/aiohttp_admin建立在这个项目 - https://github.com/marmelab/ng-admin的基础上,这样你就可以使用 Angular 构建一个 aiohttp 管理界面。

ng-admin 的发布者也发布了https://github.com/marmelab/admin-on-rest - 这是我用我的 aiohttp 处理程序尝试的东西(如果你想像我一样遵循选项 2,你将需要 COR)

aiohttp_admin 有一个未解决的问题,需要迁移到 admin-on-rest https://github.com/aio-libs/aiohttp_admin/issues/359

所以我想这将为每个需要此功能且不是reactjs程序员的人解决问题

这就是我可以开始工作的内容(我仍在尝试解决分页错误,需要为我的应用程序开发自定义restclient)

下面的示例应该可以帮助某人了解让 admin-on-rest 与您的 aiohttp API 对话所需的所有代码以及如何序列化您的响应。谨慎使用,这并不是 100% 有效

aiohttp 处理程序 -

async def get_limits(request):
    """
    ---
    description: This end-point lists task IDs.
    tags:
    - scheduler
    produces:
    - application/json
    responses:
        "200":
            description: successful operation returns task IDs
        "405":
            description: invalid HTTP Method
    """
    limits = copy(request.app.limits)
    pages = str(len(limits.keys()))
    response_ = serialize_limits(limits)
    return json_response(response_[0], headers={
        "X-Total-Count": pages, "X-Content-Range": pages})
Run Code Online (Sandbox Code Playgroud)

序列化器 -

import toastedmarshmallow
from marshmallow import Schema, fields


class LimitSchema(Schema):
    """
    schema for scheduler limits
    """
    resource = fields.Str()
    limit = fields.Int()
    id = fields.Int()


class Limit(object):
    """
    model for scheduler limits
    """

    def __init__(self, resource, limit, id):
        self.resource = resource
        self.limit = limit
        self.id = id

    def __repr__(self):
        return '<Limit(resource={self.resource!r})>'.format(self=self)


def serialize_limits(dict_):
    """
    output a serialized version of an input dict
    :param dict_:
    :return:
    """
    limits = []
    schema = LimitSchema(many=True)
    schema.jit = toastedmarshmallow.Jit
    id = 0
    for key, value in dict_.items():
        limits.append(Limit(resource=key, limit=value, id=id))
        id += 1

    return schema.dump(limits)
Run Code Online (Sandbox Code Playgroud)

反应js-

list.js -

import React from 'react';
import { List, Datagrid, TextField } from 'admin-on-rest';

export const Limitlist = (props) => (
    <List title="Limits" {...props}>
        <Datagrid>
            <TextField source="resource" />
            <TextField source="limit" />
        </Datagrid>
        </List>
);
Run Code Online (Sandbox Code Playgroud)

应用程序.js

import React from 'react';
import { jsonServerRestClient, simpleRestClient, Admin, Resource} from 'admin-on-rest';
import myApiRestClient from './avionicsRestClient';
import { Limitlist } from './limits';
import Dashboard from './Dashboard';


const App = () => (
<Admin restClient={myApiRestClient}>
<Resource name="limits" list={Limitlist} />
</Admin>
);

export default App;
Run Code Online (Sandbox Code Playgroud)