sqlalchemy 使用_使用Bottle,SQLAlchemy和Twitter API构建简单的Web应用

sqlalchemy 使用

daily python tip

This is a guest blog post by Bob Belderbos. Bob is a driven Pythonista working as a software developer at Oracle. He is also co-founder of PyBites, a Python blog featuring code challenges, articles, and news. Bob is passionate about automation, data, web development, code quality, and mentoring other developers.

这是Bob Belderbos的客座博客文章。 鲍勃(Bob)是一名受驱动的Pythonista,在Oracle担任软件开发人员。 他还是Python博客PyBites的联合创始人,该博客介绍了代码挑战,文章和新闻。 Bob对自动化,数据,Web开发,代码质量以及指导其他开发人员充满热情。



Last October we challenged our PyBites’ audience to make a web app to better navigate the Daily Python Tip feed. In this article, I’ll share what I built and learned along the way.

去年10月,我们 PyBites的受众发起了挑战,要求他们制作一个Web应用程序以更好地浏览Daily Python Tip提要。 在本文中,我将分享我在此过程中构建和学习的内容。

In this article you will learn:

在本文中,您将学习:

  1. How to clone the project repo and set up the app.
  2. How to use the Twitter API via the Tweepy module to load in the tweets.
  3. How to use SQLAlchemy to store and manage the data (tips and hashtags).
  4. How to build a simple web app with Bottle, a micro web-framework similar to Flask.
  5. How to use the pytest framework to add tests.
  6. How Better Code Hub’s guidance led to more maintainable code.
  1. 如何克隆项目存储库并设置应用程序。
  2. 如何通过Tweepy模块使用Twitter API加载推文。
  3. 如何使用SQLAlchemy存储和管理数据(技巧和主题标签)。
  4. 如何使用Bottle(类似于Flask的微型网络框架)构建简单的Web应用程序。
  5. 如何使用pytest框架添加测试。
  6. 更好的代码中心的指导如何使代码更具可维护性。

If you want to follow along, reading the code in detail (and possibly contribute), I suggest you fork the repo. Let’s get started.

如果您想继续阅读,详细阅读代码(并可能会做一些贡献),建议您分叉repo 。 让我们开始吧。

项目设置 (Project Setup)

First, Namespaces are one honking great idea so let’s do our work in a virtual environment. Using Anaconda I create it like so:

首先,命名空间是一个很棒的主意,因此让我们在虚拟环境中进行工作。 使用Anaconda我可以这样创建它:

1
1

Create a production and a test database in Postgres:

在Postgres中创建生产和测试数据库:

1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8

We’ll need credentials to connect to the the database and the Twitter API (create a new app first). As per best practice configuration should be stored in the environment, not the code. Put the following env variables at the end of ~/virtualenvs/pytip/bin/activate, the script that handles activation / deactivation of your virtual environment, making sure to update the variables for your environment:

我们需要凭据才能连接到数据库和Twitter API(首先创建一个新应用 )。 按照最佳实践,配置应存储在环境中,而不是代码中。 将以下env变量放在〜/ virtualenvs / pytip / bin / activate的末尾,该脚本用于处理虚拟环境的激活/停用,并确保为您的环境更新变量:

1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8

In the deactivate function of the same script, I unset them so we keep things out of the shell scope when deactivating (leaving) the virtual environment:

在同一脚本的deactivate函数中,我取消了它们的设置,因此在停用(离开)虚拟环境时,我们将其排除在Shell作用域之外:

1
1
2
2
3
3
4
4
5
5
6
6

Now is a good time to activate the virtual environment:

现在是激活虚拟环境的好时机:

1
1

Clone the repo and, with the virtual environment enabled, install the requirements:

克隆存储库,并在启用虚拟环境的情况下安装要求:

1
1
2
2

Next, we import the collection of tweets with:

接下来,我们使用以下命令导入推文集合:

1
1

Then, verify that the tables were created and the tweets were added:

