Slugify

Today while working on the flask casts site, I decided it would be a good idea to generate a url slug. This is extremely important for search engine optimization. I thought about writing my own class to do this, then thought it might get ugly…so I searched for a package. I found Slugify: https://github.com/un33k/python-slugify

Pretty simple to use. When creating the Post object I just modified my __init__ to the following:

[pastacode lang=”python” manual=”%20%20%20%20def%20__init__(self%2C%20title%2C%20content%2C%20author%2C%20created%3DNone)%3A%0A%20%20%20%20%20%20%20%20self.title%20%3D%20title%0A%20%20%20%20%20%20%20%20self.slug%20%3D%20slugify(title)%0A%20%20%20%20%20%20%20%20self.content%20%3D%20content%0A%20%20%20%20%20%20%20%20self.author%20%3D%20author%0A%20%20%20%20%20%20%20%20self.created%20%3D%20datetime.datetime.utcnow().strftime(‘%25A%20%25x%20%40%20%25H%3A%25M%3A%25S’)%20%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20created%20is%20None%20else%20created” message=”” highlight=”” provider=”manual”/]

Now I can pass the slug to a url like: flaskcasts.com/post/this-is-the-post-title

[pastacode lang=”python” manual=”%40home.route(‘%2Fpost%2F%3Cstring%3Aslug%3E’)%0Adef%20post(slug)%3A%0A%20%20%20%20post%20%3D%20Post.get_post(slug)%0A%20%20%20%20author%20%3D%20User.get_user(post%5B’author’%5D)%0A%20%20%20%20return%20render_template(‘home%2Fpost.html’%2C%20post%3Dpost%2C%20author%3Dauthor%5B’fullname’%5D)” message=”” highlight=”” provider=”manual”/]

Thanks for reading!

Pagination

So the concept escaped me for a couple of days. I actually had considered abandoning my MongoDB trials in favor of a SQL based system. What I discovered was that I am more persistent in finding a solution to my problem than I originally thought. I stumbled upon this Gist: https://gist.github.com/wonderb0lt/10645080

This is a very simple and basic Pagination class written for MongoEngine. Flask already has an extension for MongoEngine with this already built in. After looking at the code I realized all this is doing is passing an iterable to the Pagination class and then building links in the template. So I decided I would type it out line by line so I could get a better grasp on what was happening in the code.

So now I have Flask-PyMongo communicating with my database and was able to build the models in such a way that makes more sense to me at this stage of my learning.

For instance, my Post model looks like this:

[pastacode lang=”python” manual=”class%20Post(object)%3A%0A%0A%0A%20%20%20%20def%20__init__(self%2C%20title%2C%20content%2C%20author%2C%20created%3DNone)%3A%0A%20%20%20%20%20%20%20%20self.title%20%3D%20title%0A%20%20%20%20%20%20%20%20self.content%20%3D%20content%0A%20%20%20%20%20%20%20%20self.author%20%3D%20author%0A%20%20%20%20%20%20%20%20self.created%20%3D%20datetime.datetime.utcnow().strftime(‘%25A%20%25x%20%40%20%25H%3A%25M%3A%25S’)%20%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20created%20is%20None%20else%20created%0A%0A%20%20%20%20def%20__repr__(self)%3A%0A%20%20%20%20%20%20%20%20return%20%22%3CPost%20%7B%7D%3E%22.format(self.title)%0A%0A%20%20%20%20def%20json(self)%3A%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20self.title%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22content%22%3A%20self.content%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22author%22%3A%20self.author%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22created%22%3A%20self.created%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20def%20save(self)%3A%0A%20%20%20%20%20%20%20%20mongo.db.posts.update(%7B’title’%3A%20self.title%7D%2C%20self.json()%2C%20upsert%3DTrue)%0A” message=”” highlight=”” provider=”manual”/]

MongoEngine allows reference fields so you can actually store the author object in the post document…which is kind of cool becuase you could do something like this from the template post.author.full_name. So I was a little stuck on trying to find a way to do this using PyMongo until I read this post: https://docs.mongodb.com/manual/tutorial/model-referenced-one-to-many-relationships-between-documents/

It explains a more efficient way of doing this. In my case I am referencing the user by the author variable, so I have set my User class up so that _id is a unique username and will reference the user by the username.

See the User class:

