Why http via proxy not working?

Hi buddies,
I’m trying to access gpt api via swi-prolog, and have tried stable version 9.0.3 and development 9.1.10. I have to use proxy for this here but always got time out errors. Below is the message. Any helps are greatly appreciated!

  1. proxy is ok because python program works well:
arthurwang@ArthurdeMacBook-Pro python % echo $all_proxy
http://127.0.0.1:10077
arthurwang@ArthurdeMacBook-Pro python % python3 gptapi.py
你好,你怎么样?
arthurwang@ArthurdeMacBook-Pro python % cat gptapi.py
import requests
import json

API_KEY = ""
API_ENDPOINT = "https://api.openai.com/v1/chat/completions"

def generate_chat_completion(messages, model="gpt-3.5-turbo", temperature=1, max_tokens=None):
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {API_KEY}",
    }

    data = {
        "model": model,
        "messages": messages,
        "temperature": temperature,
    }

    if max_tokens is not None:
        data["max_tokens"] = max_tokens

    response = requests.post(API_ENDPOINT, headers=headers, data=json.dumps(data))

    if response.status_code == 200:
        return response.json()["choices"][0]["message"]["content"]
    else:
        raise Exception(f"Error {response.status_code}: {response.text}")

messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Translate the following English text to Chinese: 'Hello, how are you?'"}
]
response_text = generate_chat_completion(messages)
print(response_text)
  1. prolog code:
%server.pl
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
% :- use_module(library(http/http_unix_daemon)).
:- use_module(library(http/http_files)).
:- use_module(library(http/http_json)).
:- use_module(library(http/http_client)).
:- multifile http:location/3.
http:location(files, root(files), []).
server(Port) :-
	http_server(http_dispatch, [port(Port)]).
:- http_handler(root(.), http_reply_from_files('.', []), [prefix]). % defaults to index.html
:- http_handler(files(.), serve_files_in_directory(folders), [prefix]).
:- http_handler('/api', handle_api, []).

handle_api(Request) :-
	member(method(post), Request), !,
	http_read_json_dict(Request, Query),
	query_gpt(Query, Solution),
	reply_json_dict(Solution), !.
handle_api(Request) :-
	reply_json_dict(_{req:Request}).


query_gpt(_{query:Query}, Solution) :-
	Url = 'https://api.openai.com/v1/chat/completions',
	Headers = headers([content_type('application/json; charset="utf-8"')]),
	Data = _{
		model: 'gpt-3.5-turbo',
		temperature:0.7,
		messages:[
			_{
				role: user,
				content: Query
			}
		]
	},
	http_post(Url, Data, Solution, [Headers, authorization(bearer('my key'))]).
  1. call query_gpt:
arthurwang@ArthurdeMacBook-Pro gptapi % swipl server.pl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.0.3)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- query_gpt(_{query:'Say hello in Chinese'}, Reply).
ERROR: Socket error: Operation timed out
ERROR: In:
ERROR:   [21] throw(error(socket_error(etimedout,'Operation timed out'),_6888))
ERROR:   [19] catch('<garbage_collected>','<garbage_collected>','<garbage_collected>') at /usr/local/Cellar/swi-prolog/9.0.3/libexec/lib/swipl/boot/init.pl:565
ERROR:   [17] socket:tcp_connect('api.openai.com':443,_6954,[visited(...),...|...]) at /usr/local/Cellar/swi-prolog/9.0.3/libexec/lib/swipl/library/socket.pl:385
ERROR:   [16] http_open:open_socket('<garbage_collected>',_7010,[visited(...),...|...]) at /usr/local/Cellar/swi-prolog/9.0.3/libexec/lib/swipl/library/http/http_open.pl:945
ERROR:   [14] http_open:try_http_proxy(direct,[uri('https://api.openai.com/v1/chat/completions'),...|...],_7062,'<garbage_collected>') at /usr/local/Cellar/swi-prolog/9.0.3/libexec/lib/swipl/library/http/http_open.pl:491
ERROR:   [12] http_client:http_get('https://api.openai.com/v1/chat/completions',_7112,[post(...),...|...]) at /usr/local/Cellar/swi-prolog/9.0.3/libexec/lib/swipl/library/http/http_client.pl:141
ERROR:    [9] toplevel_call('<garbage_collected>') at /usr/local/Cellar/swi-prolog/9.0.3/libexec/lib/swipl/boot/toplevel.pl:1173
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
?-
  1. I’ve tried adding proxy in option argument, not working either.
  2. I’ve tried proxychain, failed too

I have no idea what’s wrong.
Thank you very much for help!

With best regards,
Arthur Wang

1 Like

Looks like you should use http_open/3

https://groups.google.com/g/swi-prolog/c/tmScPR12tOI

You do need the option proxy(localhost:10077). Rather than just Data in the http_post/4 call, you need json(Data). I think you do not need Headers = headers([content_type('application/json; charset="utf-8"')]). If it doesn’t work, try

?- debug(http(_)).

to get feedback on what it is trying to do. As we’ve been here several times, here is code that works :slight_smile: It assumes your key in a file key.

:- use_module(library(http/http_client)).
:- use_module(library(http/http_json)).
:- use_module(library(http/json)).


get_key(Key) :-
    setup_call_cleanup(
        open(key, read, In),
        read_line_to_string(In, Key),
        close(In)).

query_gpt(_{query:Query}, Reply) :-
    get_key(Key),
    Url = 'https://api.openai.com/v1/chat/completions',
    Data = _{ model: 'gpt-3.5-turbo',
              temperature:0.7,
              messages:[
                  _{ role: user,
                     content: Query
                   }
              ]
            },
    http_post(Url, json(Data), Reply0,
              [ json(Data),
                authorization(bearer(Key)),
                status_code(Status),
                json_object(dict)
              ]),
    Reply = Reply0.put(status, Status).

Test run:

?- query_gpt(_{query:"Can you write an elevator pitch on what Prolog is?"}, Solution).
Solution =
_{ choices:[ _{ finish_reason:"stop",
		index:0,
		message:_{ content:"Prolog is a logic programming language that enables computers to reason about problems and provide solutions. It is based on a declarative programming paradigm, which means that users can express what they want the program to do rather than how to do it. Prolog is particularly useful for tasks such as natural language processing, expert systems, and AI. It is an efficient and expressive language that allows users to create complex and flexible programs with ease.",
			   role:"assistant"
			 }
	      }
	   ],
   created:1686055220,
   id:"chatcmpl-7OQGyb9gna0sVD6Ri4s7IjSmFO2GM",
   model:"gpt-3.5-turbo-0301",
   object:"chat.completion",
   status:200,
   usage:_{completion_tokens:86,prompt_tokens:20,total_tokens:106}
 }
1 Like

Thank you so much Jan! It works now.