然后,验证是否已创建表并添加了鸣叫:

1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
11
11
12
12
13
13
14
14
15
15
16
16
17
17
18
18
19
19
20
20
21
21
22
22
23
23
24
24
25
25

Now let’s run the tests:

现在让我们运行测试:

1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10

And lastly run the Bottle app with:

最后使用以下命令运行Bottle应用程序:

1
1

Browse to http://localhost:8080 and voilà: you should see the tips sorted descending on popularity. Clicking on a hashtag link at the left, or using the search box, you can easily filter them. Here we see the pandas tips for example:

浏览到http:// localhost:8080和voilà:您应该看到提示按受欢迎程度降序排列。 单击左侧的主题标签链接,或使用搜索框,可以轻松过滤它们。 这里我们以熊猫提示为例:

daily python tip

The design I made with MUI – a lightweight CSS framework that follows Google’s Material Design guidelines.

我使用MUI进行的设计-一种轻量级CSS框架,遵循Google的Material Design指南。

实施细节 (Implementation Details)

数据库和SQLAlchemy (The DB and SQLAlchemy)

I used SQLAlchemy to interface with the DB to prevent having to write a lot of (redundant) SQL.

我使用SQLAlchemy与数据库进行交互,以防止不得不编写大量(冗余)SQL。

In tips/models.py, we define our models – Hashtag and Tip – that SQLAlchemy will map to DB tables:

tip / models.py中 ,我们定义了模型HashtagTip -SQLAlchemy将映射到数据库表:

1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
11
11
12
12
13
13
14
14
15
15
16
16
17
17
18
18
19
19
20
20
21
21
22
22
23
23
24
24
25
25
26
26
27
27

In tips/db.py, we import these models, and now it’s easy to work with the DB, for example to interface with the Hashtag model:

tips / db.py中 ,我们导入了这些模型,现在可以轻松地与数据库一起使用,例如与Hashtag模型对接:

1
1
2
2

And:

和:

1
1
2
2
3
3
4
4

查询Twitter API (Query the Twitter API)

We need to retrieve the data from Twitter. For that, I created tasks/import_tweets.py. I packaged this under tasks because it should be run in a daily cronjob to look for new tips and update stats (number of likes and retweets) on existing tweets. For the sake of simplicity I have the tables recreated daily. If we start to rely on FK relations with other tables we should definitely choose update statements over delete+add.

我们需要从Twitter检索数据。 为此,我创建了task / import_tweets.py 。 我将其打包在任务下,因为它应该在日常cronjob中运行,以查找新的提示并更新现有推文的统计信息(喜欢和转发的次数)。 为了简单起见,我每天都会重新创建表。 如果我们开始依赖与其他表的FK关系,则我们绝对应该选择update语句,而不是delete + add。

We used this script in the Project Setup. Let’s see what it does in more detail.

我们在项目设置中使用了此脚本。 让我们更详细地了解它的作用。

First, we create an API session object which we pass to tweepy.Cursor. This feature of the API is really nice: it deals with pagination, iterating through the timeline. For the amount of tips – 222 at the time I write this – it’s really fast. The exclude_replies=True and include_rts=False arguments are convenient because we only want Daily Python Tip’s own tweets (not re-tweets).

首先,我们创建一个API会话对象,该对象将传递给tweepy.Cursor 。 API的此功能非常好:它处理分页,并在时间轴上迭代。 对于技巧的数量(我撰写本文时为222),它的速度确实非常快。 exclude_replies=Trueinclude_rts=False参数很方便,因为我们只需要Daily Python Tip自己的推文(而不是重新推文)。

Extracting hashtags from the tips requires very little code.

从技巧中提取主题标签只需要很少的代码。



First, I defined a regex for a tag:

首先,我为标签定义了一个正则表达式:

1
1

Then, I used findall to get all tags.

然后,我使用findall来获取所有标签。

