├── .gitignore ├── README.md ├── cli.py ├── gpt3_wordpress.py ├── poetry.lock ├── pyproject.toml └── screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GPT3 WordPress Post Generator 2 | This is a simple script I use to create posts for [NoHumansWrite](https://nohumanswrite.com) blog. It uses 3 | the OpenAI GPT-3 API to generate a WordPress post starting from the topic and tone 4 | of what you want to write. 5 | 6 | ![GPT3 WordPress Post Generator](screenshot.png) 7 | 8 | It uses the [OpenAI Python library](https://github.com/openai/openai-python) to make the OpenAI api calls and the 9 | [WordPress XML-RPC library](https://github.com/maxcutler/python-wordpress-xmlrpc) to create WordPress posts. 10 | 11 | At the moment this is a very rough implementation. I'm looking to improve it in the future and add more options to 12 | the script. Feel free to contribute if you find it useful. 13 | 14 | ## Installation 15 | 1. Clone the repository 16 | 2. Install the requirements: `poetry install` 17 | 3. Export the following variables: 18 | 19 | ```bash 20 | export OPENAI_API_KEY="Your OpenAI API Key" 21 | export WORDPRESS_URL="Your WordPress xmlrpc URL" 22 | export WORDPRESS_USERNAME="Your WordPress username" 23 | export WORDPRESS_PASSWORD="Your WordPress password" 24 | ``` 25 | 4. Run the script: `poetry run python cli.py --help` 26 | 5. Enjoy! 27 | 28 | ## Known Limitations 29 | - WordPress post won't be created using blocks, it will be created using the classic editor. To convert it to blocks, 30 | you can go to the post and click on the "Convert to blocks" button. -------------------------------------------------------------------------------- /cli.py: -------------------------------------------------------------------------------- 1 | import os 2 | import typer 3 | import rich 4 | from rich.progress import Progress, SpinnerColumn, TextColumn 5 | from gpt3_wordpress import Gpt3Wordpress 6 | 7 | gpt3wordpress_cli = typer.Typer() 8 | 9 | 10 | @gpt3wordpress_cli.command() 11 | def cli( 12 | open_api_key: str = typer.Option( 13 | help="Your OpenAI API key.", 14 | envvar="OPENAI_API_KEY", 15 | default=os.getenv("OPENAI_API_KEY") 16 | ), 17 | wordpress_blog_url: str = typer.Option( 18 | help="Your WordPress blog URL. (e.g. https://example.com)", 19 | envvar="WORDPRESS_BLOG_URL", 20 | default=os.getenv("WORDPRESS_BLOG_URL") 21 | ), 22 | wordpress_username: str = typer.Option( 23 | help="Your WordPress username.", 24 | envvar="WORDPRESS_USERNAME", 25 | default=os.getenv("WORDPRESS_USERNAME") 26 | ), 27 | wordpress_password: str = typer.Option( 28 | help="Your WordPress password.", 29 | envvar="WORDPRESS_PASSWORD", 30 | default=os.getenv("WORDPRESS_PASSWORD") 31 | ), 32 | topic: str = typer.Option( 33 | ..., 34 | prompt="\nWhat is the topic of the post?", 35 | help="The topic of the post. (e.g. technology, crypto, ai, etc.)" 36 | ), 37 | tone: str = typer.Option( 38 | prompt="What is the tone of the post?", 39 | help="The tone of the post. (e.g. funny, serious, etc.)", 40 | default="neutral" 41 | ), 42 | max_words: int = typer.Option( 43 | prompt="Maximum words for the post?", 44 | help="Maximum words for the post. (e.g. 2500)", 45 | default=2500 46 | ) 47 | ): 48 | generator = Gpt3Wordpress( 49 | open_api_key, 50 | wordpress_blog_url, 51 | wordpress_username, 52 | wordpress_password, 53 | ) 54 | title = generator.generate_post_title(topic) 55 | content = generator.generate_post(title, tone, max_words) 56 | 57 | with Progress( 58 | SpinnerColumn(), 59 | TextColumn("[progress.description]{task.description}"), 60 | ) as progress: 61 | progress.add_task(description="Creating WordPress post...", total=None) 62 | generator.create_wordpress_post(title, content) 63 | rich.print(f"Created post with title: {title}\n") 64 | 65 | 66 | if __name__ == '__main__': 67 | rich.print("\n") 68 | rich.print("█▀▀ █▀█ ▀█▀ ▄▄ ▀▀█   █░█░█ █▀█ █▀█ █▀▄ █▀█ █▀█ █▀▀ █▀ █▀   █▀█ █▀█ █▀ ▀█▀  █▀▀ █▀▀ █▄░█ █▀▀ █▀█ ▄▀█ ▀█▀ █▀█ █▀█") 69 | rich.print("█▄█ █▀▀ ░█░ ░░ ▄██   ▀▄▀▄▀ █▄█ █▀▄ █▄▀ █▀▀ █▀▄ ██▄ ▄█ ▄█   █▀▀ █▄█ ▄█ ░█░  █▄█ ██▄ █░▀█ ██▄ █▀▄ █▀█ ░█░ █▄█ █▀▄") 70 | typer.run(cli) 71 | -------------------------------------------------------------------------------- /gpt3_wordpress.py: -------------------------------------------------------------------------------- 1 | import openai 2 | import rich 3 | import typer 4 | 5 | from rich.progress import Progress, SpinnerColumn, TextColumn 6 | from wordpress_xmlrpc import Client, WordPressPost 7 | from wordpress_xmlrpc.methods.posts import NewPost 8 | 9 | 10 | class Gpt3Wordpress: 11 | def __init__(self, api_key: str, blog_url: str, username: str, password: str): 12 | openai.api_key = api_key 13 | self.blog_url = blog_url + "/xmlrpc.php" 14 | self.username = username 15 | self.password = password 16 | 17 | def _gpt3_query(self, prompt: str) -> str: 18 | """Query the OpenAI GPT-3 API with the given prompt and return the response.""" 19 | try: 20 | response = openai.Completion.create( 21 | model="text-davinci-003", 22 | prompt=prompt, 23 | temperature=0.6, 24 | max_tokens=3000, 25 | top_p=1.0, 26 | frequency_penalty=0.0, 27 | presence_penalty=0.6, 28 | ) 29 | return response.choices[0].text 30 | except Exception() as e: 31 | rich.print(f"Error: {e}") 32 | exit(1) 33 | 34 | def _generate_loop(self, prompt: str, kind: str) -> str: 35 | """Generate a title or post until it meets the requirements.""" 36 | while True: 37 | with Progress( 38 | SpinnerColumn(), 39 | TextColumn("[progress.description]{task.description}"), 40 | ) as progress: 41 | progress.add_task(description=f"Generating {kind}...", total=None) 42 | content = self._gpt3_query(prompt) 43 | rich.print(f"\nGenerated {kind}: {content}") 44 | confirm = typer.confirm(f"\nDo you like the generated {kind}?") 45 | if confirm: 46 | return content 47 | 48 | def generate_post_title(self, topic: str) -> str: 49 | """Generate a post title.""" 50 | return self._generate_loop(f"Blog post title." 51 | f"Title must be about {topic}." 52 | f"Length must be maximum 70 characters", 53 | "title") 54 | 55 | def generate_post(self, title: str, tone: str, max_words: int) -> str: 56 | """Generate a post.""" 57 | return self._generate_loop(f"Blog post which titles {title}. " 58 | f"Tone must be {tone}. " 59 | f"Length must be maximum {max_words} words.", 60 | "post") 61 | 62 | def create_wordpress_post(self, title: str, content: str) -> None: 63 | """Create a WordPress post.""" 64 | client = Client(self.blog_url, self.username, self.password) 65 | post = WordPressPost() 66 | post.title = title 67 | post.content = content 68 | post.post_status = 'draft' 69 | try: 70 | client.call(NewPost(post)) 71 | except Exception() as e: 72 | rich.print(f"Error: {e}") 73 | exit(1) 74 | 75 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "certifi" 3 | version = "2022.12.7" 4 | description = "Python package for providing Mozilla's CA Bundle." 5 | category = "main" 6 | optional = false 7 | python-versions = ">=3.6" 8 | 9 | [[package]] 10 | name = "charset-normalizer" 11 | version = "2.1.1" 12 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 13 | category = "main" 14 | optional = false 15 | python-versions = ">=3.6.0" 16 | 17 | [package.extras] 18 | unicode-backport = ["unicodedata2"] 19 | 20 | [[package]] 21 | name = "click" 22 | version = "8.1.3" 23 | description = "Composable command line interface toolkit" 24 | category = "main" 25 | optional = false 26 | python-versions = ">=3.7" 27 | 28 | [package.dependencies] 29 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 30 | 31 | [[package]] 32 | name = "colorama" 33 | version = "0.4.6" 34 | description = "Cross-platform colored terminal text." 35 | category = "main" 36 | optional = false 37 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 38 | 39 | [[package]] 40 | name = "commonmark" 41 | version = "0.9.1" 42 | description = "Python parser for the CommonMark Markdown spec" 43 | category = "main" 44 | optional = false 45 | python-versions = "*" 46 | 47 | [package.extras] 48 | test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] 49 | 50 | [[package]] 51 | name = "et-xmlfile" 52 | version = "1.1.0" 53 | description = "An implementation of lxml.xmlfile for the standard library" 54 | category = "main" 55 | optional = false 56 | python-versions = ">=3.6" 57 | 58 | [[package]] 59 | name = "idna" 60 | version = "3.4" 61 | description = "Internationalized Domain Names in Applications (IDNA)" 62 | category = "main" 63 | optional = false 64 | python-versions = ">=3.5" 65 | 66 | [[package]] 67 | name = "numpy" 68 | version = "1.23.5" 69 | description = "NumPy is the fundamental package for array computing with Python." 70 | category = "main" 71 | optional = false 72 | python-versions = ">=3.8" 73 | 74 | [[package]] 75 | name = "openai" 76 | version = "0.25.0" 77 | description = "Python client library for the OpenAI API" 78 | category = "main" 79 | optional = false 80 | python-versions = ">=3.7.1" 81 | 82 | [package.dependencies] 83 | numpy = "*" 84 | openpyxl = ">=3.0.7" 85 | pandas = ">=1.2.3" 86 | pandas-stubs = ">=1.1.0.11" 87 | requests = ">=2.20" 88 | tqdm = "*" 89 | typing_extensions = "*" 90 | 91 | [package.extras] 92 | dev = ["black (>=21.6b0,<22.0)", "pytest (>=6.0.0,<7.0.0)"] 93 | embeddings = ["matplotlib", "plotly", "scikit-learn (>=1.0.2)", "sklearn", "tenacity (>=8.0.1)"] 94 | wandb = ["wandb"] 95 | 96 | [[package]] 97 | name = "openpyxl" 98 | version = "3.0.10" 99 | description = "A Python library to read/write Excel 2010 xlsx/xlsm files" 100 | category = "main" 101 | optional = false 102 | python-versions = ">=3.6" 103 | 104 | [package.dependencies] 105 | et-xmlfile = "*" 106 | 107 | [[package]] 108 | name = "pandas" 109 | version = "1.5.2" 110 | description = "Powerful data structures for data analysis, time series, and statistics" 111 | category = "main" 112 | optional = false 113 | python-versions = ">=3.8" 114 | 115 | [package.dependencies] 116 | numpy = [ 117 | {version = ">=1.20.3", markers = "python_version < \"3.10\""}, 118 | {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, 119 | {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, 120 | ] 121 | python-dateutil = ">=2.8.1" 122 | pytz = ">=2020.1" 123 | 124 | [package.extras] 125 | test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] 126 | 127 | [[package]] 128 | name = "pandas-stubs" 129 | version = "1.2.0.62" 130 | description = "Type annotations for Pandas" 131 | category = "main" 132 | optional = false 133 | python-versions = "*" 134 | 135 | [[package]] 136 | name = "pygments" 137 | version = "2.13.0" 138 | description = "Pygments is a syntax highlighting package written in Python." 139 | category = "main" 140 | optional = false 141 | python-versions = ">=3.6" 142 | 143 | [package.extras] 144 | plugins = ["importlib-metadata"] 145 | 146 | [[package]] 147 | name = "python-dateutil" 148 | version = "2.8.2" 149 | description = "Extensions to the standard Python datetime module" 150 | category = "main" 151 | optional = false 152 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" 153 | 154 | [package.dependencies] 155 | six = ">=1.5" 156 | 157 | [[package]] 158 | name = "python-wordpress-xmlrpc" 159 | version = "2.3" 160 | description = "WordPress XML-RPC API Integration Library" 161 | category = "main" 162 | optional = false 163 | python-versions = "*" 164 | 165 | [[package]] 166 | name = "pytz" 167 | version = "2022.6" 168 | description = "World timezone definitions, modern and historical" 169 | category = "main" 170 | optional = false 171 | python-versions = "*" 172 | 173 | [[package]] 174 | name = "requests" 175 | version = "2.28.1" 176 | description = "Python HTTP for Humans." 177 | category = "main" 178 | optional = false 179 | python-versions = ">=3.7, <4" 180 | 181 | [package.dependencies] 182 | certifi = ">=2017.4.17" 183 | charset-normalizer = ">=2,<3" 184 | idna = ">=2.5,<4" 185 | urllib3 = ">=1.21.1,<1.27" 186 | 187 | [package.extras] 188 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 189 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] 190 | 191 | [[package]] 192 | name = "rich" 193 | version = "12.6.0" 194 | description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" 195 | category = "main" 196 | optional = false 197 | python-versions = ">=3.6.3,<4.0.0" 198 | 199 | [package.dependencies] 200 | commonmark = ">=0.9.0,<0.10.0" 201 | pygments = ">=2.6.0,<3.0.0" 202 | 203 | [package.extras] 204 | jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] 205 | 206 | [[package]] 207 | name = "six" 208 | version = "1.16.0" 209 | description = "Python 2 and 3 compatibility utilities" 210 | category = "main" 211 | optional = false 212 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 213 | 214 | [[package]] 215 | name = "tqdm" 216 | version = "4.64.1" 217 | description = "Fast, Extensible Progress Meter" 218 | category = "main" 219 | optional = false 220 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 221 | 222 | [package.dependencies] 223 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 224 | 225 | [package.extras] 226 | dev = ["py-make (>=0.1.0)", "twine", "wheel"] 227 | notebook = ["ipywidgets (>=6)"] 228 | slack = ["slack-sdk"] 229 | telegram = ["requests"] 230 | 231 | [[package]] 232 | name = "typer" 233 | version = "0.7.0" 234 | description = "Typer, build great CLIs. Easy to code. Based on Python type hints." 235 | category = "main" 236 | optional = false 237 | python-versions = ">=3.6" 238 | 239 | [package.dependencies] 240 | click = ">=7.1.1,<9.0.0" 241 | 242 | [package.extras] 243 | all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] 244 | dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] 245 | doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] 246 | test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] 247 | 248 | [[package]] 249 | name = "typing-extensions" 250 | version = "4.4.0" 251 | description = "Backported and Experimental Type Hints for Python 3.7+" 252 | category = "main" 253 | optional = false 254 | python-versions = ">=3.7" 255 | 256 | [[package]] 257 | name = "urllib3" 258 | version = "1.26.13" 259 | description = "HTTP library with thread-safe connection pooling, file post, and more." 260 | category = "main" 261 | optional = false 262 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" 263 | 264 | [package.extras] 265 | brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] 266 | secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] 267 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] 268 | 269 | [metadata] 270 | lock-version = "1.1" 271 | python-versions = "^3.9" 272 | content-hash = "7e5dbd00ad179361860eb85ab465afc65785b46fabeae804041008df065d12aa" 273 | 274 | [metadata.files] 275 | certifi = [ 276 | {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, 277 | {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, 278 | ] 279 | charset-normalizer = [ 280 | {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, 281 | {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, 282 | ] 283 | click = [ 284 | {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, 285 | {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, 286 | ] 287 | colorama = [ 288 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 289 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 290 | ] 291 | commonmark = [ 292 | {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, 293 | {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, 294 | ] 295 | et-xmlfile = [ 296 | {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, 297 | {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, 298 | ] 299 | idna = [ 300 | {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, 301 | {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, 302 | ] 303 | numpy = [ 304 | {file = "numpy-1.23.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9c88793f78fca17da0145455f0d7826bcb9f37da4764af27ac945488116efe63"}, 305 | {file = "numpy-1.23.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e9f4c4e51567b616be64e05d517c79a8a22f3606499941d97bb76f2ca59f982d"}, 306 | {file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7903ba8ab592b82014713c491f6c5d3a1cde5b4a3bf116404e08f5b52f6daf43"}, 307 | {file = "numpy-1.23.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e05b1c973a9f858c74367553e236f287e749465f773328c8ef31abe18f691e1"}, 308 | {file = "numpy-1.23.5-cp310-cp310-win32.whl", hash = "sha256:522e26bbf6377e4d76403826ed689c295b0b238f46c28a7251ab94716da0b280"}, 309 | {file = "numpy-1.23.5-cp310-cp310-win_amd64.whl", hash = "sha256:dbee87b469018961d1ad79b1a5d50c0ae850000b639bcb1b694e9981083243b6"}, 310 | {file = "numpy-1.23.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ce571367b6dfe60af04e04a1834ca2dc5f46004ac1cc756fb95319f64c095a96"}, 311 | {file = "numpy-1.23.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56e454c7833e94ec9769fa0f86e6ff8e42ee38ce0ce1fa4cbb747ea7e06d56aa"}, 312 | {file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5039f55555e1eab31124a5768898c9e22c25a65c1e0037f4d7c495a45778c9f2"}, 313 | {file = "numpy-1.23.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58f545efd1108e647604a1b5aa809591ccd2540f468a880bedb97247e72db387"}, 314 | {file = "numpy-1.23.5-cp311-cp311-win32.whl", hash = "sha256:b2a9ab7c279c91974f756c84c365a669a887efa287365a8e2c418f8b3ba73fb0"}, 315 | {file = "numpy-1.23.5-cp311-cp311-win_amd64.whl", hash = "sha256:0cbe9848fad08baf71de1a39e12d1b6310f1d5b2d0ea4de051058e6e1076852d"}, 316 | {file = "numpy-1.23.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f063b69b090c9d918f9df0a12116029e274daf0181df392839661c4c7ec9018a"}, 317 | {file = "numpy-1.23.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0aaee12d8883552fadfc41e96b4c82ee7d794949e2a7c3b3a7201e968c7ecab9"}, 318 | {file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92c8c1e89a1f5028a4c6d9e3ccbe311b6ba53694811269b992c0b224269e2398"}, 319 | {file = "numpy-1.23.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d208a0f8729f3fb790ed18a003f3a57895b989b40ea4dce4717e9cf4af62c6bb"}, 320 | {file = "numpy-1.23.5-cp38-cp38-win32.whl", hash = "sha256:06005a2ef6014e9956c09ba07654f9837d9e26696a0470e42beedadb78c11b07"}, 321 | {file = "numpy-1.23.5-cp38-cp38-win_amd64.whl", hash = "sha256:ca51fcfcc5f9354c45f400059e88bc09215fb71a48d3768fb80e357f3b457e1e"}, 322 | {file = "numpy-1.23.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8969bfd28e85c81f3f94eb4a66bc2cf1dbdc5c18efc320af34bffc54d6b1e38f"}, 323 | {file = "numpy-1.23.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7ac231a08bb37f852849bbb387a20a57574a97cfc7b6cabb488a4fc8be176de"}, 324 | {file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf837dc63ba5c06dc8797c398db1e223a466c7ece27a1f7b5232ba3466aafe3d"}, 325 | {file = "numpy-1.23.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33161613d2269025873025b33e879825ec7b1d831317e68f4f2f0f84ed14c719"}, 326 | {file = "numpy-1.23.5-cp39-cp39-win32.whl", hash = "sha256:af1da88f6bc3d2338ebbf0e22fe487821ea4d8e89053e25fa59d1d79786e7481"}, 327 | {file = "numpy-1.23.5-cp39-cp39-win_amd64.whl", hash = "sha256:09b7847f7e83ca37c6e627682f145856de331049013853f344f37b0c9690e3df"}, 328 | {file = "numpy-1.23.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:abdde9f795cf292fb9651ed48185503a2ff29be87770c3b8e2a14b0cd7aa16f8"}, 329 | {file = "numpy-1.23.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9a909a8bae284d46bbfdefbdd4a262ba19d3bc9921b1e76126b1d21c3c34135"}, 330 | {file = "numpy-1.23.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:01dd17cbb340bf0fc23981e52e1d18a9d4050792e8fb8363cecbf066a84b827d"}, 331 | {file = "numpy-1.23.5.tar.gz", hash = "sha256:1b1766d6f397c18153d40015ddfc79ddb715cabadc04d2d228d4e5a8bc4ded1a"}, 332 | ] 333 | openai = [ 334 | {file = "openai-0.25.0.tar.gz", hash = "sha256:59ac6531e4f7bf8e9a53186e853d9ffb1d5f07973ecb4f7d273163a314814510"}, 335 | ] 336 | openpyxl = [ 337 | {file = "openpyxl-3.0.10-py2.py3-none-any.whl", hash = "sha256:0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355"}, 338 | {file = "openpyxl-3.0.10.tar.gz", hash = "sha256:e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449"}, 339 | ] 340 | pandas = [ 341 | {file = "pandas-1.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e9dbacd22555c2d47f262ef96bb4e30880e5956169741400af8b306bbb24a273"}, 342 | {file = "pandas-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e2b83abd292194f350bb04e188f9379d36b8dfac24dd445d5c87575f3beaf789"}, 343 | {file = "pandas-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2552bffc808641c6eb471e55aa6899fa002ac94e4eebfa9ec058649122db5824"}, 344 | {file = "pandas-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fc87eac0541a7d24648a001d553406f4256e744d92df1df8ebe41829a915028"}, 345 | {file = "pandas-1.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0d8fd58df5d17ddb8c72a5075d87cd80d71b542571b5f78178fb067fa4e9c72"}, 346 | {file = "pandas-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:4aed257c7484d01c9a194d9a94758b37d3d751849c05a0050c087a358c41ad1f"}, 347 | {file = "pandas-1.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:375262829c8c700c3e7cbb336810b94367b9c4889818bbd910d0ecb4e45dc261"}, 348 | {file = "pandas-1.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc3cd122bea268998b79adebbb8343b735a5511ec14efb70a39e7acbc11ccbdc"}, 349 | {file = "pandas-1.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4f5a82afa4f1ff482ab8ded2ae8a453a2cdfde2001567b3ca24a4c5c5ca0db3"}, 350 | {file = "pandas-1.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8092a368d3eb7116e270525329a3e5c15ae796ccdf7ccb17839a73b4f5084a39"}, 351 | {file = "pandas-1.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6257b314fc14958f8122779e5a1557517b0f8e500cfb2bd53fa1f75a8ad0af2"}, 352 | {file = "pandas-1.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:82ae615826da838a8e5d4d630eb70c993ab8636f0eff13cb28aafc4291b632b5"}, 353 | {file = "pandas-1.5.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:457d8c3d42314ff47cc2d6c54f8fc0d23954b47977b2caed09cd9635cb75388b"}, 354 | {file = "pandas-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c009a92e81ce836212ce7aa98b219db7961a8b95999b97af566b8dc8c33e9519"}, 355 | {file = "pandas-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:71f510b0efe1629bf2f7c0eadb1ff0b9cf611e87b73cd017e6b7d6adb40e2b3a"}, 356 | {file = "pandas-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a40dd1e9f22e01e66ed534d6a965eb99546b41d4d52dbdb66565608fde48203f"}, 357 | {file = "pandas-1.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ae7e989f12628f41e804847a8cc2943d362440132919a69429d4dea1f164da0"}, 358 | {file = "pandas-1.5.2-cp38-cp38-win32.whl", hash = "sha256:530948945e7b6c95e6fa7aa4be2be25764af53fba93fe76d912e35d1c9ee46f5"}, 359 | {file = "pandas-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:73f219fdc1777cf3c45fde7f0708732ec6950dfc598afc50588d0d285fddaefc"}, 360 | {file = "pandas-1.5.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9608000a5a45f663be6af5c70c3cbe634fa19243e720eb380c0d378666bc7702"}, 361 | {file = "pandas-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:315e19a3e5c2ab47a67467fc0362cb36c7c60a93b6457f675d7d9615edad2ebe"}, 362 | {file = "pandas-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e18bc3764cbb5e118be139b3b611bc3fbc5d3be42a7e827d1096f46087b395eb"}, 363 | {file = "pandas-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0183cb04a057cc38fde5244909fca9826d5d57c4a5b7390c0cc3fa7acd9fa883"}, 364 | {file = "pandas-1.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:344021ed3e639e017b452aa8f5f6bf38a8806f5852e217a7594417fb9bbfa00e"}, 365 | {file = "pandas-1.5.2-cp39-cp39-win32.whl", hash = "sha256:e7469271497960b6a781eaa930cba8af400dd59b62ec9ca2f4d31a19f2f91090"}, 366 | {file = "pandas-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:c218796d59d5abd8780170c937b812c9637e84c32f8271bbf9845970f8c1351f"}, 367 | {file = "pandas-1.5.2.tar.gz", hash = "sha256:220b98d15cee0b2cd839a6358bd1f273d0356bf964c1a1aeb32d47db0215488b"}, 368 | ] 369 | pandas-stubs = [ 370 | {file = "pandas-stubs-1.2.0.62.tar.gz", hash = "sha256:89c022dad41d28e26a1290eb1585db1042ccb09e6951220bb5c9146e2f795147"}, 371 | {file = "pandas_stubs-1.2.0.62-py3-none-any.whl", hash = "sha256:32a9e04582173104d42c090135efacc64d70e08c003405455b7dfb1540bd7e6c"}, 372 | ] 373 | pygments = [ 374 | {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, 375 | {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, 376 | ] 377 | python-dateutil = [ 378 | {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, 379 | {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, 380 | ] 381 | python-wordpress-xmlrpc = [ 382 | {file = "python-wordpress-xmlrpc-2.3.zip", hash = "sha256:e15a8e9aca16db169369e5967299c29965570ed83c7c3ad418ed59b5ad1471bd"}, 383 | ] 384 | pytz = [ 385 | {file = "pytz-2022.6-py2.py3-none-any.whl", hash = "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427"}, 386 | {file = "pytz-2022.6.tar.gz", hash = "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2"}, 387 | ] 388 | requests = [ 389 | {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, 390 | {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, 391 | ] 392 | rich = [ 393 | {file = "rich-12.6.0-py3-none-any.whl", hash = "sha256:a4eb26484f2c82589bd9a17c73d32a010b1e29d89f1604cd9bf3a2097b81bb5e"}, 394 | {file = "rich-12.6.0.tar.gz", hash = "sha256:ba3a3775974105c221d31141f2c116f4fd65c5ceb0698657a11e9f295ec93fd0"}, 395 | ] 396 | six = [ 397 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, 398 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, 399 | ] 400 | tqdm = [ 401 | {file = "tqdm-4.64.1-py2.py3-none-any.whl", hash = "sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1"}, 402 | {file = "tqdm-4.64.1.tar.gz", hash = "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4"}, 403 | ] 404 | typer = [ 405 | {file = "typer-0.7.0-py3-none-any.whl", hash = "sha256:b5e704f4e48ec263de1c0b3a2387cd405a13767d2f907f44c1a08cbad96f606d"}, 406 | {file = "typer-0.7.0.tar.gz", hash = "sha256:ff797846578a9f2a201b53442aedeb543319466870fbe1c701eab66dd7681165"}, 407 | ] 408 | typing-extensions = [ 409 | {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, 410 | {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, 411 | ] 412 | urllib3 = [ 413 | {file = "urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc"}, 414 | {file = "urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"}, 415 | ] 416 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "gpt3-wordpress-cli" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["Nicola Ballotta <432172+nicolaballotta@users.noreply.github.com>"] 6 | readme = "README.md" 7 | packages = [{include = "gpt3_wordpress_cli"}] 8 | 9 | [tool.poetry.dependencies] 10 | python = "^3.9" 11 | click = "^8.1.3" 12 | openai = "^0.25.0" 13 | python-wordpress-xmlrpc = "^2.3" 14 | typer = "^0.7.0" 15 | rich = "^12.6.0" 16 | 17 | 18 | [build-system] 19 | requires = ["poetry-core"] 20 | build-backend = "poetry.core.masonry.api" 21 | 22 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolaballotta/gpt3-wordpress-post-generator/01e28f93c3a5f9b6b5f259c0a38b55b2a3b56058/screenshot.png --------------------------------------------------------------------------------