DEV Community

Cover image for My first Python project: Auto-Publish to DEV API
Eugene Dorfling
Eugene Dorfling

Posted on

My first Python project: Auto-Publish to DEV API

My first Python project

As I am learning programming skills I have thought it a good idea to have an ongoing project that I can work on while learning.

My weapon of choice of course is Python.

The starting line is still in my sights and this is only the beginning but I found that I learn, remember and understand better when I actually do something with what I have learned. It challenges me to test my knowledge and clearly highlights the areas where I am still lacking.

The project I chose is to build is a publishing automation app. As a new technical writer, publishing to all the different platforms we use is becoming a job on its own. Logging into each site, editing the formatting of the piece and setting all the different configurations like tags and the canonical URL(which I only recently discovered) simply takes too much of my time that could be better utilized learning how to code.

One of my biggest reasons for learning how to code, other than my job, is to start automating some of my time consuming repetitive tasks. Looking into how I spend my time, I realized that a lot of things can actually be automated if I only knew how to code.

So I started with this project as my first. I know it might take a while before I can really use it but I know that when it is done(it might become a never-ending project with all the features I am so optimistically adding every day) I will have more time and skills to start building more automation apps. Who knows what else I will be building next, the sky really is the limit when you know how to use the tools.

Where am I with my project?

Well, I have jumped into the deep end as I usually do and started figuring out how can I publish to these platforms and I found APIs. APWhat? Yeah, I am still learning about lists, tuples and dictionaries and then I start my project off by connecting to APIs. I know I tend to always err on the over-ambitious side but hey it wouldn't be a challenge if it was a random number generating app.

Just so we are on the same level, what is an API?

API stands for Application Programming Interface, it is a software intermediary that allows two applications to talk to each other(thanks Google). I see it as a translator that allows you to interface with a server through a pre-defined set of rules. So you can send instructions to a URL that is configured to accept certain commands and do a specific job based on the commands and parameters given. Regardless of the language you use, the API can understand what you are asking and it translates your request to the server. The server then responds through the API so that the API can translate back to the originating party.

Anyways, I obviously still have a lot to learn about APIs so please don't take my view on APIs as the truth. I will probably write a post on APIs when I better understand them.

Publishing through the DEV.to API

So I started out with DEV.to as it is by far my favorite place to publish my articles. I found the documentation on the DEV.to API and started hacking endlessly until I managed to get it working. Well, a few hours but it felt endless.

Now my auto-publisher app can publish articles to DEV.to, I only have to write it and run the program. I can now happily write in vim or vscode or any text editor for that matter and tell my app which Markdown file I want to publish and boom it does it all for me.

It took me a while to figure it out as I am only working off the documentation and other friendly dev writers who shared their process. But here is what I did to make this happen.

  • First and most important write an article and save it in Markdown format.

  • Include the front matter at the top of the body of your article. This is where I set the tags, canonical URL and so on. You can also set these with the params in your request but I found it easier to leave them blank in the request and simply configure them within each article. Note: If the Markdown contains a front matter, it will take precedence on the equivalent params given in the payload.

---
title: Hello, World!
published: true
tags: beginners, replit
date:
series:
canonical_url:
cover_image: 
---

# Article Heading 

Rest of your article
Enter fullscreen mode Exit fullscreen mode
  • Create a Python file, import the requests library and write the code that gets the content from your file and copies it into the variable that we will use as the body.
import requests

filename = input('File Name:')

f = open(filename, 'r')

body_markdown = f.read()
Enter fullscreen mode Exit fullscreen mode
  • Set up the connection variables => url, api_key, body_markdown(defined above). The API key is unique to each user. You can generate yours on your DEV.to Settings page under Account -> DEV API Keys
url = "https://dev.to/api/articles"
api_key='eXUXQXpX5XVXXyXaXwX4XgXA'
Enter fullscreen mode Exit fullscreen mode
  • Then I have a function defined that does the magic. As you will see the create_article() function takes all the parameters that are already embedded within your article so they all default to None. If you choose to rather set these here you can, however, just remember that if your file contains front matter these will be ignored.
def create_article(
        title,
        body_markdown="",  # must default to empty string instead of None otherwise dev.to raises error on edit
        published=None,
        series=None,
        main_image=None,
        canonical_url=None,
        description=None,
        tags=None,
        organization_id=None,
    ):
        """Create an article
        :param title: Title
        :param body_markdown: Article Markdown content
        :param published: True to create published article, false otherwise
        :param series: Article series name
        :param main_image: Main image (or cover image)
        :param canonical_url: Canonical Url
        :param description: Article Description
        :param tags: List of article tags
        :param organization_id: Organization id
        :return: newly created article
        """

        data = {
            "title": title,
            "body_markdown": body_markdown,
            "series": series,
            "published": published,
            "main_image": main_image,
            "canonical_url": canonical_url,
            "description": description,
            "tags": tags,
            "organization_id": organization_id,
        }
        # remove None keys from dict
        data = {k: v for k, v in data.items() if v is not None}
        response = requests.post(url, json=data, headers={"api-key":api_key}).json()
        if response.get("id") == None:
            print('Error Article not published')
        else:
            print('Article Posted. ID:{} /n Created at:{}'.format(response.get("id"),response.get("created_at")))
Enter fullscreen mode Exit fullscreen mode
  • Then I call the create_article() function, pass an empty title as it's already defined within the front matter of the file and then pass the body_markdown which contains the content.
create_article('',body_markdown)
Enter fullscreen mode Exit fullscreen mode
  • The function will put everything together and post your article with this line of code response = requests.post(url, json=data, headers={"api-key":api_key}).json(). If successful the response will give you an article id and the date & time it was created. If it fails it only prints an error message but you can also print the actual response if you want to see what went wrong.

That is it for the DEV.to integration. Now I am off to study some more so I can add more platforms and features. I will definitely pay special attention to APIs when they come across my learning path, looks like I will be working with them more often than I thought.

Top comments (0)