[pastacode lang=”python” manual=”class%20User(object)%3A%0A%0A%20%20%20%20def%20__init__(self%2C%20_id%2C%20email%2C%20password%2C%20fullname)%3A%0A%20%20%20%20%20%20%20%20self._id%20%3D%20_id%20%23%20username%2C%20unique%0A%20%20%20%20%20%20%20%20self.email%20%3D%20email%0A%20%20%20%20%20%20%20%20self.password%20%3D%20password%0A%20%20%20%20%20%20%20%20self.fullname%20%3D%20fullname%0A%0A%20%20%20%20def%20__repr__(self)%3A%0A%20%20%20%20%20%20%20%20return%20%22%3CUser%20%7B%7D%3E%22.format(self.fullname)%0A%0A%20%20%20%20def%20json(self)%3A%0A%20%20%20%20%20%20%20%20return%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22_id%22%3A%20self._id%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22email%22%3A%20self.email%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22password%22%3A%20self.password%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22fullname%22%3A%20self.fullname%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%40staticmethod%0A%20%20%20%20def%20get_user(user_id)%3A%0A%20%20%20%20%20%20%20%20return%20mongo.db.users.find_one(%7B%22_id%22%3A%20user_id%7D)%0A%0A%20%20%20%20def%20save(self)%3A%0A%20%20%20%20%20%20%20%20mongo.db.users.update(%7B%22_id%22%3A%20self._id%7D%2C%20self.json()%2C%20upsert%3DTrue)%0A” message=”” highlight=”” provider=”manual”/]

So using the get_user() method I can get the fullname…

LEARNING A LOT! and having a lot of fun!

Also found this library…for generating fake data…VERY useful http://mimesis.readthedocs.io/en/latest/

Change of plans…sort of…kind of…

I am currently reconsidering my options as far as the database for FlaskCasts. As a newbie to Flask and Python, I am starting to see that MongoDB may be more challenging to use than I had initially thought. However, I’m not one to give up so soon. A couple of things I am confused about stand out:

  1. Implementing Pagination for the list of videos on the front page.
  2. Sorting those in descending order.

Coming from an SQL background this isn’t so complicated and in fact a lot of the SQLAlchemy based libraries have a pagination method built in.

Right now I am looking at the Flask-PyMongo extension to see if this will make things any easier. So far I have used plain PyMongo (on my blog attempt I mentioned earlier) and wrote a lot of the DB methods myself. I’ve already came across YouTube videos showing how to sort with this library so I think I may be able to use this and roll my own pagination.

After a little more research, I found Flask-MongoEngine. With just a little tinkering I was able to implement a very basic pagination. So I am pretty happy with that. This library seems to be well supported so I may just stick with this.

[pastacode lang=”python” manual=”from%20flask%20import%20Flask%2C%20request%2C%20Blueprint%2C%20render_template%0Afrom%20flask_mongoengine%20import%20*%0Afrom%20.models%20import%20Post%0A%0Aapp%20%3D%20Flask(__name__)%0Aapp.config.from_object(‘config’)%0Adb%20%3D%20MongoEngine(app)%0A%0A%40app.route(‘%2F’)%0Adef%20hello_world()%3A%0A%20%20%20%20page%20%3D%20int(request.args.get(‘page’)%20or%201)%0A%20%20%20%20posts%20%3D%20Post.objects.order_by(‘-created’)%0A%20%20%20%20paginated_posts%20%3D%20Pagination(posts%2C%20page%3Dpage%2C%20per_page%3D2)%0A%20%20%20%20return%20render_template(‘index.html’%2C%20paginated_posts%3Dpaginated_posts)” message=”” highlight=”” provider=”manual”/]

This is my view. Basically it checks to see if a page variable is being passed through. Gets the posts in descending order. Passes the posts to the Pagination class that is built in with the current page and showing only 2 entries per page. Then it renders the template with the paginated_posts.