I passed them to collections.Counter which returns a dict like object with the tags as keys, and counts as values, ordered in descending order by values (most common). I excluded the too common python tag which would skew the results.

我将它们传递给collections.Counter ,它返回像dict这样的字典,对象以标签为键,并计数为值,按值的降序排列(最常见)。 我排除了太普通的python标签,它会使结果偏斜。

1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8

Finally, the import_* functions in tasks/import_tweets.py do the actual import of the tweets and hashtags, calling add_* DB methods of the tips directory/package.

最后, tasks / import_tweets.py中import_*函数会实际导入推文和主题标签,并调用tips目录/程序包的add_* DB方法。

使用Bottle创建一个简单的Web应用 (Make a Simple web app with Bottle)

With this pre-work done, making a web app is surprisingly easy (or not so surprising if you used Flask before).

完成这些准备工作后,制作Web应用程序非常简单(如果您以前使用过Flask,则不会那么令人惊讶)。

First of all meet Bottle:

首先遇到瓶子

Bottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is distributed as a single file module and has no dependencies other than the Python Standard Library.

Bottle是用于Python的快速,简单且轻量级的WSGI微型Web框架。 它作为单个文件模块分发,除Python标准库外没有其他依赖项。

Nice. The resulting web app comprises of < 30 LOC and can be found in app.py.

真好 生成的Web应用程序包含<30 LOC,可以在app.py中找到。

For this simple app, a single method with an optional tag argument is all it takes. Similar to Flask, the routing is handled with decorators. If called with a tag it filters the tips on tag, else it shows them all. The view decorator defines the template to use. Like Flask (and Django) we return a dict for use in the template.

对于这个简单的应用程序,只需一个带有可选tag参数的方法。 与Flask相似,路由由装饰器处理。 如果使用标签调用,它将过滤标签上的提示,否则将全部显示。 视图装饰器定义要使用的模板。 像Flask(和Django)一样,我们返回一个在模板中使用的字典。

1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
11
11

As per documentation, to work with static files, you add this snippet at the top, after the imports:

根据文档 ,要使用静态文件,请在导入之后在顶部添加以下代码段:

1
1
2
2
3
3

Finally, we want to make sure we only run in debug mode on localhost, hence the APP_LOCATION env variable we defined in Project Setup:

最后,我们要确保仅在本地主机上以调试模式运行,因此要在项目设置中定义的APP_LOCATION env变量:

1
1
2
2
3
3
4
4

瓶模板 (Bottle Templates)

Bottle comes with a fast, powerful and easy to learn built-in template engine called SimpleTemplate.

Bottle带有一个名为SimpleTemplate的快速,强大且易于学习的内置模板引擎。

In the views subdirectory I defined a header.tpl, index.tpl, and footer.tpl. For the tag cloud, I used some simple inline CSS increasing tag size by count, see header.tpl:

views子目录中,我定义了header.tpl,index.tpl和footer.tpl。 对于标签云,我使用了一些简单的嵌入式CSS来按数量增加标签大小,请参见header.tpl

1
1
2
2
3
3

In index.tpl we loop over the tips:

index.tpl中,我们遍历提示:

1
1
2
2
3
3
4
4
5
5
6
6

If you are familiar with Flask and Jinja2 this should look very familiar. Embedding Python is even easier, with less typing – (% ... vs {% ... %}).

如果您熟悉Flask和Jinja2,则应该非常熟悉。 嵌入Python更加容易,而且键入更少– (% ... vs {% ... %} )。

All css, images (and JS if we’d use it) go into the static subfolder.

所有的css,图片(如果使用的话,也包含JS)都放入静态子文件夹。

And that’s all there is to making a basic web app with Bottle. Once you have the data layer properly defined it’s pretty straightforward.

这就是使用Bottle创建基本的Web应用程序的全部内容。 一旦正确定义了数据层,就很简单了。

用pytest添加测试 (Add tests with pytest)

