To connect to the database and the Twitter API, we'll need credentials (create a new app first). Best practices recommend that environment data, not code, be used to hold configuration. Make sure to change the environment-specific variables before adding the following env variables at the end of your virtual environment's activation/deactivation script, located at /virtualenvs/pytip/bin/activate:
export DATABASE_URL='postgres://postgres:password@localhost:6273/pytip'
# twitter
export CONSUMER_KEY='xyz'
export CONSUMER_SECRET='xyz'
export ACCESS_TOKEN='xyz'
export ACCESS_SECRET='xyz'
# if deploying it, set this to 'heroku'
export APP_LOCATION=local
To prevent objects from entering the shell scope after deactivating (leaving) the virtual environment, I unset them in the deactivate method of the same script.
Visit http://localhost:8080 and bingo. You should see the suggestions listed in order of decreasing popularity. You may quickly filter them by using the search box or a hashtag link on the left. Here are some examples of panda advice:
Understanding the Implementation🚀
🛢️DataBase and SQLAlchemy
We have used SQLAlchemy to interface with the DB to prevent having to write a lot of (redundant) SQL in our App.
In tips/models.py, we define our own models - Hashtag and Tip - that SQLAlchemy will map to the DB tables in the SQL:
from sqlalchemy import Column, Sequence, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Hashtag(Base):
__tablename__ = 'hashtags'
id_name = Column(Integer, Sequence('id_seq'), primary_key=True)
name = Column(String(20))
count = Column(Integer)
def __repr__(self):
return "<Hashtag('%s', '%d')>" % (self.name, self.count)
class Tip(Base):
__tablename__ = 'tips'
id_name = Column(Integer, Sequence('id_seq'), primary_key=True)
tweetid = Column(String(22))
text = Column(String(300))
created = Column(DateTime)
likes = Column(Integer)
retweets = Column(Integer)
def __repr__(self):
return "<Tip('%d', '%s')>" % (self. id_name , self.text)
You can also try this code with Online Python Compiler
We must gather the data from Twitter. We have made tasks/import tweets.py to do that. I packaged this under tasks since a daily cronjob should be used to search for fresh tips and update statistics (such as the number of likes and retweets) on posted tweets. I have the tables updated every day for the purpose of simplicity. Update statements are always preferable to delete+add if we begin to rely on FK relations with other tables.
Before using tweepy.Cursor, we first establish an API session object. The API has a beneficial function that deals with pagination and iterating across the timeline. It moves along quite quickly for the number of tips it has—222 as of this writing. We just want Daily Python Tip's tweets. Thus, the exclude replies=True and include rts=False options are convenient (not re-tweets).
First, I defined the regex for a tag like:
TAG = re.compile(r'#([a-z0-9]{3,})')
You can also try this code with Online Python Compiler
I then used findall to retrieve every tag. They were passed off to collections.
With the counts as values and the tags as keys, the counter returns a dict-like object that is sorted by values (most common). I removed the overused Python tag because it would bias the results.
def get_hashtag_counter(tips):
#adding in the variables
blob = ' '.join(t.text.lower() for t in tips)
cnt = Counter(TAG.findall(blob))
#It is an hashtag counter
if EXCLUDE_PYTHON_HASHTAG:
#excluding the arguement value
cnt.pop('python', None)
return cnt
You can also try this code with Online Python Compiler
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.
Making the App🧑💻
Only one method is required for this straightforward app, along with an optional tag argument. The routing is managed using decorators, much like Flask. When called with a tag, the tips are filtered; otherwise, they are all displayed. The view decorator specifies the template to use. For use in the template, we return a dict, just as Flask (and Django).
@route('/')
@route('/<tag>')
@view('index')
def index(tag=None):
#Bottle App setup
tag = tag or request.query.get('tag') or None
#collecting tags
tags = get_hashtags()
tips = get_tips(tag)
#returning the values
return {'search_tag': tag or '',
'tags': tags,
'tips': tips}
You can also try this code with Online Python Compiler
In the views subdirectory, We have defined a header.tpl, index.tpl, and footer.tpl. For the tag name cloud, I used some simple inline CSS to increase the tag size by count, see header.tpl:
% for tag in tags:
<a style="font-size: {{ tag.count/10 + 1 }}em;" href="/{{ tag.name }}">#{{ tag.name }}</a>
% end
You can also try this code with Online Python Compiler
If you are familiar with the Flask and Jinja2 this should look very familiar. Embedding Python is easier, with less typing—(% ... vs {% ... %}).
If we'd use it, all CSS and images (and JS) go into the static subfolder.
And that's all there is to make a basic web app with Bottle Framework. Once you have the data layer properly defined, now it's pretty straightforward.
Frequently Asked Questions
What do you understand about the bottle web framework?
The bottle is a Python WSGI micro web framework that is quick, easy, and lightweight. It is supplied as a single file module and only requires the Python Standard Library as a dependency.
Describe Django and the Bottle.
Model-template-view (MTV) is the basis for its design. It includes many tools that application developers require, including an ORM framework, admin panel, directory structure, and more.
What does WSGI stand for?
The Web Server Gateway Interface (pronounced whiskey or WIZ-ghee) is a straightforward calling standard used by web servers to route requests to web applications or frameworks created in the Python programming language.
Is Apache a WSGI?
A Python application is embedded within the Apache HTTP Server using the mod WSGI module, which enables communication via the Python WSGI interface as specified in Python PEP 333. One Python method for creating high-quality, high-performance web apps is WSGI.
What is Falcon for Python?
Falcon is a dependable, high-performance Python web framework for creating microservices and the backends of large-scale applications. It supports the REST architectural movement and strives to be as efficient as possible by doing the bare minimum.
Conclusion
In this article, we have extensively discussed Building Simple Web Applications Using Bottle Framework, SQLAlchemy and Twitter API.