# aiocrafters/autoblog-python architecture

> Architecture diagram of the GitHub repository aiocrafters/autoblog-python, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-23). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/aiocrafters/autoblog-python
- Repository: https://github.com/aiocrafters/autoblog-python

## Overview

1. This repository is a small Python command-line automation tool, not a long-running service. Its architecture is a sequence of one-off scripts that interact with Google’s OAuth 2.0 and Blogger API v3.

2. The repo has three functional entry points:
   - `get_blogger_token.py` for initial OAuth authorization and refresh-token acquisition
   - `get_blog_id.py` for discovering available Blogger blogs and their IDs
   - `publish_post.py` for creating Blogger posts or drafts

3. The main external boundary is Google’s cloud APIs. The project depends on:
   - Google OAuth 2.0 for user authorization
   - Blogger API v3 for blog discovery and post creation
   - Google account permissions tied to the user’s Blogger blog

4. Configuration is separated from code through a `.env` file. The runtime credentials boundary is:
   - `GOOGLE_CLIENT_ID`
   - `GOOGLE_CLIENT_SECRET`
   - `GOOGLE_REFRESH_TOKEN`
   - `BLOGGER_BLOG_ID`
   This keeps secrets out of the scripts and makes the tooling account-specific.

5. The authentication flow is two-stage. First, the user runs `get_blogger_token.py` to perform a browser-based OAuth consent flow. That script exchanges the initial authorization for a refresh token, which is then reused for future runs without prompting the browser again.

6. `get_blog_id.py` is a discovery tool. It uses the authenticated Google session to call the Blogger API and list blogs associated with the account, exposing the blog title, URL, and numeric blog ID. That ID becomes a required input for publishing.

7. `publish_post.py` is the write path. It constructs a Blogger post from locally defined content fields such as title, body, and draft/publish mode, then sends the create-post request to the Blogger API using the selected blog ID and stored refresh token.

8. The data flow is linear and manual:
   - Google Cloud OAuth client credentials are created externally
   - The token script produces a refresh token
   - The blog-id script discovers the target blog ID
   - The publish script sends content to that blog
   Each step feeds the next through `.env` or copied values.

9. The repository’s Python dependency layer is thin and focused on Google integration:
   - `google-auth`, `google-auth-oauthlib`, and `google-auth-httplib2` handle OAuth and credential refresh
   - `google-api-python-client` talks to Blogger API v3
   - `python-dotenv` loads `.env` configuration into the scripts

10. There is no database, queue, or internal API server. State is mostly externalized in Google account credentials and the `.env` file, with the only durable outputs being the refresh token, the blog ID, and the published Blogger posts themselves.

11. The operational boundary is local machine execution. The scripts assume a desktop-style OAuth client and a user running them manually from a Python environment, typically with a virtualenv.

12. For an architecture diagram, the key components are: local Python scripts, `.env` configuration, Google OAuth 2.0, and Blogger API v3. The primary arrows are from scripts to Google auth, then from authenticated scripts to Blogger API, with discovered identifiers and tokens stored back into `.env` for reuse.

