Изменить:
Как и @MattP, я добавлю это заявление о моем понимании:
Фон
Я полагаю, что вы используете продукт под названием abaqus. Продукт abaqus включает интерпретатор Python, к которому вы можете получить доступ каким-либо образом (возможно, запустив abaqus python foo.py
в командной строке).
У вас также есть отдельная установка Python на той же машине. Вы разрабатываете код, возможно, включая numpy/scipy, для запуска на этой установке python.
Эти две установки разные: у них разные бинарные интерпретаторы, разные библиотеки, разные пути установки и т. д. Но они живут на одном физическом хосте.
Ваша цель состоит в том, чтобы разрешить написанным вами программам на «простом питоне» взаимодействовать с одним или несколькими сценариями, работающими в среде «Abaqus python», чтобы эти сценарии могли выполнять работу внутри системы Abaqus и возвращать результаты.
Решение
Вот решение на основе сокетов. Есть две части, abqlistener.py
и abqclient.py
. Преимущество этого подхода в том, что он использует четко определенный механизм «ожидания работы». Никакого опроса файлов и т.д. И это "жесткий" API. Вы можете подключиться к процессу-слушателю из процесса на той же машине, где работает та же версия Python, или с другой машины, или из другой версии Python, или из Ruby, или C, или Perl, или даже COBOL. Это позволяет вам создать в вашей системе настоящий «воздушный зазор», чтобы вы могли разрабатывать две части с минимальной связью.
Серверная часть abqlistener
. Цель состоит в том, чтобы вы скопировали часть этого кода в свой сценарий Abaqus. Затем процесс abq станет сервером, прослушивающим соединения на определенном номере порта и выполняющим работу в ответ. Отправка ответа или нет. И так далее.
Я не уверен, что вам нужно выполнять настройку для каждого задания. Если да, то это должно быть частью связи. Это просто запускает ABQ, прослушивает порт (навсегда) и обрабатывает запросы. Любая настройка для конкретной работы должна быть частью рабочего процесса. (Возможно, отправьте строку параметров или имя файла конфигурации или что-то еще.)
Клиентская часть abqclient
. Это можно переместить в модуль или просто скопировать/вставить в существующий код программы, отличной от ABQ. По сути, вы открываете соединение с правильной комбинацией хост: порт и разговариваете с сервером. Отправить некоторые данные, получить некоторые данные обратно и т. д.
Этот материал в основном взят из примера кода онлайн. Так что это должно выглядеть очень знакомо, если вы начнете во что-то копаться.
Вот abqlistener.py:
# The below usage example is completely bogus. I don't have abaqus, so
# I'm just running python2.7 abqlistener.py [options]
usage = """
abacus python abqlistener.py [--host 127.0.0.1 | --host mypc.example.com ] \\
[ --port 2525 ]
Sets up a socket listener on the host interface specified (default: all
interfaces), on the given port number (default: 2525). When a connection
is made to the socket, begins processing data.
"""
import argparse
parser = argparse.ArgumentParser(description='Abacus listener',
add_help=True,
usage=usage)
parser.add_argument('-H', '--host', metavar='INTERFACE', default='',
help='Interface IP address or name, or (default: empty string)')
parser.add_argument('-P', '--port', metavar='PORTNUM', type=int, default=2525,
help='port number of listener (default: 2525)')
args = parser.parse_args()
import SocketServer
import json
class AbqRequestHandler(SocketServer.BaseRequestHandler):
"""Request handler for our socket server.
This class is instantiated whenever a new connection is made, and
must override `handle(self)` in order to handle communicating with
the client.
"""
def do_work(self, data):
"Do some work here. Call abaqus, whatever."
print "DO_WORK: Doing work with data!"
print data
return { 'desc': 'low-precision natural constants','pi': 3, 'e': 3 }
def handle(self):
# Allow the client to send a 1kb message (file path?)
self.data = self.request.recv(1024).strip()
print "SERVER: {} wrote:".format(self.client_address[0])
print self.data
result = self.do_work(self.data)
self.response = json.dumps(result)
print "SERVER: response to {}:".format(self.client_address[0])
print self.response
self.request.sendall(self.response)
if __name__ == '__main__':
print args
server = SocketServer.TCPServer((args.host, args.port), AbqRequestHandler)
print "Server starting. Press Ctrl+C to interrupt..."
server.serve_forever()
А вот abqclient.py
:
usage = """
python2.7 abqclient.py [--host HOST] [--port PORT]
Connect to abqlistener on HOST:PORT, send a message, wait for reply.
"""
import argparse
parser = argparse.ArgumentParser(description='Abacus listener',
add_help=True,
usage=usage)
parser.add_argument('-H', '--host', metavar='INTERFACE', default='',
help='Interface IP address or name, or (default: empty string)')
parser.add_argument('-P', '--port', metavar='PORTNUM', type=int, default=2525,
help='port number of listener (default: 2525)')
args = parser.parse_args()
import json
import socket
message = "I get all the best code from stackoverflow!"
print "CLIENT: Creating socket..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "CLIENT: Connecting to {}:{}.".format(args.host, args.port)
s.connect((args.host, args.port))
print "CLIENT: Sending message:", message
s.send(message)
print "CLIENT: Waiting for reply..."
data = s.recv(1024)
print "CLIENT: Got response:"
print json.loads(data)
print "CLIENT: Closing socket..."
s.close()
И вот что они печатают, когда я запускаю их вместе:
$ python2.7 abqlistener.py --port 3434 &
[2] 44088
$ Namespace(host='', port=3434)
Server starting. Press Ctrl+C to interrupt...
$ python2.7 abqclient.py --port 3434
CLIENT: Creating socket...
CLIENT: Connecting to :3434.
CLIENT: Sending message: I get all the best code from stackoverflow!
CLIENT: Waiting for reply...
SERVER: 127.0.0.1 wrote:
I get all the best code from stackoverflow!
DO_WORK: Doing work with data!
I get all the best code from stackoverflow!
SERVER: response to 127.0.0.1:
{"pi": 3, "e": 3, "desc": "low-precision natural constants"}
CLIENT: Got response:
{u'pi': 3, u'e': 3, u'desc': u'low-precision natural constants'}
CLIENT: Closing socket...
Ссылки:
argparse
, SocketServer
, json
, socket
— все это "стандартные" библиотеки Python.
person
aghast
schedule
12.04.2017
python 3.x
, и чтобы он вызывал, например,"abaqus python aq_script.py"
, который считывает и собираетabaqus
данные. А затем еще один сценарий вывода обратно вabaqus
вызывается таким же образом после повторного травления. Это медленно, но если вам нужноscipy
илиtensorflow
и т. д., это все равно будет быстрее, чем реализация в древней реализацииnumpy
abaqus. - person Daniel F   schedule 11.04.2017subprocess.call('abaqus cae script = test.py',shell=True)
. Это выводит сообщение о том, что сервер лицензий abaqus запущен, и открывает программу abaqus с заданным скриптом. Мне нужен способ связи с этим скриптом из моего основного скрипта. Структурировать его наоборот нелогично, как указывал мой предыдущий ответ. - person mooisjken   schedule 12.04.2017numpy
abaqus действительно является одним из преимуществ запуска обеих отдельных программ. Я прав, думая, что ваше решение соответствует моему текущему обходному пути? И как сделать, чтобы Abaqus эффективнее принимал сигнал, вместо того, чтобы без устали проверять изменение в маринованном файле? - person mooisjken   schedule 12.04.2017subprocess.call
. Я понятия не имею, как заставить это работать на практике. - person mooisjken   schedule 12.04.2017"operation:5; parameters:(11, 32.7)"
из вашего основного скрипта вашему воркеру. В Интернете есть множество примеров кода для программирования сокетов. - person Right leg   schedule 12.04.2017