{"id":18654384,"url":"https://github.com/llmkira/novelai-python","last_synced_at":"2025-05-09T03:29:28.359Z","repository":{"id":219205178,"uuid":"748460728","full_name":"LlmKira/novelai-python","owner":"LlmKira","description":"✨ NovelAI api python sdk, easy to use, modern and user-friendly.","archived":false,"fork":false,"pushed_at":"2025-01-05T11:55:11.000Z","size":15764,"stargazers_count":31,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-31T11:05:49.876Z","etag":null,"topics":["async","generative-ai-tools","image-generation","large-language-model","nai-diffusion","novelai","python3","stable-diffusion","text-generation","voice-generation"],"latest_commit_sha":null,"homepage":"https://novelai.net","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LlmKira.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-26T02:30:00.000Z","updated_at":"2025-01-21T14:20:40.000Z","dependencies_parsed_at":"2024-01-30T16:08:12.226Z","dependency_job_id":"938d958e-6f3f-4ab7-988b-8b100c9d87d8","html_url":"https://github.com/LlmKira/novelai-python","commit_stats":null,"previous_names":["llmkira/novelai-python"],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LlmKira%2Fnovelai-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LlmKira%2Fnovelai-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LlmKira%2Fnovelai-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LlmKira%2Fnovelai-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LlmKira","download_url":"https://codeload.github.com/LlmKira/novelai-python/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238053511,"owners_count":19408702,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","generative-ai-tools","image-generation","large-language-model","nai-diffusion","novelai","python3","stable-diffusion","text-generation","voice-generation"],"created_at":"2024-11-07T07:14:59.555Z","updated_at":"2025-05-09T03:29:28.352Z","avatar_url":"https://github.com/LlmKira.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![banner](https://github.com/LlmKira/novelai-python/blob/dev/playground/banner-raw.png?raw=true)\n\n---\n\n[![PyPI version](https://badge.fury.io/py/novelai-python.svg)](https://badge.fury.io/py/novelai-python)\n[![Downloads](https://pepy.tech/badge/novelai_python)](https://pepy.tech/project/novelai_python)\n\n✨ NovelAI api python sdk with Pydantic, modern and user-friendly.\n\nThe goal of this repository is to use Pydantic to build legitimate requests to access\nthe [NovelAI API service](https://api.novelai.net/docs).\n\n\u003e Python \u003e= 3.9 is required.\n\n### 📰 News\n\n- [NovelAI Diffusion V4.5 Curated is Here!](https://blog.novelai.net/novelai-diffusion-v4-5-curated-is-here-9e5ba1f628f3)\n- [Image Generation Model Release — NovelAI Anime Diffusion V4 Curated Preview (EN)](https://blog.novelai.net/release-novelai-anime-diffusion-v4-curated-preview-en-ca4b0b11e671)\n- [Tutorial: Creating Consistent Characters with NovelAI Diffusion Anime [Female]](https://blog.novelai.net/tutorial-en-creating-consistent-characters-with-novelai-diffusion-anime-female-538b4b678a4e)\n\n### 📦 Usage\n\n```shell\npip -U install novelai-python\n```\n\nAll API users must adhere to the NovelAI Terms of Service: https://novelai.net/terms.\n\n**More examples can be found in the [playground](https://github.com/LlmKira/novelai-python/tree/main/playground)\ndirectory, read code as documentation.**\n\n```python\nimport asyncio\nimport os\n\nfrom dotenv import load_dotenv\nfrom pydantic import SecretStr\n\nfrom novelai_python import GenerateImageInfer, ImageGenerateResp, ApiCredential\nfrom novelai_python.sdk.ai.generate_image import Model, Character, Sampler, UCPreset\nfrom novelai_python.sdk.ai.generate_image.schema import PositionMap\n\nload_dotenv()\nsession = ApiCredential(api_token=SecretStr(os.getenv(\"NOVELAI_JWT\")))  # pst-***\n# For security reasons, storing user credentials in plaintext is strongly discouraged.\n\nprompt = \"2girls, fisheye, closeup, from above\"\n\n\nasync def main():\n    gen = GenerateImageInfer.build_generate(\n        prompt=prompt,\n        model=Model.NAI_DIFFUSION_4_5_CURATED,\n        character_prompts=[\n            Character(\n                prompt=\"1girl, head tilt, short hair, black hair, grey eyes, small breasts, looking at viewer\",\n                uc=\"red hair\",\n                center=PositionMap.B2\n            ),\n            Character(\n                prompt=\"1girl, fox ears, fox tail, white hair, white tail, white ears\",\n                uc=\"black hair\",\n                center=PositionMap.D2\n            )\n        ],\n        sampler=Sampler.K_EULER_ANCESTRAL,\n        ucPreset=UCPreset.TYPE0,\n        # Recommended, using preset negative_prompt depends on selected model\n        qualityToggle=True,\n        decrisp_mode=False,\n        variety_boost=True,\n        # Checkbox in novelai.net\n    )\n    cost = gen.calculate_cost(is_opus=True)\n    print(f\"charge: {cost} if you are vip3\")\n    resp = await gen.request(session=session)\n    resp: ImageGenerateResp\n    print(resp.meta)\n    file = resp.files[0]\n    with open(file[0], \"wb\") as f:\n        f.write(file[1])\n\n\nloop = asyncio.get_event_loop()\nloop.run_until_complete(main())\n\n```\n\n#### 📦 LLM\n\n```python\nimport asyncio\nimport os\n\nfrom dotenv import load_dotenv\nfrom pydantic import SecretStr\n\nfrom novelai_python import APIError, LoginCredential\nfrom novelai_python.sdk.ai.generate import TextLLMModel, LLM, get_default_preset, AdvanceLLMSetting\nfrom novelai_python.sdk.ai.generate._enum import get_model_preset\n\nload_dotenv()\nusername = os.getenv(\"NOVELAI_USER\", None)\nassert username is not None\n# credential = JwtCredential(jwt_token=SecretStr(jwt))\nlogin_credential = LoginCredential(\n    username=os.getenv(\"NOVELAI_USER\"),\n    password=SecretStr(os.getenv(\"NOVELAI_PASS\"))\n)\n\n\nasync def chat(prompt: str):\n    try:\n        model = TextLLMModel.ERATO  # llama3\n        parameters = get_default_preset(model).parameters\n        agent = LLM.build(\n            prompt=prompt,\n            model=model,\n            # parameters=None,  # Auto Select or get from preset\n            parameters=get_model_preset(TextLLMModel.ERATO).get_all_presets()[0].parameters,  # Select from enum preset\n            advanced_setting=AdvanceLLMSetting(\n                min_length=1,\n                max_length=None,  # Auto\n            )\n        )\n        # NOTE:parameter \u003e advanced_setting, which logic in generate/__init__.py\n        # If you not pass the parameter, it will use the default preset.\n        # So if you want to set the generation params, you should pass your own params.\n        # Only if you want to use some params not affect the generation, you can use advanced_setting.\n        result = await agent.request(session=login_credential)\n    except APIError as e:\n        raise Exception(f\"Error: {e.message}\")\n    print(f\"Result: \\n{result.text}\")\n\n\nloop = asyncio.get_event_loop()\nloop.run_until_complete(chat(\"Hello\"))\n```\n\n#### 📦 Random Prompt\n\n```python\nfrom novelai_python.tool.random_prompt import RandomPromptGenerator\n\ngenerator = RandomPromptGenerator()\nfor i in range(10):\n    print(generator.generate_common_tags(nsfw=False))\n    print(generator.generate_scene_tags())\n    print(generator.generate_scene_composition())\n    print(generator.get_holiday_themed_tags())\n```\n\n#### 📦 Run A Server\n\n```shell\npip install novelai_python\npython3 -m novelai_python.server -h '127.0.0.1' -p 7888\n```\n\n#### 📦 Tokenizer\n\n```python\nfrom novelai_python._enum import get_tokenizer_model, TextLLMModel, TextTokenizerGroup\nfrom novelai_python.tokenizer import NaiTokenizer\n\n# Through llm model name to get the tokenizer\ntokenizer_package = NaiTokenizer(get_tokenizer_model(TextLLMModel.ERATO))\n# Directly use the tokenizer\nclip_tokenizer = NaiTokenizer(TextTokenizerGroup.CLIP)\n\n# Tokenize a text\nt_text = \"a fox jumped over the lazy dog\"\nencode_tokens = tokenizer_package.encode(t_text)\nprint(tokenizer_package.tokenize_text(t_text))\nprint(f\"Tokenized text: {encode_tokens}\")\nprint(tokenizer_package.decode(tokenizer_package.encode(t_text)))\n\n```\n\n### 🔨 Roadmap\n\n- [x] tool.random_prompt\n- [x] tool.paint_mask\n- [x] tool.image_metadata\n- [x] tokenizer\n- [x] /ai/generate-image\n- [x] /user/subscription\n- [x] /user/login\n- [x] /user/information\n- [x] /ai/upscale\n- [x] /ai/generate-image/suggest-tags\n- [x] /ai/generate-voice\n- [x] /ai/generate-stream\n- [x] /ai/generate\n- [x] /ai/augment-image\n- [ ] /ai/annotate-image\n- [ ] /ai/classify\n- [ ] /ai/generate-prompt\n\n\u003e GenerateImageInfer.calculate_cost is correct in most cases, but please request account information to get accurate\n\u003e consumption information.\n\n\u003e This repo is maintained by me personally now. If you have any questions, please feel free to open an issue.\n\n## 🚫 About Nsfw\n\nYou might need some solutions for identifying NSFW content and adding a mosaic to prevent operational mishaps.\n\nhttps://dghs-imgutils.deepghs.org/main/api_doc/detect/nudenet.html\n\nhttps://dghs-imgutils.deepghs.org/main/api_doc/operate/censor.html\n\n## 🙏 Acknowledgements\n\n[novelai-api](https://github.com/Aedial/novelai-api)\n\n[NovelAI-API](https://github.com/HanaokaYuzu/NovelAI-API)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fllmkira%2Fnovelai-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fllmkira%2Fnovelai-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fllmkira%2Fnovelai-python/lists"}