Main entry points: [`publish_post.py`](https://github.com/aiocrafters/autoblog-python/blob/main/publish_post.py) (Publish post), [`get_blogger_token.py`](https://github.com/aiocrafters/autoblog-python/blob/main/get_blogger_token.py) (Get token), [`get_blog_id.py`](https://github.com/aiocrafters/autoblog-python/blob/main/get_blog_id.py) (Get blog ID)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_local["Local scripts"]
  node_token_script["Get token<br/>script"]
  node_blogid_script["Get blog ID<br/>script<br/>[get_blog_id.py]"]
  node_publish_script["Publish post<br/>script<br/>[publish_post.py]"]
  node_dotenv[".env<br/>config"]
  node_client_id["Client ID<br/>secret"]
  node_client_secret["Client secret"]
  node_refresh_token["Refresh token<br/>credential"]
  node_blog_id["Blog ID<br/>identifier"]
end

subgraph group_google["Google services"]
  node_google_oauth(("OAuth 2.0<br/>auth service"))
  node_blogger_api{{"Blogger API v3"}}
  node_account(("Google account<br/>user account"))
end

node_dotenv -->|"loads"| node_client_id
node_dotenv -->|"loads"| node_client_secret
node_dotenv -->|"loads"| node_refresh_token
node_dotenv -->|"loads"| node_blog_id
node_token_script -->|"authenticates"| node_google_oauth
node_google_oauth -->|"consents"| node_account
node_token_script -->|"writes"| node_refresh_token
node_blogid_script -->|"authenticates"| node_google_oauth
node_blogid_script -->|"lists blogs"| node_blogger_api
node_blogger_api -->|"returns"| node_blog_id
node_publish_script -->|"uses"| node_refresh_token
node_publish_script -->|"targets"| node_blog_id
node_publish_script -->|"creates post"| node_blogger_api
node_blogger_api -->|"authorizes"| node_account

click node_token_script "https://github.com/aiocrafters/autoblog-python/blob/main/get_blogger_token.py"
click node_blogid_script "https://github.com/aiocrafters/autoblog-python/blob/main/get_blog_id.py"
click node_publish_script "https://github.com/aiocrafters/autoblog-python/blob/main/publish_post.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_token_script,node_blogid_script,node_publish_script,node_dotenv,node_client_id,node_client_secret,node_refresh_token,node_blog_id toneBlue
class node_google_oauth,node_blogger_api,node_account toneAmber
```

## Components

### Local scripts

One-off Python entry points and local runtime inputs.

- [Get token](https://github.com/aiocrafters/autoblog-python/blob/main/get_blogger_token.py): script · Runs browser-based OAuth consent and captures a refresh token. · `get_blogger_token.py`
- [Get blog ID](https://github.com/aiocrafters/autoblog-python/blob/main/get_blog_id.py): script · Lists Blogger blogs for the authenticated account and surfaces the target blog ID. · `get_blog_id.py`
- [Publish post](https://github.com/aiocrafters/autoblog-python/blob/main/publish_post.py): script · Creates a Blogger post or draft for the selected blog. · `publish_post.py`
- **.env**: config · Local credential and runtime settings boundary for account-specific values.
- **Client ID**: secret · Google OAuth client identifier loaded from environment.
- **Client secret**: secret · Google OAuth client secret loaded from environment.
- **Refresh token**: credential · Reusable Google OAuth refresh token persisted for later runs.
- **Blog ID**: identifier · Selected Blogger blog identifier used when publishing.

### Google services

External OAuth and Blogger API boundaries.

- **OAuth 2.0**: auth service · Google authorization flow used to obtain and refresh credentials.
- **Blogger API v3**: api · Google API for discovering blogs and creating posts.
- **Google account**: user account · User-owned account that grants Blogger permissions.

## Connections

- .env → Client ID: loads · Environment file provides OAuth client ID.
- .env → Client secret: loads · Environment file provides OAuth client secret.
- .env → Refresh token: loads · Environment file provides stored refresh token.
- .env → Blog ID: loads · Environment file provides selected blog ID.
- Get token → OAuth 2.0: authenticates · Initiates browser-based OAuth consent and token exchange.
- OAuth 2.0 → Google account: consents · User grants access to the Blogger-enabled Google account.
- Get token → Refresh token: writes · Produces a reusable refresh token for later runs.
- Get blog ID → OAuth 2.0: authenticates · Uses Google credentials to access Blogger discovery endpoints.
- Get blog ID → Blogger API v3: lists blogs · Fetches blogs associated with the authenticated account.
- Blogger API v3 → Blog ID: returns · Discovery response yields the numeric blog identifier.
- Publish post → Refresh token: uses · Refresh token is exchanged for access during publishing.
- Publish post → Blog ID: targets · Selected blog ID determines where the post is created.
- Publish post → Blogger API v3: creates post · Sends the post or draft creation request.
- Blogger API v3 → Google account: authorizes · Blogger enforces permissions tied to the Google account.
