diff --git a/app.py b/app.py index 8a259d0..50e459c 100644 --- a/app.py +++ b/app.py @@ -6,24 +6,35 @@ app = FastAPI(title="Nepali Calendar API") DATA_DIR = "./data" + @app.get("/", summary="Root Endpoint") async def root(): - return {"message": "Welcome to the Nepali Calendar API. Use /docs for interactive API documentation."} + return { + "message": "Welcome to the Nepali Calendar API. Use /docs for interactive API documentation." + } + @app.get("/calendar/{year}", summary="Get Yearly Calendar") async def get_year_calendar(year: int): file_path = f"{DATA_DIR}/{year}.json" if not os.path.exists(file_path): - raise HTTPException(status_code=404, detail=f"Calendar data for year {year} not found. Please run the scraper for this year.") - + raise HTTPException( + status_code=404, + detail=f"Calendar data for year {year} not found. Please run the scraper for this year.", + ) + with open(file_path, "r", encoding="utf-8") as f: return json.load(f) + @app.get("/calendar/{year}/{month}", summary="Get Monthly Calendar") async def get_month_calendar(year: int, month: int): file_path = f"{DATA_DIR}/{year}/{month}.json" if not os.path.exists(file_path): - raise HTTPException(status_code=404, detail=f"Calendar data for {year}/{month} not found. Please run the scraper for this year.") - + raise HTTPException( + status_code=404, + detail=f"Calendar data for {year}/{month} not found. Please run the scraper for this year.", + ) + with open(file_path, "r", encoding="utf-8") as f: - return json.load(f) \ No newline at end of file + return json.load(f) diff --git a/pyproject.toml b/pyproject.toml index fb1d2bd..b559149 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,3 +14,7 @@ dependencies = [ authors = [ { name = "Sankalp Tharu", email = 'sankalptharu50028@gmail.com' }, ] +[dependency-groups] +dev = [ + "ruff>=0.14.6", +] diff --git a/scraper.py b/scraper.py index 9323e32..64d9034 100644 --- a/scraper.py +++ b/scraper.py @@ -147,7 +147,9 @@ async def fetch_month(session, year, month, save_dir=True, attempt=1): async def scrape_year(session, year, save_single=True, save_dir=True): print(Style.BRIGHT + f"\nStarting scrape for year: {Fore.CYAN}{year}") - print(f" Mode: {'Single JSON' if save_single else ''} {'Directory' if save_dir else ''}\n") + print( + f" Mode: {'Single JSON' if save_single else ''} {'Directory' if save_dir else ''}\n" + ) year_data = {} success_count = 0 @@ -167,7 +169,7 @@ async def scrape_year(session, year, save_single=True, save_dir=True): with open(year_file_path, "w", encoding="utf-8") as f: json.dump(year_data, f, indent=2, ensure_ascii=False) print(Style.BRIGHT + Fore.GREEN + f"\nSaved aggregated file: {year_file_path}") - + fail_count = 12 - success_count print(Fore.LIGHTBLACK_EX + f"Success: {success_count} Failed: {fail_count}\n") @@ -183,9 +185,21 @@ async def scrape_years(start_year, end_year, save_single=True, save_dir=True): if __name__ == "__main__": parser = argparse.ArgumentParser(description="Nepali Calendar Scraper") - parser.add_argument("years", nargs="+", type=int, help="Year or year range (start end)") - parser.add_argument("--single", nargs="?", const="json", help="Generate single JSON (e.g. --single json)") - parser.add_argument("--dir", nargs="?", const="format", help="Generate directory format (e.g. --dir format)") + parser.add_argument( + "years", nargs="+", type=int, help="Year or year range (start end)" + ) + parser.add_argument( + "--single", + nargs="?", + const="json", + help="Generate single JSON (e.g. --single json)", + ) + parser.add_argument( + "--dir", + nargs="?", + const="format", + help="Generate directory format (e.g. --dir format)", + ) args = parser.parse_args() diff --git a/test.py b/test.py index d6fdc39..07f933c 100644 --- a/test.py +++ b/test.py @@ -6,29 +6,41 @@ app = FastAPI(title="Nepali Calendar API") DATA_DIR = "./data" + @app.get("/", summary="Root Endpoint") async def root(): - return {"message": "Welcome to the Nepali Calendar API. Use /docs for interactive API documentation."} + return { + "message": "Welcome to the Nepali Calendar API. Use /docs for interactive API documentation." + } + @app.get("/calendar/{year}", summary="Get Yearly Calendar") async def get_year_calendar(year: int): file_path = f"{DATA_DIR}/{year}.json" if not os.path.exists(file_path): - raise HTTPException(status_code=404, detail=f"Calendar data for year {year} not found. Please run the scraper for this year.") - + raise HTTPException( + status_code=404, + detail=f"Calendar data for year {year} not found. Please run the scraper for this year.", + ) + with open(file_path, "r", encoding="utf-8") as f: return json.load(f) + @app.get("/calendar/{year}/{month}", summary="Get Monthly Calendar") async def get_month_calendar(year: int, month: int): file_path = f"{DATA_DIR}/{year}/{month}.json" if not os.path.exists(file_path): - raise HTTPException(status_code=404, detail=f"Calendar data for {year}/{month} not found. Please run the scraper for this year.") - + raise HTTPException( + status_code=404, + detail=f"Calendar data for {year}/{month} not found. Please run the scraper for this year.", + ) + with open(file_path, "r", encoding="utf-8") as f: return json.load(f) if __name__ == "__main__": import uvicorn + uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/uv.lock b/uv.lock index 3d7c7ee..ce99133 100644 --- a/uv.lock +++ b/uv.lock @@ -363,6 +363,11 @@ dependencies = [ { name = "uvicorn" }, ] +[package.dev-dependencies] +dev = [ + { name = "ruff" }, +] + [package.metadata] requires-dist = [ { name = "aiohttp", specifier = ">=3.13.3" }, @@ -372,6 +377,9 @@ requires-dist = [ { name = "uvicorn", specifier = ">=0.34.0" }, ] +[package.metadata.requires-dev] +dev = [{ name = "ruff", specifier = ">=0.14.6" }] + [[package]] name = "propcache" version = "0.4.1" @@ -509,6 +517,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, ] +[[package]] +name = "ruff" +version = "0.14.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/50/0a/1914efb7903174b381ee2ffeebb4253e729de57f114e63595114c8ca451f/ruff-0.14.13.tar.gz", hash = "sha256:83cd6c0763190784b99650a20fec7633c59f6ebe41c5cc9d45ee42749563ad47", size = 6059504, upload-time = "2026-01-15T20:15:16.918Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/ae/0deefbc65ca74b0ab1fd3917f94dc3b398233346a74b8bbb0a916a1a6bf6/ruff-0.14.13-py3-none-linux_armv6l.whl", hash = "sha256:76f62c62cd37c276cb03a275b198c7c15bd1d60c989f944db08a8c1c2dbec18b", size = 13062418, upload-time = "2026-01-15T20:14:50.779Z" }, + { url = "https://files.pythonhosted.org/packages/47/df/5916604faa530a97a3c154c62a81cb6b735c0cb05d1e26d5ad0f0c8ac48a/ruff-0.14.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:914a8023ece0528d5cc33f5a684f5f38199bbb566a04815c2c211d8f40b5d0ed", size = 13442344, upload-time = "2026-01-15T20:15:07.94Z" }, + { url = "https://files.pythonhosted.org/packages/4c/f3/e0e694dd69163c3a1671e102aa574a50357536f18a33375050334d5cd517/ruff-0.14.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d24899478c35ebfa730597a4a775d430ad0d5631b8647a3ab368c29b7e7bd063", size = 12354720, upload-time = "2026-01-15T20:15:09.854Z" }, + { url = "https://files.pythonhosted.org/packages/c3/e8/67f5fcbbaee25e8fc3b56cc33e9892eca7ffe09f773c8e5907757a7e3bdb/ruff-0.14.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9aaf3870f14d925bbaf18b8a2347ee0ae7d95a2e490e4d4aea6813ed15ebc80e", size = 12774493, upload-time = "2026-01-15T20:15:20.908Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ce/d2e9cb510870b52a9565d885c0d7668cc050e30fa2c8ac3fb1fda15c083d/ruff-0.14.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac5b7f63dd3b27cc811850f5ffd8fff845b00ad70e60b043aabf8d6ecc304e09", size = 12815174, upload-time = "2026-01-15T20:15:05.74Z" }, + { url = "https://files.pythonhosted.org/packages/88/00/c38e5da58beebcf4fa32d0ddd993b63dfacefd02ab7922614231330845bf/ruff-0.14.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d2b1097750d90ba82ce4ba676e85230a0ed694178ca5e61aa9b459970b3eb9", size = 13680909, upload-time = "2026-01-15T20:15:14.537Z" }, + { url = "https://files.pythonhosted.org/packages/61/61/cd37c9dd5bd0a3099ba79b2a5899ad417d8f3b04038810b0501a80814fd7/ruff-0.14.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d0bf87705acbbcb8d4c24b2d77fbb73d40210a95c3903b443cd9e30824a5032", size = 15144215, upload-time = "2026-01-15T20:15:22.886Z" }, + { url = "https://files.pythonhosted.org/packages/56/8a/85502d7edbf98c2df7b8876f316c0157359165e16cdf98507c65c8d07d3d/ruff-0.14.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3eb5da8e2c9e9f13431032fdcbe7681de9ceda5835efee3269417c13f1fed5c", size = 14706067, upload-time = "2026-01-15T20:14:48.271Z" }, + { url = "https://files.pythonhosted.org/packages/7e/2f/de0df127feb2ee8c1e54354dc1179b4a23798f0866019528c938ba439aca/ruff-0.14.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:642442b42957093811cd8d2140dfadd19c7417030a7a68cf8d51fcdd5f217427", size = 14133916, upload-time = "2026-01-15T20:14:57.357Z" }, + { url = "https://files.pythonhosted.org/packages/0d/77/9b99686bb9fe07a757c82f6f95e555c7a47801a9305576a9c67e0a31d280/ruff-0.14.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4acdf009f32b46f6e8864af19cbf6841eaaed8638e65c8dac845aea0d703c841", size = 13859207, upload-time = "2026-01-15T20:14:55.111Z" }, + { url = "https://files.pythonhosted.org/packages/7d/46/2bdcb34a87a179a4d23022d818c1c236cb40e477faf0d7c9afb6813e5876/ruff-0.14.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:591a7f68860ea4e003917d19b5c4f5ac39ff558f162dc753a2c5de897fd5502c", size = 14043686, upload-time = "2026-01-15T20:14:52.841Z" }, + { url = "https://files.pythonhosted.org/packages/1a/a9/5c6a4f56a0512c691cf143371bcf60505ed0f0860f24a85da8bd123b2bf1/ruff-0.14.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:774c77e841cc6e046fc3e91623ce0903d1cd07e3a36b1a9fe79b81dab3de506b", size = 12663837, upload-time = "2026-01-15T20:15:18.921Z" }, + { url = "https://files.pythonhosted.org/packages/fe/bb/b920016ece7651fa7fcd335d9d199306665486694d4361547ccb19394c44/ruff-0.14.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:61f4e40077a1248436772bb6512db5fc4457fe4c49e7a94ea7c5088655dd21ae", size = 12805867, upload-time = "2026-01-15T20:14:59.272Z" }, + { url = "https://files.pythonhosted.org/packages/7d/b3/0bd909851e5696cd21e32a8fc25727e5f58f1934b3596975503e6e85415c/ruff-0.14.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6d02f1428357fae9e98ac7aa94b7e966fd24151088510d32cf6f902d6c09235e", size = 13208528, upload-time = "2026-01-15T20:15:03.732Z" }, + { url = "https://files.pythonhosted.org/packages/3b/3b/e2d94cb613f6bbd5155a75cbe072813756363eba46a3f2177a1fcd0cd670/ruff-0.14.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e399341472ce15237be0c0ae5fbceca4b04cd9bebab1a2b2c979e015455d8f0c", size = 13929242, upload-time = "2026-01-15T20:15:11.918Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c5/abd840d4132fd51a12f594934af5eba1d5d27298a6f5b5d6c3be45301caf/ruff-0.14.13-py3-none-win32.whl", hash = "sha256:ef720f529aec113968b45dfdb838ac8934e519711da53a0456038a0efecbd680", size = 12919024, upload-time = "2026-01-15T20:14:43.647Z" }, + { url = "https://files.pythonhosted.org/packages/c2/55/6384b0b8ce731b6e2ade2b5449bf07c0e4c31e8a2e68ea65b3bafadcecc5/ruff-0.14.13-py3-none-win_amd64.whl", hash = "sha256:6070bd026e409734b9257e03e3ef18c6e1a216f0435c6751d7a8ec69cb59abef", size = 14097887, upload-time = "2026-01-15T20:15:01.48Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e1/7348090988095e4e39560cfc2f7555b1b2a7357deba19167b600fdf5215d/ruff-0.14.13-py3-none-win_arm64.whl", hash = "sha256:7ab819e14f1ad9fe39f246cfcc435880ef7a9390d81a2b6ac7e01039083dd247", size = 13080224, upload-time = "2026-01-15T20:14:45.853Z" }, +] + [[package]] name = "soupsieve" version = "2.8.1"