Package: curse-api
curse-apiA simple async python Curseforge api wrapper using pydanticBuilt to serve CF endpoints while providing methods and functions to assist in finding the right mod.Quick Install:pip install curse-api[quick]FeaturesQuick StartExamplesSome backstoryA while back when I was starting to learn python further then the basics I created a small tool to download Minecraft mods from a pack manifest.
Soon after I wrote it the new API changes came and broke it. Now once more I want to return to that project idea and expand further. After first rewriting the project usingchiliit felt off, so returned to rewrite once more usingpydanticfor data validation and ease of access. This is mostly a pet project to learn further python.FeaturesMain Dependency:PydanticNative async library support:Aiohttp-pip install curse-api[aiohttp]Httpx-pip install curse-api[httpx]Currently implemented:Important endpoint supportFull CurseForge modelMediocre error handlingPluggable API factoriesSerialization and deserialization of modelsPython 3.7, 3.8 & 3.9 supportAsyncTo Do:Fix to be usable with pydantic based ORM'sAddress all TODO'sTest other games tooAdd moreWrite docsUpdate and fix error handlingShortcuts to import clientsCI/CD:Type checkingVersion testingTestsExamplesQuick startRequires an api from CF to use the API. You can get onehere.
This example runs through most of the basicsfromcurse_apiimportCurseAPIfromcurse_api.clients.httpximportHttpxFactoryimportosimportasyncioasyncdefmain():asyncwithCurseAPI(os.environ["CF_API_KEY"],factory=HttpxFactory)asapi:"Mods"a=awaitapi.search_mods(searchFilter="JEI",slug="jei")# applies the search filters to the standard of CF docsmod=awaitapi.get_mod(250398)# returns a singular Modmod_list=awaitapi.get_mods([285109,238222])# returns a list of Mods"files""See examples/download.py"# TODO finish file supportfiles=awaitapi.get_files([3940240])# returns a list of Files matching their idmod_files=awaitapi.get_mod_files(238222)# returns all the Files of on a give Mod"Version details - large data""See examples/modloader.py"mc=awaitapi.minecraft_versions()# returns all of minecraft version dataml=awaitapi.modloader_versions()# returns **ALL** modloader versions on curseforgemc_112=awaitapi.get_specific_minecraft_version("1.12.2")# returns minecraft version related informationforge=awaitapi.get_specific_minecraft_modloader("forge-36.2.39")# returns forge related version informationif__name__=="__main__":asyncio.run(main())Downloading to a fileThis example opens a properly named file in the current working directory and writes to it.fromcurse_apiimportCurseAPIfromcurse_api.clients.httpximportHttpxFactoryimportosimportasyncioasyncdefmain():asyncwithCurseAPI(os.environ["CF_API_KEY"],factory=HttpxFactory)asapi:# fetch the latest file from project with slug 'jei'mod_l,page_data=awaitapi.search_mods(slug="jei")latest=mod_l[0].latestFiles[0]withopen(latest.fileName,"wb")asf:down=awaitapi.download(latest.downloadUrl)# type: ignoreasyncforbindown:f.write(b)if__name__=="__main__":asyncio.run(main())Sub project / extension ideasModloader download and installationMinecraft Version type / parserMC pack installationDB cache extensionManifest parsing