Now let’s make this project a bit more robust by adding some tests. Testing the DB required a bit more digging into the pytest framework, but I ended up using the pytest.fixture decorator to set up and tear down a database with some test tweets.

现在,通过添加一些测试,使该项目更加健壮。 测试数据库需要进一步深入pytest框架,但最终我使用了pytest.fixture装饰器通过一些测试推文来建立和拆除数据库。

Instead of calling the Twitter API, I used some static data provided in tweets.json. And, rather than using the live DB, in tips/db.py, I check if pytest is the caller (sys.argv[0]). If so, I use the test DB. I probably will refactor this, because Bottle supports working with config files.

我没有调用Twitter API,而是使用了tweets.json中提供的一些静态数据。 并且,而不是使用实时数据库,在tips / db.py中 ,我检查pytest是否是调用方( sys.argv[0] )。 如果是这样,我将使用测试数据库。 我可能会重构它,因为Bottle支持使用config文件

The hashtag part was easier to test (test_get_hashtag_counter) because I could just add some hashtags to a multiline string. No fixtures needed.

主题标签部分更易于测试( test_get_hashtag_counter ),因为我可以将一些主题标签添加到多行字符串中。 无需固定装置。

代码质量至关重要–更好的代码中心 (Code quality matters – Better Code Hub)

Better Code Hub guides you in writing, well, better code. Before writing the tests the project scored a 7:

更好的代码中心可以指导您编写更好的代码。 在编写测试之前,项目的得分为7:

better code hub

Not bad, but we can do better:

不错,但是我们可以做得更好:

  1. I bumped it to a 9 by making the code more modular, taking the DB logic out of the app.py (web app), putting it in the tips folder/ package (refactorings 1 and 2)

  2. Then with the tests in place the project scored a 10:

  1. 我通过使代码更具模块化,将DB逻辑从app.py(Web应用程序)中删除,并将其放在tips文件夹/程序包中(将12分解),将其提高到了9。

  2. 然后通过适当的测试,该项目获得了10分:

better code hub

结论与学习 (Conclusion and Learning)

Our Code Challenge #40 offered some good practice:

我们的代码挑战40提供了一些好的做法:

  1. I built a useful app which can be expanded (I want to add an API).
  2. I used some cool modules worth exploring: Tweepy, SQLAlchemy, and Bottle.
  3. I learned some more pytest because I needed fixtures to test interaction with the DB.
  4. Above all, having to make the code testable, the app became more modular which made it easier to maintain. Better Code Hub was of great help in this process.
  5. I deployed the app to Heroku using our step-by-step guide.
  1. 我构建了一个可以扩展的有用应用程序(我想添加一个API)。
  2. 我使用了一些很酷的模块值得探索:Tweepy,SQLAlchemy和Bottle。
  3. 我学习了更多的pytest,因为我需要测试夹具来测试与数据库的交互。
  4. 最重要的是,由于必须使代码可测试,因此该应用程序变得更加模块化,从而更易于维护。 更好的代码中心在此过程中有很大帮助。
  5. 我使用分步指南将应用程序部署到了Heroku

我们挑战你 (We Challenge You)

The best way to learn and improve your coding skills is to practice. At PyBites we solidified this concept by organizing Python code challenges. Check out our growing collection, fork the repo, and get coding!

学习和提高编码技能的最佳方法是练习 。 在PyBites,我们通过组织Python代码挑战巩固了这一概念。 看看我们不断增长的收藏分叉仓库 ,并获得编码!

Let us know if you build something cool by making a Pull Request of your work. We have seen folks really stretching themselves through these challenges, and so did we.

让我们知道您是否通过对您的工作提出请求来构建一些很棒的东西。 我们已经看到人们真的在这些挑战中伸了个懒腰,我们也是如此。

Happy coding!

编码愉快!

联络资料 (Contact Info)

翻译自: https://www.pybloggers.com/2017/12/building-a-simple-web-app-with-bottle-sqlalchemy-and-the-twitter-api/

sqlalchemy 使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值