A new article on DEV with Python
Tags: tutorial, python
Published: 2022-03-01 20:23:21

## DEV API
If you want to create a new article on DEV, you can do it using the [DEV API](https://developers.forem.com/api), running the following command from the terminal:

```
curl -X POST -H "Content-Type: application/json" \
  -H "api-key: API_KEY" \
  -d '{"article":{"title":"Title","body_markdown":"Body","published":false,"tags":["discuss", "javascript"]}}' \
  https://dev.to/api/articles
```

Replacing the following values in the *article* JSON object:

- *title*: Title of your new article
- *body_markdown*: Content of your article, markdown formatted.
- *published*: It can be *true* or *false*, when *false* the article is saved as draft.
- *tags*: Any tag from [dev.to/tags](https://dev.to/tags).

You also must replace the value of *api-key* with your own key that you can get from the *DEV Community API Keys* section at [dev.to/settings/accounts](https://dev.to/settings/account).

## Optimize the process with Python
Wrote a blog post some months ago on how to [Automate your posting process on DEV with Python, Bash and GitLab CI](https://dev.to/mattdark/automate-your-posting-process-on-dev-with-python-bash-and-gitlab-ci-5fm6) where I explained how to automate the whole process using those technologies.

This week, I updated the GitLab project and deleted the Bash script to use Python instead.

The directory structure of the project is as follows:

- *articles*: A directory where Markdown files with the content of the articles are stored
- *articles/articles.yml*: Configuration file with details of the articles, including *title*, *body* and *tags*.
- *publish.py*: Python script that makes sure your article is published on DEV.
- *tweet.py*: Python script that shares your article on Twitter.

### articles.yml
Create a directory named *articles* and a YAML file, inside that directory, named *articles.yml*. This file will contain the following information and must be updated whenever a new article will be published:

```
recent_articles:
  - title: "Title"
    body: "articles/article.md"
    tags: "tag1 tag2"
```

Every new article is formatted using Markdown and that content is captured in a *.md* file.

### publish.py
The Python script will get the details of the article from the *articles/articles.yml* file, read the Markdown file and pass the content to the *article* JSON object and make the *POST* request to the DEV API for publishing the new article.

The following Python libraries are required:

- yaml
- requests

They can be installed using *pip*:

```
pip install PyYAML requests
```

After that, must be imported into the Python script:

```
import yaml
import json
import requests
```

The content of the *.md* file is read and assigned to a variable that will be passed to the `json_escape()` function as some characters must be escaped before assigning that value to the *body_markdown* variable in the JSON object.

`dumps()` method from the *json* library is used for escaping characters in the Markdown file. 

```
def json_escape(md):
    markdown=json.dumps(md)
    return markdown
```

The API key you got from the settings of your DEV account is assigned to the `dev_api_key` variable.

```
dev_api_key = API-KEY
```

*articles/articles.yml* is opened for reading the content and get the details of the article, including *title*, *body* and *tags*, those values are stored in a dictionary.

```
with open('articles/articles.yml') as f:
    dict = yaml.safe_load(f)
```

And assigned to the *title*, *body* and *t* variables.

```
title = dict['recent_articles'][0]['title']
body = dict['recent_articles'][0]['body']
t = dict['recent_articles'][0]['tags'].split()
```

*t* is a list that contains the tags of your article, extracted from the string in the dictionary using the `split()` method.

```
f = open(body, 'r')
md = f.read()
markdown = json_escape(md)
```

*body* variable contains the name of the Markdown file that is read and the content passed to the `json_escape()` method.

Tags in the *t* list are concatenated to get a string similar to `["tag1", "tag2"]` that is assigned to the *tags* array in the JSON object.

```
tags="["
for i in t:
    tags+= '"' + i + '"'
    if i != t[-1]:
        tags+=","
tags+="]"
```

Now, the *requests* library will be used instead of the *curl* command for making the *POST* request to the DEV API.

The value of URL and headers are set in variables.

```
url = 'https://dev.to/api/articles'

headers = {'Content-Type': 'application/json', 'api-key': dev_api_key}
```

A *json* variable, with the JSON object and corresponding values, is declared.

```
json='{"article":{"title":"' + title + '","body_markdown":' + markdown + ',"published":true,"tags":' + tags + '}}'
```

Now, the *POST* request is made.

```
r = requests.post(url, headers=headers, data=json)
```

## Your first article
Write the content of your article in a Markdown file and save it with the *.md* extension.

Modify the *articles/articles.yml* file and write the details of your article.

Run the Python script from the command line.

```
python publish.py
```

Your article is published now.