From f6f3296b0af3eaaa222978f29a2fe6afd8e376d8 Mon Sep 17 00:00:00 2001 From: Bryce Date: Wed, 27 May 2026 09:30:18 -0700 Subject: [PATCH] uses openrouter --- .gitignore | 1 + code/main.py | 40 +++++++++++++++++++++++++++------------- pyproject.toml | 1 + uv.lock | 11 +++++++++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index d6c7339..c9ba8ae 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ layer *.zip .py_cache .venv +.env diff --git a/code/main.py b/code/main.py index 06ee0b3..a426d03 100755 --- a/code/main.py +++ b/code/main.py @@ -2,11 +2,21 @@ import base64 import json import os +import re import urllib.request +from dotenv import load_dotenv + +_env_path = os.path.join(os.path.dirname(__file__), '.env') +if os.path.exists(_env_path): + load_dotenv(_env_path) + import openai -client = openai.OpenAI(api_key="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") +client = openai.OpenAI( + api_key=os.environ["OPENROUTER_API_KEY"], + base_url="https://openrouter.ai/api/v1", +) def slurp_file(filename): @@ -36,7 +46,7 @@ IMPORTANT: - Do NOT skip entries because some fields are missing. Extract what you can. - For statements/summaries, each row in an invoice table is a separate invoice entry. - If OCR fails completely and no text can be extracted at all, return an array with one object containing only the explanation field. -- Your FINAL response to the user must be ONLY a JSON array. Do NOT wrap it in markdown code blocks. Do NOT add any prose before or after the JSON.""" +- Your FINAL response must be ONLY a JSON array. Do NOT wrap it in markdown code blocks. Do NOT add any prose before or after the JSON.""" def analyze_pdf(pdf_path): @@ -45,28 +55,32 @@ def analyze_pdf(pdf_path): base64_string = base64.b64encode(pdf_data).decode("utf-8") - response = client.responses.create( - model="gpt-4o", - instructions=BASE_PROMPT, - input=[ + response = client.chat.completions.create( + model="openai/gpt-4o", + messages=[ + { + "role": "system", + "content": BASE_PROMPT, + }, { "role": "user", "content": [ { - "type": "input_file", - "filename": os.path.basename(pdf_path), - "file_data": f"data:application/pdf;base64,{base64_string}", + "type": "file", + "file": { + "filename": os.path.basename(pdf_path), + "file_data": f"data:application/pdf;base64,{base64_string}", + }, }, { - "type": "input_text", + "type": "text", "text": "extract the invoice(s) and/or credit(s) details from this document.", }, ], - } + }, ], ) - text = response.output_text - import re + text = response.choices[0].message.content match = re.search(r'```(?:json)?\s*\n(.*?)\n```', text, re.DOTALL) if match: text = match.group(1) diff --git a/pyproject.toml b/pyproject.toml index c912735..b6fbfda 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,4 +6,5 @@ requires-python = ">=3.11" dependencies = [ "openai==1.109.1", "pydantic==2.13.4", + "python-dotenv>=1.2.2", ] diff --git a/uv.lock b/uv.lock index 2e1caa9..5054739 100644 --- a/uv.lock +++ b/uv.lock @@ -58,12 +58,14 @@ source = { virtual = "." } dependencies = [ { name = "openai" }, { name = "pydantic" }, + { name = "python-dotenv" }, ] [package.metadata] requires-dist = [ { name = "openai", specifier = "==1.109.1" }, { name = "pydantic", specifier = "==2.13.4" }, + { name = "python-dotenv", specifier = ">=1.2.2" }, ] [[package]] @@ -339,6 +341,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" }, ] +[[package]] +name = "python-dotenv" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, +] + [[package]] name = "sniffio" version = "1.3.1"