[pastacode lang=”python” manual=”%7B%25%20for%20post%20in%20paginated_posts.items%20%25%7D%0A%20%20%20%20%3Ch2%3E%7B%7B%20post.title%20%7D%7D%3C%2Fh2%3E%0A%20%20%20%20%3Cp%3E%7B%7B%20post.content%20%7D%7D%3C%2Fp%3E%0A%20%20%20%20%3Cp%3EPosted%20by%3A%20%7B%7B%20post.author.fullname%20%7D%7D%3C%2Fp%3E%0A%7B%25%20endfor%20%25%7D%0A%0A%7B%23%20Macro%20for%20creating%20navigation%20links%20%23%7D%0A%7B%25%20macro%20render_navigation(pagination%2C%20endpoint)%20%25%7D%0A%20%20%3Cdiv%20class%3Dpagination%3E%0A%20%20%7B%25%20for%20page%20in%20pagination.iter_pages()%20%25%7D%0A%20%20%20%20%7B%25%20if%20page%20%25%7D%0A%20%20%20%20%20%20%7B%25%20if%20page%20!%3D%20pagination.page%20%25%7D%0A%20%20%20%20%20%20%20%20%3Ca%20href%3D%22%7B%7B%20url_for(endpoint%2C%20page%3Dpage)%20%7D%7D%22%3E%7B%7B%20page%20%7D%7D%3C%2Fa%3E%0A%20%20%20%20%20%20%7B%25%20else%20%25%7D%0A%20%20%20%20%20%20%20%20%3Cstrong%3E%7B%7B%20page%20%7D%7D%3C%2Fstrong%3E%0A%20%20%20%20%20%20%7B%25%20endif%20%25%7D%0A%20%20%20%20%7B%25%20else%20%25%7D%0A%20%20%20%20%20%20%3Cspan%20class%3Dellipsis%3E%E2%80%A6%3C%2Fspan%3E%0A%20%20%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endfor%20%25%7D%0A%20%20%3C%2Fdiv%3E%0A%7B%25%20endmacro%20%25%7D%0A%0A%7B%7B%20render_navigation(paginated_posts%2C%20’hello_world’)%20%7D%7D%0A” message=”” highlight=”” provider=”manual”/]

I’d never really messed wtih a Macro in Jinja before this so I need to do a little more studying to get a grasp on what is happening here.  But…it works, and is much easier to roll out than anything else I think I could have done.

The models are a bit confusing as these classes inherit from the Document class…and I have not yet worked with anything like this, I’ve written my own classes. I am going to play around with the concepts a little more to get confortable. Here is what they look like right now:

[pastacode lang=”python” manual=”import%20datetime%0Afrom%20mongoengine%20import%20*%0A%0A%0Aclass%20User(Document)%3A%0A%20%20%20%20email%20%3D%20EmailField()%0A%20%20%20%20password%20%3D%20StringField()%0A%20%20%20%20fullname%20%3D%20StringField()%0A%0A%0Aclass%20Post(Document)%3A%0A%20%20%20%20title%20%3D%20StringField()%0A%20%20%20%20content%20%3D%20StringField()%0A%20%20%20%20author%20%3D%20ReferenceField(User)%0A%20%20%20%20created%20%3D%20DateTimeField(datetime.datetime.now)” message=”” highlight=”” provider=”manual”/]

Going to work on this some more tomorrow. Very happy to have solved this pagination issue however.

 

Flask application structure…

One of the beautiful things about Flask is the freedom to do whatever the hell you want. Unfortunately, for me as a novice, this can be a huge disadvantage at the same time. Not knowing all of the best practices can cause some unnecessary headache. Lucky for me there are a lot of blog entries out there to help get this off the ground.

Blueprints is a flask feature that allows you to organize your app in a modular way. Each “section” will act almost as if it is it’s own application. I took a screenshot of my current directory structure to show you what it looks like. So the project itself would be considered a repository,

and will end up on github at some point as I make more solid plans.

Right now I just wanted to get something running even if it is technically just a simple and basic “Hello World.”

Currently the run.py file contains:

[pastacode lang=”python” manual=”from%20flaskcasts%20import%20app%0A%0Aapp.run(debug%3Dapp.config%5B’DEBUG’%5D)%0A” message=”” highlight=”” provider=”manual”/]

When ran, it then goes to the flaskcasts directory since it is a module and runs the code in __init__.py:

[pastacode lang=”python” manual=”from%20flask%20import%20Flask%0A%0Aapp%20%3D%20Flask(__name__)%0A%0Aapp.config.from_object(‘config’)%0A%0Afrom%20.views.home%20import%20home%0Aapp.register_blueprint(home)” message=”” highlight=”” provider=”manual”/]

This will go to the home blueprint and execute that code:

[pastacode lang=”python” manual=”from%20flask%20import%20Blueprint%0A%0Ahome%20%3D%20Blueprint(‘home’%2C%20__name__)%0A%0A%40home.route(‘%2F’)%0Adef%20index()%3A%0A%20%20%20%20return%20%22Welcome%20to%20the%20Index%22″ message=”” highlight=”” provider=”manual”/]

The only other file is config.py and it basically holds the DEBUG=True boolean only.

 

Structurally, for a very basic application that is only going to feed videos from a YouTube or similar service, this should suffice.

The one thing…

Had a long drive for work today. I usually listen to a lot of different podcasts on various topics. Lately my favorites are “Talk Python to Me” and the like… I listened “The SaaS podcast” because one of my goals from learning to code in Python is to develop a product, release it, and start earning supplemental income. Podcasts are great because not only will you learn things and absorb a lot of data, you find inspiration. The host kept talking about the book “The One Thing” by Gary Keller. Since I had 3 credits on Audible, I decided, why not! So far it is a GREAT book.

The main idea is to pick 1 thing, and focus on it with everything you have. Build habits by struggling with the difficulties of doing that 1 thing for 66 days on average and it becomes easy. So, I asked myself. What is the one thing that I can do today that will propel me toward my goal of becoming a successful freelancer and entrepreneur? The answer that came to mind is, Blog about coding and code. Talk about the things I am learning in a blog post and share with the world. Set aside some time to document, almost in a diary like format the things that I am working on and learning.

This will propel me in my coding career because the habit of blogging will force me to find things to write about. The process of finding things to write about will help me to learn new concepts and force me to produce code to share. Even on days when my normal job has sucked out all of my energy and I just don’t have it in me to write a line of code, I can talk about ways to find inspiration. I can talk about the feeling that comes from building something that works and solves a problem for someone. I can think about how satisfying it is to finally solve a bug in my code.

So, this is my blog. I am going to update this site regularly with information that will build confidence and keep me on track to success. I plan to work on some tutorials tomorrow and will write about my thoughts.

Writing a screencast blog with Flask

I read somewhere that the best way to learn a programming language, and to get better at coding is to work on projects. Open-source projects can be daunting for beginners so, it’s probably a good idea to roll your own apps for things you need personally. I really wanted to write my own blog but like I mentioned earlier, I set a deadline for the new moon/solar eclipse to launch, and I just couldn’t quite get the “pagination” working in time.

I got the idea to make a Blog for flask newbies. The idea was based on an old ruby-on-rails site I used to visit when I was trying to learn Ruby on Rails. The domain that I have purchased is flaskcast.com and basically all I’m going to do is write a simple blog website in flask that will display the YouTube videos embedded in the posts with a title and date posted. I may eventually add a discussion section for each video.

Tools
  • Python 3.6.2
  • Flask
  • Database (probably use MongoDB, as I am enjoying learning new stuff but may go with sqlite3 or postgres)
  • The Flask-MongoAlchemy extension. https://pythonhosted.org/Flask-MongoAlchemy/
  • Blueprints (to make the app modular, may need to scale it up at some point)
  • Digital Ocean for hosting
  • PyCharm
  • probably more…

The big issue I faced trying to write my own blog engine was that I had to write my own database module that utilized PyMongo. It was a learning experience, and in fact I got most of the code from a Udemy course that I had taken. I’m just not advanced enough right now to write my own pagination code that uses MongoDB. After looking at the docs for the MongoAlchemy extension, it looks like 90% of the code I had to write is already taken care of. This is copied from the docs:

[pastacode lang=”python” manual=”from%20flask%20import%20Flask%0Afrom%20flask.ext.mongoalchemy%20import%20MongoAlchemy%0Aapp%20%3D%20Flask(__name__)%0Aapp.config%5B’MONGOALCHEMY_DATABASE’%5D%20%3D%20’library’%0Adb%20%3D%20MongoAlchemy(app)%0A%0Aclass%20Author(db.Document)%3A%0A%20%20%20%20name%20%3D%20db.StringField()%0A%0Aclass%20Book(db.Document)%3A%0A%20%20%20%20title%20%3D%20db.StringField()%0A%20%20%20%20author%20%3D%20db.DocumentField(Author)%0A%20%20%20%20year%20%3D%20db.IntField()%0A%0Afrom%20application%20import%20Author%2C%20Book%0Amark_pilgrim%20%3D%20Author(name%3D’Mark%20Pilgrim’)%0Adive%20%3D%20Book(title%3D’Dive%20Into%20Python’%2C%20author%3Dmark_pilgrim%2C%20year%3D2004)%0A%0Amark_pilgrim.name%20%3D%20’Mark%20Stalone’%0Amark_pilgrim.save()” message=”Flask-MongoAlchemy example” highlight=”” provider=”manual”/]

