diff options
| author | 2018-05-22 22:12:43 +0200 | |
|---|---|---|
| committer | 2018-05-22 22:12:43 +0200 | |
| commit | f689ce549689b3192ce1f7510804495acfd7869d (patch) | |
| tree | 56ac7af58d1b9a8ea59a943e711e337a10220cdd | |
| parent | Delete test.py (diff) | |
adds webapp and docker-compose for more proof of concept
| -rw-r--r-- | .dockerignore | 15 | ||||
| -rw-r--r-- | Pipfile | 10 | ||||
| -rw-r--r-- | Pipfile.lock | 183 | ||||
| -rw-r--r-- | README.md | 36 | ||||
| -rw-r--r-- | docker-compose.yml | 18 | ||||
| -rw-r--r-- | docker/Dockerfile | 12 | ||||
| -rw-r--r-- | runner/consume.py | 68 | ||||
| -rw-r--r-- | snekbox/config.py (renamed from runner/config.py) | 4 | ||||
| -rw-r--r-- | snekbox/consume.py | 75 | ||||
| -rw-r--r-- | snekbox/publish.py (renamed from runner/publish.py) | 36 | ||||
| -rw-r--r-- | tox.ini | 6 | ||||
| -rw-r--r-- | webapp/rmq.py | 48 | ||||
| -rw-r--r-- | webapp/templates/index.html | 64 | ||||
| -rw-r--r-- | webapp/webapp.py | 39 | 
14 files changed, 511 insertions, 103 deletions
| diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..210f85f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,15 @@ +.venv +scripts +htmlcov +__pycache__ +.vagrant +.pytest_cache +.git +.github +.cache +Vagrantfile +.coverage +.coveragerc +.gitignore +.travis.yml +docker @@ -7,6 +7,11 @@ name = "pypi"  pika = "*"  [dev-packages] +docker = "*" +flask = "*" +flask-sockets = "*" +gevent = "==1.2.2" +gevent-websocket = "*"  [requires]  python_version = "3.6" @@ -14,5 +19,6 @@ python_version = "3.6"  [scripts]  consume = "python consume.py"  publish = "python publish.py" -build = "docker build -t runner:latest -f docker/Dockerfile ." -docker = "docker run --network=host runner" +build = "docker build -t pythondiscord/snekbox:latest -f docker/Dockerfile ." +compose = "docker-compose up" +webapp = "PYTHONPATH=/vagrant/discord-python/snekbox python webapp/webapp.py" diff --git a/Pipfile.lock b/Pipfile.lock index 00a32d2..885f9c1 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@  {      "_meta": {          "hash": { -            "sha256": "7374d59c23f8adb4d87cd3533f6a7e8f95cc7d7e2e1f5bc1c9dcb49a02459bbd" +            "sha256": "0a745b21e4db904bb3575c80d627ab80a3418bcb42e6e5c3695e914b88756114"          },          "pipfile-spec": 6,          "requires": { @@ -25,5 +25,184 @@              "version": "==0.11.2"          }      }, -    "develop": {} +    "develop": { +        "certifi": { +            "hashes": [ +                "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", +                "sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0" +            ], +            "version": "==2018.4.16" +        }, +        "chardet": { +            "hashes": [ +                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", +                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" +            ], +            "version": "==3.0.4" +        }, +        "click": { +            "hashes": [ +                "sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d", +                "sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b" +            ], +            "version": "==6.7" +        }, +        "docker": { +            "hashes": [ +                "sha256:43b45b92bed372161a5d4f3c7137e16b30d93845e99a00bc727938e52850694e", +                "sha256:dc5cc0971a0d36fe94c5ce89bd4adb6c892713500af7b0818708229c3199911a" +            ], +            "index": "pypi", +            "version": "==3.3.0" +        }, +        "docker-pycreds": { +            "hashes": [ +                "sha256:764a7ea2f6484bc5de5bf0c060f08b41a1118cf1acb987626b3ff45f3cc40dac", +                "sha256:e3732a03610a00461a716997670c7010bf1c214a3edc440f7d6a2a3a830ecd9d" +            ], +            "version": "==0.2.3" +        }, +        "flask": { +            "hashes": [ +                "sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48", +                "sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05" +            ], +            "index": "pypi", +            "version": "==1.0.2" +        }, +        "flask-sockets": { +            "hashes": [ +                "sha256:072927da8edca0e81e024f5787e643c87d80b351b714de95d723becb30e0643b", +                "sha256:350a76d55f5889f64afd2ca9b32f262680b7960965f0830365576307d30cfe1e" +            ], +            "index": "pypi", +            "version": "==0.2.1" +        }, +        "gevent": { +            "hashes": [ +                "sha256:0901975628790e8a57fc92bb7062e5b856edea48c8de9caf36cfda14eae07329", +                "sha256:1af93825db5753550fa8ff5ab2f2132e8733170b3f8d38347b34fa4a984cb624", +                "sha256:2ff045a91509c35664c27a849c8cbf742a227f587b7cdbc88301e9c85dcaedff", +                "sha256:33fa6759eabc9176ddbe0d29b66867a82e19a61f06eb7cfabbac35343c0ecf24", +                "sha256:35790f1a3c8e431ada3471b70bb2105050009ea4beb15cbe41b86bc716a7ffa9", +                "sha256:4791c8ae9c57d6f153354736e1ccab1e2baf6c8d9ae5a77a9ac90f41e2966b2d", +                "sha256:4f098002126ebef7f2907188b6c8b09e5193161ce968847d9e6a8bc832b0db9a", +                "sha256:552719cec4721673b8c7d2f9de666e3f7591b9b182f801ecaef1c76e638052aa", +                "sha256:59e9237af027f8db85e5d78a9da2e328ae96f01d67a0d62abcecad3db7876908", +                "sha256:60109741377367eef8ded9283a1bf629621b73acaf3e1e8aac9d1a0f50fa0f05", +                "sha256:6892fabc9051e8c0a171d543b6536859aabeb6d169db79b2f45d64dc2a15808c", +                "sha256:70558dd45c7a1f8046ba45792e489dd0f409bd8a3b7a0635ca9d3055223b3dff", +                "sha256:74bce0c30bb2240e3d5d515ba8cb3eadf840c2bde7109a1979c7a26c9d0f5a6a", +                "sha256:7f93b67b680f4a921f517294048d05f8f6f0ed5962b78d6685a6cf0fcd7d8202", +                "sha256:81cb24e0f7bd9888596364e8d8ed0d65c2547c84884c67bb46d956faeed67396", +                "sha256:833bebdc36bfeeedefc200ca9aee9b8eddd80f56b63ca1e886e18b97b1240edd", +                "sha256:8a710eddb3e9e5f22bdbd458b5f211b94f59409ecd6896f15b9fee2cba266a59", +                "sha256:9b492bb1a043540abb6e54fdb5537531e24962ca49c09f3b47dc4f9c37f6297c", +                "sha256:a0ed8ba787b9c0c1c565c2675d71652e6c1e2d4e91f53530860d0303e867fe85", +                "sha256:a16db4f56699ef07f0249b953ff949aae641e50b2bdc4710f11c0d8d9089b296", +                "sha256:a66cf99f08da65c501826a19e30f5a6e7ba942fdd79baba5ce2d51eebaa13444", +                "sha256:b67a10799923f9fed546ca5f8b93a2819c71a60132d7a97b4a13fbdab66b278a", +                "sha256:b7e0e6400c2f3ce78a9ae1cdd55b53166feedd003d60c033863881227129a4d3", +                "sha256:c35b29de49211014ec66d056fd4f9ba7a04795e2a654697f72879c0cf365d6d4", +                "sha256:c9dd6534c46ed782e2d7236767cd07115cb29ce8670c2fc0794f264de9024fe0", +                "sha256:de13a8e378103af84a8bf6015ad1d2761d46f29b8393e8dd6d9bb7cb51bbb713", +                "sha256:deafd70d04ab62428d4e291e8e2c0fb22f38690e6a9f23a67ee6c304087634da", +                "sha256:df52e06a2754c2d905aad75a7dc06a732c804d9edbc87f06f47c8f483ba98bca", +                "sha256:fce894a64db3911897cdad6c37fbb23dfb18b7bf8b9cb8c00a8ea0a7253651c9" +            ], +            "index": "pypi", +            "version": "==1.2.2" +        }, +        "gevent-websocket": { +            "hashes": [ +                "sha256:17b67d91282f8f4c973eba0551183fc84f56f1c90c8f6b6b30256f31f66f5242", +                "sha256:7eaef32968290c9121f7c35b973e2cc302ffb076d018c9068d2f5ca8b2d85fb0" +            ], +            "index": "pypi", +            "version": "==0.10.1" +        }, +        "greenlet": { +            "hashes": [ +                "sha256:09ef2636ea35782364c830f07127d6c7a70542b178268714a9a9ba16318e7e8b", +                "sha256:0fef83d43bf87a5196c91e73cb9772f945a4caaff91242766c5916d1dd1381e4", +                "sha256:1b7df09c6598f5cfb40f843ade14ed1eb40596e75cd79b6fa2efc750ba01bb01", +                "sha256:1fff21a2da5f9e03ddc5bd99131a6b8edf3d7f9d6bc29ba21784323d17806ed7", +                "sha256:42118bf608e0288e35304b449a2d87e2ba77d1e373e8aa221ccdea073de026fa", +                "sha256:50643fd6d54fd919f9a0a577c5f7b71f5d21f0959ab48767bd4bb73ae0839500", +                "sha256:58798b5d30054bb4f6cf0f712f08e6092df23a718b69000786634a265e8911a9", +                "sha256:5b49b3049697aeae17ef7bf21267e69972d9e04917658b4e788986ea5cc518e8", +                "sha256:75c413551a436b462d5929255b6dc9c0c3c2b25cbeaee5271a56c7fda8ca49c0", +                "sha256:769b740aeebd584cd59232be84fdcaf6270b8adc356596cdea5b2152c82caaac", +                "sha256:ad2383d39f13534f3ca5c48fe1fc0975676846dc39c2cece78c0f1f9891418e0", +                "sha256:b417bb7ff680d43e7bd7a13e2e08956fa6acb11fd432f74c97b7664f8bdb6ec1", +                "sha256:b6ef0cabaf5a6ecb5ac122e689d25ba12433a90c7b067b12e5f28bdb7fb78254", +                "sha256:c2de19c88bdb0366c976cc125dca1002ec1b346989d59524178adfd395e62421", +                "sha256:c7b04a6dc74087b1598de8d713198de4718fa30ec6cbb84959b26426c198e041", +                "sha256:f8f2a0ae8de0b49c7b5b2daca4f150fdd9c1173e854df2cce3b04123244f9f45", +                "sha256:fcfadaf4bf68a27e5dc2f42cbb2f4b4ceea9f05d1d0b8f7787e640bed2801634" +            ], +            "version": "==0.4.13" +        }, +        "idna": { +            "hashes": [ +                "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f", +                "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4" +            ], +            "version": "==2.6" +        }, +        "itsdangerous": { +            "hashes": [ +                "sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519" +            ], +            "version": "==0.24" +        }, +        "jinja2": { +            "hashes": [ +                "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", +                "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4" +            ], +            "version": "==2.10" +        }, +        "markupsafe": { +            "hashes": [ +                "sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665" +            ], +            "version": "==1.0" +        }, +        "requests": { +            "hashes": [ +                "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b", +                "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e" +            ], +            "version": "==2.18.4" +        }, +        "six": { +            "hashes": [ +                "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", +                "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" +            ], +            "version": "==1.11.0" +        }, +        "urllib3": { +            "hashes": [ +                "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b", +                "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f" +            ], +            "version": "==1.22" +        }, +        "websocket-client": { +            "hashes": [ +                "sha256:188b68b14fdb2d8eb1a111f21b9ffd2dbf1dbc4e4c1d28cf2c37cdbf1dd1cae6", +                "sha256:a453dc4dfa6e0db3d8fd7738a308a88effe6240c59f3226eb93e8f020c216149" +            ], +            "version": "==0.47.0" +        }, +        "werkzeug": { +            "hashes": [ +                "sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c", +                "sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b" +            ], +            "version": "==0.14.1" +        } +    }  } @@ -3,20 +3,20 @@ Python sandbox runners for executing code in isolation  # Dependencies -| dep    | version (or greater) | -|--------|----------------------| -| python | 3.6.5                | -| pip    | 10.0.1               | -| pipenv | 2018.05.18           | -| docker | 18.03.1-ce           | - +| dep            | version (or greater) | +|----------------|:---------------------| +| python         | 3.6.5                | +| pip            | 10.0.1               | +| pipenv         | 2018.05.18           | +| docker         | 18.03.1-ce           | +| docker-compose | 1.21.2               |  ## Setup local test  install python packages  ```bash -pipenv sync +pipenv sync --dev  ```  Start a rabbitmq instance and get the container IP @@ -55,3 +55,23 @@ docker logs snekbox -f  #terminal 2  pipenv run python runner/publish.py  ``` + +## Docker compose + +Start both rabbitmq and a consumer with docker-compose + +```bash +docker-compose up +``` + +## Try the webapp + +After getting docker-compose to run the rabbitmq server and the consumer + +try running the webapp in another terminal + +```bash +pipenv run python webapp/webapp.py +``` + +and then open up the page: http://localhost:5000 (or whatever address it's running on) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..11dad71 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3' +services: +  pdrmq: +    hostname: "pdrmq" +    image: rabbitmq:3.7.5-alpine +    networks: +      - sneknet + +  pdsnekbox: +    hostname: "pdsnekbox" +    image: pythondiscord/snekbox:latest +    networks: +      - sneknet +    environment: +      RMQ_HOST: pdrmq + +networks: +  sneknet: diff --git a/docker/Dockerfile b/docker/Dockerfile index cbf1b49..47be8b1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -7,15 +7,15 @@ ENV PIPENV_VENV_IN_PROJECT=1  ENV PIPENV_IGNORE_VIRTUALENVS=1  ENV PIPENV_NOSPIN=1  ENV PIPENV_HIDE_EMOJIS=1 -ENV PYTHONPATH=/runner +ENV PYTHONPATH=/snekbox  RUN pip install pipenv -RUN mkdir -p /runner -COPY Pipfile /runner -COPY Pipfile.lock /runner -COPY runner /runner -WORKDIR /runner +RUN mkdir -p /snekbox +COPY Pipfile /snekbox +COPY Pipfile.lock /snekbox +COPY snekbox /snekbox +WORKDIR /snekbox  RUN pipenv sync diff --git a/runner/consume.py b/runner/consume.py deleted file mode 100644 index 0e4d79a..0000000 --- a/runner/consume.py +++ /dev/null @@ -1,68 +0,0 @@ -import pika -import traceback -import sys -from io import StringIO - -from config import ( -    USERNAME, -    PASSWORD, -    HOST, -    PORT, -    EXCHANGE, -    EXCHANGE_TYPE, -    QUEUE, -    ROUTING_KEY, -) - -def execute(snippet): -    old_stdout = sys.stdout -    redirected_output = sys.stdout = StringIO() -    failed = False -    try: -        exec(snippet) -    except Exception as e: -        failed = e -    finally: -        sys.stdout = old_stdout - -    if failed: -        return failed -    return redirected_output.getvalue() - - -def message_handler(ch, method, properties, body): -    msg = body.decode('utf-8') - -    # Execute code snippets here -    print(f"incoming: {msg}", flush=True) -    result = execute(msg) -    print(result, flush=True) - -    ch.basic_ack(delivery_tag = method.delivery_tag) - -def rabbitmq_consume(): -    credentials = pika.PlainCredentials(USERNAME, PASSWORD) -    connection = pika.BlockingConnection(pika.ConnectionParameters(HOST, PORT, '/', credentials)) - -    channel = connection.channel() -    channel.queue_declare(queue=QUEUE, durable=False) -    channel.basic_qos(prefetch_count=1) -    channel.basic_consume(message_handler, queue=QUEUE) - -    try: -        print(f"""Connecting to -            host: {HOST} -            port: {PORT} -            exchange: {EXCHANGE} -            queue: {QUEUE}""", flush=True) - -        channel.start_consuming() - -    except Exception: -        exc = traceback.format_exc() -        print(exc, flush=True) - -    finally: -        connection.close() - -rabbitmq_consume() diff --git a/runner/config.py b/snekbox/config.py index 75b3c28..d0bd4f6 100644 --- a/runner/config.py +++ b/snekbox/config.py @@ -1,6 +1,8 @@ +import os +  USERNAME      = 'guest'  PASSWORD      = 'guest' -HOST          = '172.17.0.2' +HOST          = os.environ.get('RMQ_HOST', '172.17.0.2')  PORT          = 5672  EXCHANGE      = 'exchange'  EXCHANGE_TYPE = 'direct' diff --git a/snekbox/consume.py b/snekbox/consume.py new file mode 100644 index 0000000..d44a018 --- /dev/null +++ b/snekbox/consume.py @@ -0,0 +1,75 @@ +import traceback +import sys +import time +import pika +import io + +from pika.exceptions import ConnectionClosed + +from config import USERNAME +from config import PASSWORD +from config import HOST +from config import PORT +from config import EXCHANGE +from config import QUEUE + +def execute(snippet): +    old_stdout = sys.stdout +    redirected_output = sys.stdout = io.StringIO() +    failed = False +    try: +        exec(snippet) +    except Exception as e: +        failed = e +    finally: +        sys.stdout = old_stdout + +    if failed: +        return failed +    return redirected_output.getvalue() + + +def message_handler(ch, method, properties, body): +    msg = body.decode('utf-8') + +    # Execute code snippets here +    print(f"incoming: {msg}", flush=True) +    result = execute(msg) +    print(result, flush=True) + +    ch.basic_ack(delivery_tag = method.delivery_tag) + +def rabbitmq_consume(): + +    while True: +        credentials = pika.PlainCredentials(USERNAME, PASSWORD) +        con_params = pika.ConnectionParameters(HOST, PORT, '/', credentials) + +        try: +            connection = pika.BlockingConnection(con_params) + +            try: +                channel = connection.channel() +                channel.queue_declare(queue=QUEUE, durable=False) +                channel.basic_qos(prefetch_count=1) +                channel.basic_consume(message_handler, queue=QUEUE) + +                print(f"""Connected to \nhost:     {HOST}\nport:     {PORT}\nexchange: {EXCHANGE}\nqueue:    {QUEUE}""", flush=True) + +                channel.start_consuming() + +            except: +                exc = traceback.format_exc() +                print(exc, flush=True) + +            finally: +                connection.close() + +        except ConnectionClosed: +            print(f"Connection lost, reconnecting to {HOST}", flush=True) +            pass + +        time.sleep(2) + +if __name__ == '__main__': +    rabbitmq_consume() diff --git a/runner/publish.py b/snekbox/publish.py index fc18d03..0598976 100644 --- a/runner/publish.py +++ b/snekbox/publish.py @@ -1,14 +1,22 @@  import pika -from config import ( -    USERNAME, -    PASSWORD, -    HOST, -    PORT, -    EXCHANGE, -    EXCHANGE_TYPE, -    QUEUE, -    ROUTING_KEY, -) +from config import USERNAME +from config import PASSWORD +from config import HOST +from config import PORT +from config import EXCHANGE +from config import EXCHANGE_TYPE +from config import QUEUE +from config import ROUTING_KEY + +try: +    import docker +    client = docker.from_env() +    containers = client.containers.get('snekbox_pdrmq_1') +    print("Attempting to get rabbitmq host automatically") +    HOST = list(containers.attrs.get('NetworkSettings').get('Networks').values())[0]['IPAddress'] +    print(f"found {HOST}") +except: +    pass  def send(message):      credentials = pika.PlainCredentials(USERNAME, PASSWORD) @@ -28,15 +36,11 @@ def send(message):      )      if result: -        print(f"""Connecting to -            host: {HOST} -            port: {PORT} -            exchange: {EXCHANGE} -            queue: {QUEUE}""", flush=True) +        print(f"""Connecting to\nhost:     {HOST}\nport:     {PORT}\nexchange: {EXCHANGE}\nqueue:    {QUEUE}""", flush=True)          print(f"Sent: '{message}'")      else:          print("not delivered")      connection.close() -send('print "bacon is delicious"') +#send('print("bacon is delicious")') @@ -0,0 +1,6 @@ +[flake8] +max-line-length=120 +application_import_names=snekbox +ignore=P102,B311,W503,E226,S311 +exclude=__pycache__, venv, .venv, tests +import-order-style=pycharm diff --git a/webapp/rmq.py b/webapp/rmq.py new file mode 100644 index 0000000..80d418a --- /dev/null +++ b/webapp/rmq.py @@ -0,0 +1,48 @@ +import os +import pika + +USERNAME      = 'guest' +PASSWORD      = 'guest' +HOST          = os.environ.get('RMQ_HOST', '172.17.0.2') +PORT          = 5672 +EXCHANGE      = 'exchange' +EXCHANGE_TYPE = 'direct' +QUEUE         = 'text' +ROUTING_KEY   = 'bacon' + +try: +    import docker +    client = docker.from_env() +    containers = client.containers.get('snekbox_pdrmq_1') +    print("Attempting to get rabbitmq host automatically") +    HOST = list(containers.attrs.get('NetworkSettings').get('Networks').values())[0]['IPAddress'] +    print(f"found {HOST}") +except: +    pass + +def send(message): +    credentials = pika.PlainCredentials(USERNAME, PASSWORD) +    connection = pika.BlockingConnection(pika.ConnectionParameters(HOST, PORT, '/', credentials)) +    properties = pika.BasicProperties(content_type='text/plain', delivery_mode=1) + +    channel = connection.channel() +    channel.queue_declare(queue=QUEUE, durable=False) +    channel.exchange_declare(exchange=EXCHANGE, exchange_type=EXCHANGE_TYPE) +    channel.queue_bind(exchange=EXCHANGE, queue=QUEUE, routing_key=ROUTING_KEY) + +    result = channel.basic_publish( +                exchange=EXCHANGE, +                routing_key=ROUTING_KEY, +                body=message, +                properties=properties +    ) + +    if result: +        print(f"""Connecting to\nhost:     {HOST}\nport:     {PORT}\nexchange: {EXCHANGE}\nqueue:    {QUEUE}""", flush=True) +        print(f"Sent: '{message}'") +    else: +        print("not delivered") + +    connection.close() + +#send('print("bacon is delicious")') diff --git a/webapp/templates/index.html b/webapp/templates/index.html new file mode 100644 index 0000000..f2213ff --- /dev/null +++ b/webapp/templates/index.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<meta charset="utf-8" /> +<title>WebSocket Test</title> +<script language="javascript" type="text/javascript"> + +var output; + +function init(){ +    output = document.getElementById("output"); +    testWebSocket(); +} + +function testWebSocket(){ +    var here = window.location.host; +    var wsUri = `ws://${here}/ws`; +    websocket = new WebSocket(wsUri); +    websocket.onopen = function(evt) { onOpen(evt) }; +    websocket.onclose = function(evt) { onClose(evt) }; +    websocket.onmessage = function(evt) { onMessage(evt) }; +    websocket.onerror = function(evt) { onError(evt) }; +} + +function onOpen(evt){ +    writeToScreen("CONNECTED"); +} + +function onClose(evt){ +    writeToScreen("DISCONNECTED"); +} + +function onMessage(evt){ +    writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>'); +    websocket.close(); +} + +function onError(evt){ +    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data); +} + +function sendMessage(message){ +    writeToScreen("SENT: " + message); +    websocket.send(message); +} + +function writeToScreen(message){ +    var pre = document.createElement("p"); +    pre.style.wordWrap = "break-word"; +    pre.innerHTML = message; +    output.appendChild(pre); +} + +function sendFromInput(){ +    var msg = document.getElementById("field1").value; +    sendMessage(msg) +} + +window.addEventListener("load", init, false); + +</script> + +<input type="text" id="field1" value="print('fsdf')"><br> +<button onclick="sendFromInput()">Send</button> + +<div id="output"></div> diff --git a/webapp/webapp.py b/webapp/webapp.py new file mode 100644 index 0000000..676fc27 --- /dev/null +++ b/webapp/webapp.py @@ -0,0 +1,39 @@ +import traceback + +from rmq import send as rmq_send +from flask import Flask +from flask import render_template +from flask_sockets import Sockets + +app = Flask(__name__) +sockets = Sockets(app) + [email protected]('/') +def index(): +    return render_template('index.html') + [email protected]('/ws') +def websocket_route(ws): +    try: +        while not ws.closed: +            message = ws.receive() + +            if not message: +                continue +            print(f"received '{message}'") + +            rmq_send(message) + +    except: +        print(traceback.format_exec()) + +    finally: +        if not ws.closed: +            ws.close() + +if __name__ == '__main__': +    #app.run(host='0.0.0.0', port=5000, debug=True) +    from gevent import pywsgi +    from geventwebsocket.handler import WebSocketHandler +    server = pywsgi.WSGIServer(('0.0.0.0', 5000), app, handler_class=WebSocketHandler) +    server.serve_forever() | 