So as you can see, basically you create document objects and work with those. Looks like querying the database is really simple as well. My module required some pretty complicated RegEx that I am not comfortable writing without assistance.

Pagination appears to be pretty simple as well…

[pastacode lang=”python” manual=”paginate(page%2C%20per_page%3D20%2C%20error_out%3DTrue)” message=”” highlight=”” provider=”manual”/]

Next post I will share some design ideas.

See you tomorrow!

Welcome to my blog!

This blog was inspired by https://dbader.org/, so I wanted to first and foremost give a shout-out and thanks.

About Me…

Well, I am a proud father and happy husband. I have 3 children, 2 dogs, several goldfish and a wonderful wife. I work professionally as a registered nurse case manager in the workers compensation field. I do love my job, but nursing isn’t what I set out to do…

In the mid 90’s my mother bought our first computer, a Tandy Sensation from Radio Shack….

This pretty much changed my life. I was able to tinker around on this computer at a young age 12-14 years old. I was blown away. Before this I used to try and make large outdoor antennas that could pick up radio stations from surrounding larger cities (I lived in a small rural town in the middle of nowhere). So having access to the internet, via dialup connection…was a game changer. I did in fact get in trouble as a kid because my cousin and I were using dial-up to connect to AOL and chat…the number was long distance so we ran up a very large phone bill.

I promise, as I do this I will get better at writing...I realize I suck right now.

As time went on I learned about ZDTV on our large c-band satellite system.

I literally grew up watching Leo and Kate. I learned how to mess around with Linux distros. I think my favorite around that time was Mandrake Linux, or Fedora.I went to college and a guy down the hall in my dorm built PC’s so, he helped me build my first one.

I then decided computer science was for me…this was late 90s early 2k’s. I made it about 2 years into my degree. I didn’t mention this before, but I was into music and played in a band. I actually set up a local music scene page called appalcore.org that does not exist today. I used that page as an outlet for my development interests. It was mostly PHP based stuff…but was fun to do.

I ultimately got scared of the “dot com bubble” and that I would not find a job…especially if I wanted to stay in my small rural town. So I switched majors to Nursing, having a lot of voices in my ear telling me to go into Health-care. In the meantime, I did start a web agency with a friend and we did a lot of early web-standards stuff. It was hard because we mostly pandered to our local market and being in a rural area…not really anyone gave a shit. There were a couple of real estate agencies and a restaurant or 2. I built a pretty big codeigniter project and tried to implement some early MVC stuff…but the code kind of sucked… The agency disbanded and I went on to get my nursing degree.

Fast forward 10 years or so…

I realize now that time goes by much faster than I ever did as a kid. A lot of my mistakes were thinking that something would take too long to complete…so I wouldn’t try. I look back now and a year literally seems like a day…

I have decided that life is too short not to follow what you are passionate about. Trying to make career choices based on what other people think, or what a local market dictates (there is no such thing as a local market in this day and age).

So this blog is dedicated to my rebirth as a developer. I started out on this path, and I wandered off. It seemed impossible for a while that I could ever get back onto this path. Yet, here I am. I am going to use this blog as a medium for my experiences and what I am learning, and doing. Some things may be more “personal”, and less informative. I am also really into esoteric shit… so you might get some of that from time to time. I had to get this in before 8/21/17…

Python is the language of choice. I had intended this blog to be hand coded in python, and actually started on the code using Flask, MongoDB… but it is imperative this be released on/before 8/21/17 for metaphysical reasons. New moons are powerful for new ventures….this one specifically. I couldn’t quite meet the deadline, and I actually had the domain and a hosting account ready to go…so I went with a basic wordpress for now.

The project I am going to produce based on the above code is FlaskCasts, www.flaskcasts.com. This is going to be a screencast/vlog/blog type situation. I am going to use this to put out videos on general web development issues and hopefully gain some traction in the community.

Hit me up via email: me@eddiegrey.com

PEACE!

Bear with me...I'll get better at writing.