diff --git a/.gitignore b/.gitignore
new file mode 100755
index 0000000..3c43fed
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+virtualenv
+pyapp/queue/data/*
+pyapp/*/__pycache__
+.idea/
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/codeStyles b/.idea/codeStyles
new file mode 100644
index 0000000..72a9bbb
--- /dev/null
+++ b/.idea/codeStyles
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/amétiq.xml b/.idea/copyright/amétiq.xml
new file mode 100644
index 0000000..9af36f1
--- /dev/null
+++ b/.idea/copyright/amétiq.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml
new file mode 100644
index 0000000..e5da8d8
--- /dev/null
+++ b/.idea/dbnavigator.xml
@@ -0,0 +1,408 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dictionaries/kotyczka.xml b/.idea/dictionaries/kotyczka.xml
new file mode 100644
index 0000000..3aff1ff
--- /dev/null
+++ b/.idea/dictionaries/kotyczka.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f51fb84
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Android
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..b5eab17
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..059ee33
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,17 @@
+{
+ "python.testing.pytestArgs": [
+ "pyapp"
+ ],
+ "python.testing.unittestEnabled": false,
+ "python.testing.pytestEnabled": true,
+ "sqltools.connections": [
+ {
+ "previewLimit": 50,
+ "driver": "SQLite",
+ "name": "test-db",
+ "group": "django",
+ "database": "${workspaceFolder:django}/pyapp/db.sqlite3"
+ }
+ ],
+ "sqltools.useNodeRuntime": true
+}
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100755
index 0000000..0d54b78
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,19 @@
+# Dockerfile
+
+# The first instruction is what image we want to base our container on
+# We Use an official Python runtime as a parent image
+FROM python:3.11-bookworm
+
+# Allows docker to cache installed dependencies between builds
+COPY requirements.txt requirements.txt
+RUN pip install --no-cache-dir -r requirements.txt
+
+# Mounts the application code to the image
+COPY ./demo /app
+WORKDIR /app
+
+EXPOSE 8000
+
+# runs the production server
+ENTRYPOINT ["python3", "manage.py"]
+CMD ["runserver", "0.0.0.0:8000"]
\ No newline at end of file
diff --git a/README.MD b/README.MD
new file mode 100755
index 0000000..facb535
--- /dev/null
+++ b/README.MD
@@ -0,0 +1,26 @@
+-- Tutorial of django
+https://duckduckgo.com/?q=django+tutorial&iax=videos&ia=videos&iai=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dsm1mokevMWk
+
+-- Make a root folder named xy
+python3 -m venv virtualenv
+#### Activate the virutal environment
+source virtualenv/bin/activate
+#### Install django
+python3 -m pip install django
+## Start the project
+django-admin startproject pyapp
+## install an app
+python3 manage.py startapp pyapp
+
+python3 manage.py createsuperuser
+python3 manage.py migrate
+
+-- Django calling Rest Services ?
+python3 manage.py runserver
+
+-- Django DB Initialisation
+# creating the model
+python3 manage.py makemigrations
+# creating the table
+python3 manage.py migrate
+
diff --git a/build-docker-image.sh b/build-docker-image.sh
new file mode 100644
index 0000000..ca097b8
--- /dev/null
+++ b/build-docker-image.sh
@@ -0,0 +1 @@
+docker build -f Dockerfile -t docker.kotyczka.ch/django-app:latest
diff --git a/django.iml b/django.iml
new file mode 100644
index 0000000..8021953
--- /dev/null
+++ b/django.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docker-compose-queue.yml b/docker-compose-queue.yml
new file mode 100755
index 0000000..dc9a082
--- /dev/null
+++ b/docker-compose-queue.yml
@@ -0,0 +1,30 @@
+version: '3'
+services:
+ rabbitmq:
+ image: rabbitmq:management
+ container_name: mq
+ restart: unless-stopped
+ environment:
+ - RABBITMQ_DEFAULT_USER=mqadmin
+ - RABBITMQ_DEFAULT_PASS=3Mnj29jKBsFybc
+ # - RABBITMQ_SSL_CERTFILE=/cert_rabbitmq/testca/cacert.pem
+ # - RABBITMQ_SSL_KEYFILE=/cert_rabbitmq/server/cert.pem
+ # - RABBITMQ_SSL_CACERTFILE=/cert_rabbitmq/server/key.pem
+ ports:
+ # The standard AMQP protocol port
+ - '5672:5672'
+ # HTTP management UI
+ - '15672:15672'
+ volumes:
+ - ./demo/pyapp/queue/data/:/var/lib/rabbitmq/
+ - ./demo/pyapp/queue/log/:/var/log/rabbitmq/
+ - ./data:/var/lib/rabbitmq/
+ # - ./certs/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro
+ # - ./certs/root.crt:/etc/ssl/rmq-cacert.pem:ro
+ # - ./certs/server.crt:/etc/ssl/rmq-cert.pem:ro
+ # - ./certs/server.key:/etc/ssl/rmq-key.pem:ro
+ networks:
+ - ametiq
+networks:
+ ametiq:
+ external: true
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100755
index 0000000..2ddc835
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,16 @@
+version: '3'
+services:
+ django:
+ container_name: demo
+ image: docker.kotyczka.ch/django-app:latest
+ build:
+ context: .
+ ports:
+ - "9000:8000"
+ - "7070:8080"
+ networks:
+ - ametiq
+ restart: unless-stopped
+networks:
+ ametiq:
+ external: true
diff --git a/pyapp/db.sqlite3 b/pyapp/db.sqlite3
new file mode 100755
index 0000000..b90f5dc
Binary files /dev/null and b/pyapp/db.sqlite3 differ
diff --git a/pyapp/manage.py b/pyapp/manage.py
new file mode 100755
index 0000000..fe8678d
--- /dev/null
+++ b/pyapp/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE','pyapp.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/pyapp/pyapp/__init__.py b/pyapp/pyapp/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/pyapp/pyapp/__pycache__/__init__.cpython-311.pyc b/pyapp/pyapp/__pycache__/__init__.cpython-311.pyc
new file mode 100755
index 0000000..6b01935
Binary files /dev/null and b/pyapp/pyapp/__pycache__/__init__.cpython-311.pyc differ
diff --git a/pyapp/pyapp/__pycache__/admin.cpython-311.pyc b/pyapp/pyapp/__pycache__/admin.cpython-311.pyc
new file mode 100644
index 0000000..e04bd06
Binary files /dev/null and b/pyapp/pyapp/__pycache__/admin.cpython-311.pyc differ
diff --git a/pyapp/pyapp/__pycache__/apps.cpython-311.pyc b/pyapp/pyapp/__pycache__/apps.cpython-311.pyc
new file mode 100644
index 0000000..31cf470
Binary files /dev/null and b/pyapp/pyapp/__pycache__/apps.cpython-311.pyc differ
diff --git a/pyapp/pyapp/__pycache__/models.cpython-311.pyc b/pyapp/pyapp/__pycache__/models.cpython-311.pyc
new file mode 100644
index 0000000..ecca321
Binary files /dev/null and b/pyapp/pyapp/__pycache__/models.cpython-311.pyc differ
diff --git a/pyapp/pyapp/__pycache__/settings.cpython-311.pyc b/pyapp/pyapp/__pycache__/settings.cpython-311.pyc
new file mode 100644
index 0000000..7be8fcb
Binary files /dev/null and b/pyapp/pyapp/__pycache__/settings.cpython-311.pyc differ
diff --git a/pyapp/pyapp/__pycache__/urls.cpython-311.pyc b/pyapp/pyapp/__pycache__/urls.cpython-311.pyc
new file mode 100644
index 0000000..e58169b
Binary files /dev/null and b/pyapp/pyapp/__pycache__/urls.cpython-311.pyc differ
diff --git a/pyapp/pyapp/__pycache__/wsgi.cpython-311.pyc b/pyapp/pyapp/__pycache__/wsgi.cpython-311.pyc
new file mode 100644
index 0000000..f2b18ed
Binary files /dev/null and b/pyapp/pyapp/__pycache__/wsgi.cpython-311.pyc differ
diff --git a/pyapp/pyapp/admin.py b/pyapp/pyapp/admin.py
new file mode 100755
index 0000000..edba562
--- /dev/null
+++ b/pyapp/pyapp/admin.py
@@ -0,0 +1,5 @@
+from django.contrib import admin
+from pyapp.models import ShoppingItem
+
+# Register your models here.
+admin.site.register(ShoppingItem)
diff --git a/pyapp/pyapp/apps.py b/pyapp/pyapp/apps.py
new file mode 100755
index 0000000..7731d55
--- /dev/null
+++ b/pyapp/pyapp/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+class PyappConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'pyapp'
diff --git a/pyapp/pyapp/asgi.py b/pyapp/pyapp/asgi.py
new file mode 100755
index 0000000..b767eab
--- /dev/null
+++ b/pyapp/pyapp/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for pyapp project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pyapp.settings')
+
+application = get_asgi_application()
diff --git a/pyapp/pyapp/models.py b/pyapp/pyapp/models.py
new file mode 100755
index 0000000..2a6da03
--- /dev/null
+++ b/pyapp/pyapp/models.py
@@ -0,0 +1,18 @@
+from django.db import models
+from datetime import date
+
+
+class ShoppingItem(models.Model):
+ created_at = models.DateField(default=date.today)
+ name = models.CharField(max_length=120)
+ done = models.BooleanField(default=False)
+ price = models.DecimalField(max_digits=10, decimal_places=2, default = 0.0)
+ quantity = models.PositiveIntegerField()
+
+ def __str__(self):
+ return str(self.id) + ' - ' + self.name
+
+class Product(models.Model):
+ title = models.CharField(max_length=120)
+ content= models.TextField(blank=True, null=True)
+ price = models.DecimalField(max_digits=15,decimal_places=2,default=99.99)
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/__pycache__/config.cpython-311.pyc b/pyapp/pyapp/queue/__pycache__/config.cpython-311.pyc
new file mode 100755
index 0000000..c0baa2b
Binary files /dev/null and b/pyapp/pyapp/queue/__pycache__/config.cpython-311.pyc differ
diff --git a/pyapp/pyapp/queue/ampq_client.py b/pyapp/pyapp/queue/ampq_client.py
new file mode 100755
index 0000000..3d6258a
--- /dev/null
+++ b/pyapp/pyapp/queue/ampq_client.py
@@ -0,0 +1,45 @@
+import optparse
+from proton import Message
+from proton.handlers import MessagingHandler
+from proton.reactor import Container
+
+
+class Client(MessagingHandler):
+ def __init__(self, url, requests):
+ super(Client, self).__init__()
+ self.url = url
+ self.requests = requests
+
+ def on_start(self, event):
+ self.sender = event.container.create_sender(self.url)
+ self.receiver = event.container.create_receiver(self.sender.connection, None, dynamic=True)
+
+ def next_request(self):
+ if self.receiver.remote_source.address:
+ req = Message(reply_to=self.receiver.remote_source.address, body=self.requests[0])
+ self.sender.send(req)
+
+ def on_link_opened(self, event):
+ if event.receiver == self.receiver:
+ self.next_request()
+
+ def on_message(self, event):
+ print("%s => %s" % (self.requests.pop(0), event.message.body))
+ if self.requests:
+ self.next_request()
+ else:
+ event.connection.close()
+
+
+REQUESTS = ["Twas brillig, and the slithy toves",
+ "Did gire and gymble in the wabe.",
+ "All mimsy were the borogroves,",
+ "And the mome raths outgrabe."]
+
+parser = optparse.OptionParser(usage="usage: %prog [options]",
+ description="Send requests to the supplied address and print responses.")
+parser.add_option("-a", "--address", default="localhost:5672/examples",
+ help="address to which messages are sent (default %default)")
+opts, args = parser.parse_args()
+
+Container(Client(opts.address, args or REQUESTS)).run()
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/ampq_receiver.py b/pyapp/pyapp/queue/ampq_receiver.py
new file mode 100755
index 0000000..f8fe8a9
--- /dev/null
+++ b/pyapp/pyapp/queue/ampq_receiver.py
@@ -0,0 +1,29 @@
+import optparse
+import time
+import os
+import sys
+from proton import Message
+from proton.utils import BlockingConnection
+from proton.handlers import IncomingMessageHandler
+
+broker = '5672' ##os.getenv('AMQP_BROKER_HOST_PORT')
+queue = 'proton' ##os.getenv('AMQP_ADDRESS')
+user_arg = 'smx' ##os.getenv('AMQP_USER')
+userpw_arg = 'smx' ##os.getenv('AMQP_USER_PASSWORD')
+
+conn = BlockingConnection(broker, user=user_arg, password=userpw_arg)
+receiver = conn.create_receiver(queue)
+
+count = 0
+try:
+ while True:
+ msg = receiver.receive(timeout=None)
+ count += 1
+ print("got message, processing for two seconds...")
+ sys.stdout.flush()
+ time.sleep(2)
+ receiver.accept()
+finally:
+ conn.close()
+
+print ("All done. Processed ", count, " messages.")
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/ampq_sender.py b/pyapp/pyapp/queue/ampq_sender.py
new file mode 100755
index 0000000..ef7984c
--- /dev/null
+++ b/pyapp/pyapp/queue/ampq_sender.py
@@ -0,0 +1,52 @@
+from __future__ import print_function, unicode_literals
+import optparse
+from proton import Message
+from proton.handlers import MessagingHandler
+from proton.reactor import Container
+from proton.utils import BlockingConnection
+from django.conf import settings
+
+broker = '5672' ##os.getenv('AMQP_BROKER_HOST_PORT')
+queue = 'proton' ##os.getenv('AMQP_ADDRESS')
+user_arg = 'smx' ##os.getenv('AMQP_USER')
+userpw_arg = 'smx' ##os.getenv('AMQP_USER_PASSWORD')
+
+class Send(MessagingHandler):
+ def __init__(self, url, messages):
+ super(Send, self).__init__()
+ self.url = url
+ self.sent = 0
+ self.confirmed = 0
+ self.total = messages
+
+ def on_start(self, event):
+ event.container.create_sender(self.url)
+
+ def on_sendable(self, event):
+ while event.sender.credit and self.sent < self.total:
+ msg = Message(id=(self.sent+1), body={'sequence':(self.sent+1)})
+ event.sender.send(msg)
+ self.sent += 1
+
+ def on_accepted(self, event):
+ self.confirmed += 1
+ if self.confirmed == self.total:
+ print("all messages confirmed")
+ event.connection.close()
+
+ def on_disconnected(self, event):
+ self.sent = self.confirmed
+
+conn = BlockingConnection(broker, user=user_arg, password=userpw_arg)
+
+parser = optparse.OptionParser(usage="usage: %prog [options]",
+ description="Send messages to the supplied address.")
+parser.add_option("-a", "--address", default="0.0.0.0:16161/examples",
+ help="address to which messages are sent (default %default)")
+parser.add_option("-m", "--messages", type="int", default=100,
+ help="number of messages to send (default %default)")
+opts, args = parser.parse_args()
+
+try:
+ Container(Send(opts.address, opts.messages)).run()
+except KeyboardInterrupt: pass
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/ampq_server.py b/pyapp/pyapp/queue/ampq_server.py
new file mode 100755
index 0000000..c4534f9
--- /dev/null
+++ b/pyapp/pyapp/queue/ampq_server.py
@@ -0,0 +1,51 @@
+import optparse
+import sys
+from proton import Condition, Message, Url
+from proton.handlers import MessagingHandler
+from proton.reactor import Container
+
+exit_status = 0
+
+
+class Server(MessagingHandler):
+ def __init__(self, url, address):
+ super(Server, self).__init__()
+ self.url = url
+ self.address = address
+
+ def on_start(self, event):
+ print("Listening on", self.url)
+ self.container = event.container
+ self.conn = event.container.connect(self.url, desired_capabilities="ANONYMOUS-RELAY")
+
+ def on_connection_opened(self, event):
+ if event.connection.remote_offered_capabilities and 'ANONYMOUS-RELAY' in event.connection.remote_offered_capabilities:
+ self.receiver = event.container.create_receiver(self.conn, self.address)
+ self.server = self.container.create_sender(self.conn, None)
+ else:
+ global exit_status
+ print("Server needs a broker which supports ANONYMOUS-RELAY", file=sys.stderr)
+ exit_status = 1
+ c = event.connection
+ c.condition = Condition('amqp:not-implemented', description="ANONYMOUS-RELAY required")
+ c.close()
+
+ def on_message(self, event):
+ print("Received", event.message)
+ self.server.send(Message(address=event.message.reply_to, body=event.message.body.upper(),
+ correlation_id=event.message.correlation_id))
+
+
+parser = optparse.OptionParser(usage="usage: %prog [options]")
+parser.add_option("-a", "--address", default="localhost:5672/examples",
+ help="address from which messages are received (default %default)")
+opts, args = parser.parse_args()
+
+url = Url(opts.address)
+
+try:
+ Container(Server(url, url.path)).run()
+except KeyboardInterrupt:
+ pass
+
+sys.exit(exit_status)
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/client_http.py b/pyapp/pyapp/queue/client_http.py
new file mode 100755
index 0000000..6ca4b4c
--- /dev/null
+++ b/pyapp/pyapp/queue/client_http.py
@@ -0,0 +1,96 @@
+import tornado.ioloop
+import tornado.web
+from tornado.gen import coroutine
+from tornado.concurrent import Future
+from proton import Message
+from proton.handlers import MessagingHandler
+from proton_tornado import Container
+
+
+class Client(MessagingHandler):
+ def __init__(self, host, address):
+ super(Client, self).__init__()
+ self.host = host
+ self.address = address
+ self.sent = []
+ self.pending = []
+ self.reply_address = None
+ self.sender = None
+ self.receiver = None
+
+ def on_start(self, event):
+ conn = event.container.connect(self.host)
+ self.sender = event.container.create_sender(conn, self.address)
+ self.receiver = event.container.create_receiver(conn, None, dynamic=True)
+
+ def on_link_opened(self, event):
+ if event.receiver == self.receiver:
+ self.reply_address = event.link.remote_source.address
+ self.do_request()
+
+ def on_sendable(self, event):
+ self.do_request()
+
+ def on_message(self, event):
+ if self.sent:
+ request, future = self.sent.pop(0)
+ print("%s => %s" % (request, event.message.body))
+ future.set_result(event.message.body)
+ self.do_request()
+
+ def do_request(self):
+ if self.pending and self.reply_address and self.sender.credit:
+ request, future = self.pending.pop(0)
+ self.sent.append((request, future))
+ req = Message(reply_to=self.reply_address, body=request)
+ self.sender.send(req)
+
+ def request(self, body):
+ future = Future()
+ self.pending.append((body, future))
+ self.do_request()
+ self.container.touch()
+ return future
+
+
+class ExampleHandler(tornado.web.RequestHandler):
+ def initialize(self, client):
+ self.client = client
+
+ def get(self):
+ self._write_open()
+ self._write_form()
+ self._write_close()
+
+ @coroutine
+ def post(self):
+ response = yield self.client.request(self.get_body_argument("message"))
+ self.set_header("Content-Type", "text/html")
+ self._write_open()
+ self._write_form()
+ self.write("Response: " + response)
+ self._write_close()
+
+ def _write_open(self):
+ self.write('
')
+
+ def _write_close(self):
+ self.write('')
+
+ def _write_form(self):
+ self.write('')
+
+
+loop = tornado.ioloop.IOLoop.instance()
+client = Client("localhost:5672", "examples")
+client.container = Container(client, loop=loop)
+client.container.initialise()
+app = tornado.web.Application([tornado.web.url(r"/client", ExampleHandler, dict(client=client))])
+app.listen(8888)
+try:
+ loop.start()
+except KeyboardInterrupt:
+ loop.stop()
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/config.py b/pyapp/pyapp/queue/config.py
new file mode 100755
index 0000000..8bc7a07
--- /dev/null
+++ b/pyapp/pyapp/queue/config.py
@@ -0,0 +1,5 @@
+username = 'smx'
+password = 'smx'
+
+#username = 'mqadmin'
+#password = '3Mnj29jKBsFybc'
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/connect.json b/pyapp/pyapp/queue/connect.json
new file mode 100755
index 0000000..e69de29
diff --git a/pyapp/pyapp/queue/db_receive.py b/pyapp/pyapp/queue/db_receive.py
new file mode 100755
index 0000000..88d44fc
--- /dev/null
+++ b/pyapp/pyapp/queue/db_receive.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import optparse
+from proton.handlers import MessagingHandler
+from proton.reactor import ApplicationEvent, Container, EventInjector
+from db_common import Db
+
+
+class Recv(MessagingHandler):
+ def __init__(self, url, count):
+ super(Recv, self).__init__(auto_accept=False)
+ self.url = url
+ self.delay = 0
+ self.last_id = None
+ self.expected = count
+ self.received = 0
+ self.accepted = 0
+ self.db = Db("dst_db", EventInjector())
+
+ def on_start(self, event):
+ event.container.selectable(self.db.injector)
+ e = ApplicationEvent("id_loaded")
+ e.container = event.container
+ self.db.get_id(e)
+
+ def on_id_loaded(self, event):
+ self.last_id = event.id
+ event.container.create_receiver(self.url)
+
+ def on_record_inserted(self, event):
+ self.accept(event.delivery)
+ self.accepted += 1
+ if self.accepted == self.expected:
+ event.connection.close()
+ self.db.close()
+
+ def on_message(self, event):
+ id = int(event.message.id)
+ if (not self.last_id) or id > self.last_id:
+ if self.expected == 0 or self.received < self.expected:
+ self.received += 1
+ self.last_id = id
+ self.db.insert(id, event.message.body, ApplicationEvent("record_inserted", delivery=event.delivery))
+ print("inserted message %s" % id)
+ else:
+ self.release(event.delivery)
+ else:
+ self.accept(event.delivery)
+
+
+parser = optparse.OptionParser(usage="usage: %prog [options]")
+parser.add_option("-a", "--address", default="localhost:5672/examples",
+ help="address from which messages are received (default %default)")
+parser.add_option("-m", "--messages", type="int", default=0,
+ help="number of messages to receive; 0 receives indefinitely (default %default)")
+opts, args = parser.parse_args()
+
+try:
+ Container(Recv(opts.address, opts.messages)).run()
+except KeyboardInterrupt:
+ pass
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/db_send.py b/pyapp/pyapp/queue/db_send.py
new file mode 100755
index 0000000..71e97c5
--- /dev/null
+++ b/pyapp/pyapp/queue/db_send.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python3
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import optparse
+import queue
+
+
+from proton import Message
+from proton.handlers import MessagingHandler
+from proton.reactor import ApplicationEvent, Container, EventInjector
+from db_common import Db
+
+
+class Send(MessagingHandler):
+ def __init__(self, url, count):
+ super(Send, self).__init__()
+ self.url = url
+ self.delay = 0
+ self.sent = 0
+ self.confirmed = 0
+ self.load_count = 0
+ self.records = queue.Queue(maxsize=50)
+ self.target = count
+ self.db = Db("src_db", EventInjector())
+
+ def keep_sending(self):
+ return self.target == 0 or self.sent < self.target
+
+ def on_start(self, event):
+ self.container = event.container
+ self.container.selectable(self.db.injector)
+ self.sender = self.container.create_sender(self.url)
+
+ def on_records_loaded(self, event):
+ if self.records.empty():
+ if event.subject == self.load_count:
+ print("Exhausted available data, waiting to recheck...")
+ # check for new data after 5 seconds
+ self.container.schedule(5, self)
+ else:
+ self.send()
+
+ def request_records(self):
+ if not self.records.full():
+ print("loading records...")
+ self.load_count += 1
+ self.db.load(self.records, event=ApplicationEvent(
+ "records_loaded", link=self.sender, subject=self.load_count))
+
+ def on_sendable(self, event):
+ self.send()
+
+ def send(self):
+ while self.sender.credit and not self.records.empty():
+ if not self.keep_sending():
+ return
+ record = self.records.get(False)
+ id = record['id']
+ self.sender.send(Message(id=id, durable=True, body=record['description']), tag=str(id))
+ self.sent += 1
+ print("sent message %s" % id)
+ self.request_records()
+
+ def on_settled(self, event):
+ id = int(event.delivery.tag)
+ self.db.delete(id)
+ print("settled message %s" % id)
+ self.confirmed += 1
+ if self.confirmed == self.target:
+ event.connection.close()
+ self.db.close()
+
+ def on_disconnected(self, event):
+ self.db.reset()
+ self.sent = self.confirmed
+
+ def on_timer_task(self, event):
+ print("Rechecking for data...")
+ self.request_records()
+
+
+parser = optparse.OptionParser(usage="usage: %prog [options]",
+ description="Send messages to the supplied address.")
+parser.add_option("-a", "--address", default="localhost:5672/examples",
+ help="address to which messages are sent (default %default)")
+parser.add_option("-m", "--messages", type="int", default=0,
+ help="number of messages to send; 0 sends indefinitely (default %default)")
+opts, args = parser.parse_args()
+
+try:
+ Container(Send(opts.address, opts.messages)).run()
+except KeyboardInterrupt:
+ pass
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/queue_consumer.py b/pyapp/pyapp/queue/queue_consumer.py
new file mode 100755
index 0000000..dbd5f62
--- /dev/null
+++ b/pyapp/pyapp/queue/queue_consumer.py
@@ -0,0 +1,22 @@
+import pika, time, config
+#declaring the credentials needed for connection like host, port, username, password, exchange etc
+credentials= pika.PlainCredentials(username= config.username, password= config.password)
+connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=5672, credentials= credentials))
+channel = connection.channel()
+channel.exchange_declare('pydev', durable=True, exchange_type='topic')
+#defining callback functions responding to corresponding queue callbacks
+def callbackFunctionForQueueA(ch,method,properties,body):
+ print('Got a message from Queue A: ', body)
+def callbackFunctionForQueueB(ch,method,properties,body):
+ print('Got a message from Queue B: ', body)
+def callbackFunctionForQueueC(ch,method,properties,body):
+ print('Got a message from Queue C: ', body)
+#Attaching consumer callback functions to respective queues that we wrote above
+channel.basic_consume(queue='A', on_message_callback=callbackFunctionForQueueA, auto_ack=True)
+channel.basic_consume(queue='B', on_message_callback=callbackFunctionForQueueB, auto_ack=True)
+channel.basic_consume(queue='C', on_message_callback=callbackFunctionForQueueC, auto_ack=True)
+#this will be command for starting the consumer session
+channel.start_consuming()
+##time.sleep(2)
+##channel.stop_consuming()
+channel.close()
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/queue_producer.py b/pyapp/pyapp/queue/queue_producer.py
new file mode 100755
index 0000000..0ead51c
--- /dev/null
+++ b/pyapp/pyapp/queue/queue_producer.py
@@ -0,0 +1,23 @@
+import pika
+##import amqp
+import config
+#declaring the credentials needed for connection like host, port, username, password, exchange etc
+credentials= pika.PlainCredentials(username= config.username, password= config.password)
+connection= pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=61616, credentials= credentials))
+channel = connection.channel()
+channel.exchange_declare(exchange='pydev', durable=True, exchange_type='topic')
+channel.queue_declare(queue= 'A')
+channel.queue_bind(exchange='pydev', queue='A', routing_key='A')
+channel.queue_declare(queue= 'B')
+channel.queue_bind(exchange='pydev', queue='B', routing_key='B')
+channel.queue_declare(queue= 'C')
+channel.queue_bind(exchange='pydev', queue='C', routing_key='C')
+#messaging to queue named C
+message_spec= 'Only this channel can see this message'
+message_all= 'Welcome to python queue handling...'
+channel.basic_publish(exchange='pydev', routing_key='A', body= message_all)
+channel.basic_publish(exchange='pydev', routing_key='B', body= message_all)
+channel.basic_publish(exchange='pydev', routing_key='C', body= message_all)
+channel.basic_publish(exchange='pydev', routing_key='B', body= message_spec)
+channel.basic_publish(exchange='pydev', routing_key='C', body= message_spec)
+channel.close()
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/send.py b/pyapp/pyapp/queue/send.py
new file mode 100755
index 0000000..ecef4d7
--- /dev/null
+++ b/pyapp/pyapp/queue/send.py
@@ -0,0 +1,6 @@
+import stomp
+
+conn = stomp.Connection()
+conn.connect('smx', 'smx', wait=True)
+conn.send(content_type='application/raw',body=' Hello Stomp ', destination='/queue/test')
+conn.disconnect()
\ No newline at end of file
diff --git a/pyapp/pyapp/queue/test.py b/pyapp/pyapp/queue/test.py
new file mode 100755
index 0000000..2a7d68c
--- /dev/null
+++ b/pyapp/pyapp/queue/test.py
@@ -0,0 +1,39 @@
+import stomp
+from stomp.listener import TestListener
+import testutils
+
+
+##@pytest.fixture()
+def conn():
+ conn = stomp.Connection11(get_artemis_host())
+ conn.set_listener("testlistener", TestListener("123", print_to_log=True))
+ conn.connect(get_artemis_user(), get_artemis_password(), wait=True)
+ yield conn
+ conn.disconnect(receipt=None)
+
+
+##@pytest.fixture()
+def conn2():
+ conn2 = stomp.Connection11(get_artemis_host())
+ conn2.set_listener("testlistener", TestListener("456", print_to_log=True))
+ conn2.connect(get_artemis_user(), get_artemis_password(), wait=True, headers={'consumerWindowSize': 0})
+ yield conn2
+ conn2.disconnect(receipt=None)
+
+
+class TestArtemis(object):
+
+ def test_send_to_artemis(self, conn):
+ conn.subscribe(destination="/queue/test", id=1, ack="auto")
+
+ conn.send(body="this is a test", destination="/queue/test", receipt="123")
+
+ validate_send(conn)
+
+ def test_prefetchsize(self, conn2):
+ conn2.subscribe(destination="/queue/test2", id=2, ack="auto", headers={'consumerWindowSize': 0})
+
+ conn2.send(body="testing sending a message after subscribing with prefetch",
+ destination="/queue/test2", receipt="456")
+
+ validate_send(conn2)
\ No newline at end of file
diff --git a/pyapp/pyapp/serializers.py b/pyapp/pyapp/serializers.py
new file mode 100755
index 0000000..8577bf9
--- /dev/null
+++ b/pyapp/pyapp/serializers.py
@@ -0,0 +1,7 @@
+from rest_framework import serializers
+from pyapp.models import ShoppingItem
+
+class ShoppingItemSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = ShoppingItem
+ fields = '__all__'
\ No newline at end of file
diff --git a/pyapp/pyapp/settings.py b/pyapp/pyapp/settings.py
new file mode 100755
index 0000000..5d621c2
--- /dev/null
+++ b/pyapp/pyapp/settings.py
@@ -0,0 +1,148 @@
+"""
+Django settings for pyapp project.
+
+Generated by 'django-admin startproject' using Django 5.0.1.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/5.0/ref/settings/
+"""
+
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'django-insecure-z$@7i%n)hn)=5-c8!%)y1-493jkohy8=s-xq8=iu(aud)xx0_+'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'rest_framework',
+ 'pyapp_api',
+ 'pyapp',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+CORS_ORIGIN_ALLOW_ALL = False
+CORS_ORIGIN_WHITELIST = (
+ 'http://localhost:8000',
+)
+
+REST_FRAMEWORK = {
+ 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
+ 'PAGE_SIZE': 10
+}
+
+ROOT_URLCONF = 'pyapp.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'pyapp.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
+
+# DATABASES = {
+# 'default': {
+# 'ENGINE': 'django.db.backends.sqlite3',
+# 'NAME': BASE_DIR / 'db.sqlite3',
+# }
+# }
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.postgresql_psycopg2',
+ 'NAME': 'pyapp',
+ 'USER': 'pyapp',
+ 'PASSWORD': 'kotyczka',
+ 'HOST': '192.168.0.9',
+ 'PORT': '5434',
+ }}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/5.0/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/5.0/howto/static-files/
+
+STATIC_URL = 'static/'
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+
diff --git a/pyapp/pyapp/templates/pyapp.html b/pyapp/pyapp/templates/pyapp.html
new file mode 100755
index 0000000..d9cae59
--- /dev/null
+++ b/pyapp/pyapp/templates/pyapp.html
@@ -0,0 +1,60 @@
+
+
+ PyApp Inventory
+
+
+
+
+
+
+
+ PyApp Item List Inventory
+
+ {% for item in all_items %}
+
+ {{item.name}}
+
+ {% endfor %}
+
+
+
+
diff --git a/pyapp/pyapp/tests.py b/pyapp/pyapp/tests.py
new file mode 100755
index 0000000..7ce503c
--- /dev/null
+++ b/pyapp/pyapp/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/pyapp/pyapp/urls.py b/pyapp/pyapp/urls.py
new file mode 100755
index 0000000..d0b1e27
--- /dev/null
+++ b/pyapp/pyapp/urls.py
@@ -0,0 +1,28 @@
+"""
+URL configuration for pyapp project.
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/5.0/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from pyapp import views
+from django.contrib import admin
+from django.urls import path,include
+from pyapp.views import pyapp_home
+from pyapp_api import urls as pyapp_urls
+
+urlpatterns = [
+path("", views.index, name= "index"),
+path('admin/', admin.site.urls),
+path("pyapp/", views.pyapp_home, name= "Item List App"),
+path('api/', include(pyapp_urls)),
+]
\ No newline at end of file
diff --git a/pyapp/pyapp/views.py b/pyapp/pyapp/views.py
new file mode 100755
index 0000000..1a16bc2
--- /dev/null
+++ b/pyapp/pyapp/views.py
@@ -0,0 +1,35 @@
+from django.shortcuts import render
+from django.http import HttpResponse, JsonResponse
+from pyapp.models import ShoppingItem
+from rest_framework import viewsets
+from pyapp.serializers import ShoppingItemSerializer
+
+class ShoppingItemViewSet(viewsets.ModelViewSet):
+ queryset = ShoppingItem.objects.all()
+ serializer_class = ShoppingItemSerializer
+
+def index(response):
+ return HttpResponse("Welcome to the Pyapp Item List")
+
+def pyapp_home(request):
+ if request.method == 'POST':
+ print('Received Data',request.POST['itemName'])
+ ShoppingItem.objects.create(name= request.POST['itemName'])
+ all_items = ShoppingItem.objects.all()
+ return render(request,'pyapp.html',{'all_items': all_items})
+
+def api_home(request,endpoint, params={"message": "Your JSON Repsonse"}):
+ body = request.body
+ data = {}
+ try:
+ data = json.loads(body)
+ except:
+ pass
+ print(request.GET)
+ print(data)
+ data['params'] = dict(request.GET)
+ data['headers'] = dict(request.headers)
+ data['content_type'] = request.content_type
+ return JsonResponse(data)
+
+ ##return JsonResponse()
diff --git a/pyapp/pyapp/window/address.py b/pyapp/pyapp/window/address.py
new file mode 100755
index 0000000..e8b39da
--- /dev/null
+++ b/pyapp/pyapp/window/address.py
@@ -0,0 +1,66 @@
+import tkinter as tk
+
+# Create a new window with the title "Address Entry Form"
+window = tk.Tk()
+window.title("Address Entry Form")
+
+# Create a new frame `frm_form` to contain the Label
+# and Entry widgets for entering address information
+frm_form = tk.Frame(relief=tk.SUNKEN, borderwidth=3)
+# Pack the frame into the window
+frm_form.pack()
+
+# List of field labels
+labels = [
+ "First Name:",
+ "Last Name:",
+ "Address Line 1:",
+ "Address Line 2:",
+ "City:",
+ "State/Province:",
+ "Postal Code:",
+ "Country:",
+]
+
+# Loop over the list of field labels
+for idx, text in enumerate(labels):
+ # Create a Label widget with the text from the labels list
+ label = tk.Label(master=frm_form, text=text)
+ # Create an Entry widget
+ entry = tk.Entry(master=frm_form, width=50)
+ # Use the grid geometry manager to place the Label and
+ # Entry widgets in the row whose index is idx
+ label.grid(row=idx, column=0, sticky="e")
+ entry.grid(row=idx, column=1)
+
+# Create a new frame `frm_buttons` to contain the
+# Submit and Clear buttons. This frame fills the
+# whole window in the horizontal direction and has
+# 5 pixels of horizontal and vertical padding.
+frm_buttons = tk.Frame()
+frm_buttons.pack(fill=tk.X, ipadx=5, ipady=5)
+
+# Create an event handler
+def handle_keypress(event):
+ """Print the character associated to the key pressed"""
+ print(event.char)
+
+# Bind keypress event to handle_keypress()
+window.bind("", handle_keypress)
+
+def handle_click(event):
+ print("Adress was submitted")
+
+# Create the "Submit" button and pack it to the
+# right side of `frm_buttons`
+btn_submit = tk.Button(master=frm_buttons, text="Submit")
+btn_submit.pack(side=tk.RIGHT, padx=10, ipadx=10)
+btn_submit.bind("", handle_click)
+
+# Create the "Clear" button and pack it to the
+# right side of `frm_buttons`
+btn_clear = tk.Button(master=frm_buttons, text="Clear")
+btn_clear.pack(side=tk.RIGHT, ipadx=10)
+
+# Start the application
+window.mainloop()
\ No newline at end of file
diff --git a/pyapp/pyapp/window/basic.py b/pyapp/pyapp/window/basic.py
new file mode 100755
index 0000000..799a723
--- /dev/null
+++ b/pyapp/pyapp/window/basic.py
@@ -0,0 +1,47 @@
+import tkinter as tk
+
+window = tk.Tk()
+label = tk.Label(
+ text="Python rocks!",
+ foreground="white", # Set the text color to white
+ background="black" # Set the background color to black
+)
+
+border_effects = {
+ "flat": tk.FLAT,
+ "sunken": tk.SUNKEN,
+ "raised": tk.RAISED,
+ "groove": tk.GROOVE,
+ "ridge": tk.RIDGE,
+}
+for relief_name, relief in border_effects.items():
+ frame = tk.Frame(master=window, relief=relief, borderwidth=5)
+ frame.pack(side=tk.LEFT)
+ label = tk.Label(master=frame, text=relief_name)
+ label.pack()
+
+label.pack()
+entry = tk.Entry()
+entry.pack()
+
+name = entry.get()
+
+frame_a = tk.Frame()
+
+
+label_a = tk.Label(master=frame_a, text="Personalliste")
+label_a.pack()
+
+frame_a.pack()
+
+text_box = tk.Text()
+text_box.pack()
+
+frame_b = tk.Frame()
+label_b = tk.Label(master=frame_b, text="I'm in Frame B")
+label_b.pack()
+frame_b.pack()
+
+
+window.mainloop()
+print(name)
\ No newline at end of file
diff --git a/pyapp/pyapp/window/config.py b/pyapp/pyapp/window/config.py
new file mode 100755
index 0000000..8bc7a07
--- /dev/null
+++ b/pyapp/pyapp/window/config.py
@@ -0,0 +1,5 @@
+username = 'smx'
+password = 'smx'
+
+#username = 'mqadmin'
+#password = '3Mnj29jKBsFybc'
\ No newline at end of file
diff --git a/pyapp/pyapp/window/dice.py b/pyapp/pyapp/window/dice.py
new file mode 100755
index 0000000..3a67e1c
--- /dev/null
+++ b/pyapp/pyapp/window/dice.py
@@ -0,0 +1,17 @@
+import random
+import tkinter as tk
+
+def roll():
+ lbl_result["text"] = str(random.randint(1, 6))
+
+window = tk.Tk()
+window.columnconfigure(0, minsize=150)
+window.rowconfigure([0, 1], minsize=50)
+
+btn_roll = tk.Button(text="Roll", command=roll)
+lbl_result = tk.Label()
+
+btn_roll.grid(row=0, column=0, sticky="nsew")
+lbl_result.grid(row=1, column=0)
+
+window.mainloop()
\ No newline at end of file
diff --git a/pyapp/pyapp/window/edit.py b/pyapp/pyapp/window/edit.py
new file mode 100755
index 0000000..6fc73ef
--- /dev/null
+++ b/pyapp/pyapp/window/edit.py
@@ -0,0 +1,94 @@
+import tkinter as tk
+import config as conf
+import pika
+
+from tkinter.filedialog import askopenfilename, asksaveasfilename
+
+def send_queue_message():
+ exchange_name = 'simple-editor'
+ message_all = 'Sent from RabbitMQ'
+
+ print(message_all)
+ credentials= pika.PlainCredentials(username= conf.username, password= conf.password)
+ connection= pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=5672, credentials= credentials))
+ channel= connection.channel()
+ channel.exchange_declare(exchange = exchange_name, durable = True, exchange_type = 'topic')
+ channel.queue_declare(queue = 'AllInfo')
+ txt = txt_edit.get("1.0", tk.END)
+ channel.queue_bind(exchange = exchange_name, queue = 'AllInfo', routing_key = 'new')
+ channel.basic_publish(exchange = exchange_name, routing_key = 'new', body = txt)
+ channel.close()
+
+def get_queue_message():
+ exchange_name = 'simple-editor'
+ credentials= pika.PlainCredentials(username= conf.username, password= conf.password)
+ connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=5672, credentials= credentials))
+ channel = connection.channel()
+ channel.exchange_declare(exchange_name, durable=True, exchange_type='topic')
+ txt_edit.delete("1.0", tk.END)
+
+ def callback(ch,method,properties,body):
+ message = 'Message from Queue Part: ' + body.decode("utf-8")
+ txt_edit.insert(tk.END, message)
+ ch.basic_publish('exchange_not_exist', routing_key='new',cbody='Nope this is wrong')
+ ##ch.basic_ack(delivery_tag = method.delivery_tag + 1)
+ # Display the message parts
+ channel.queue_bind(exchange = exchange_name, queue = 'AllInfo', routing_key = 'new')
+ channel.basic_consume(queue='AllInfo', on_message_callback=callback, auto_ack=True)
+ ##channel.consume(queue = 'AllInfo')
+
+ # Close the channel and the connection
+ channel.close()
+ connection.close()
+ message_all = 'Retrieved from RabbitMQ'
+ print(message_all)
+
+def open_file():
+ """Open a file for editing."""
+ filepath = askopenfilename(
+ filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")]
+ )
+ if not filepath:
+ return
+ txt_edit.delete("1.0", tk.END)
+ with open(filepath, mode="r", encoding="utf-8") as input_file:
+ text = input_file.read()
+ txt_edit.insert(tk.END, text)
+ window.title(f"Simple Text Editor - {filepath}")
+
+def save_file():
+ """Save the current file as a new file."""
+ filepath = asksaveasfilename(
+ defaultextension=".txt",
+ filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")],
+ )
+ if not filepath:
+ return
+ with open(filepath, mode="w", encoding="utf-8") as output_file:
+ text = txt_edit.get("1.0", tk.END)
+ output_file.write(text)
+ window.title(f"Simple Text Editor - {filepath}")
+
+window = tk.Tk()
+window.title("Simple Text Editor")
+
+window.rowconfigure(0, minsize=800, weight=1)
+window.columnconfigure(1, minsize=800, weight=1)
+
+
+txt_edit = tk.Text(window)
+frm_buttons = tk.Frame(window, relief=tk.RAISED, bd=2)
+btn_open = tk.Button(frm_buttons, text="Open", command=open_file)
+btn_save = tk.Button(frm_buttons, text="Save As...", command=save_file)
+btn_send = tk.Button(frm_buttons, text="Send", command=send_queue_message)
+btn_receive = tk.Button(frm_buttons, text="Receive", command=get_queue_message)
+
+btn_open.grid(row=0, column=0, sticky="ew", padx=5, pady=5)
+btn_save.grid(row=1, column=0, sticky="ew", padx=5)
+btn_send.grid(row=2, column=0, sticky="ew", padx=5, pady=5)
+btn_receive.grid(row=3, column=0, sticky="ew", padx=5, pady=5)
+
+frm_buttons.grid(row=0, column=0, sticky="ns")
+txt_edit.grid(row=0, column=1, sticky="nsew")
+
+window.mainloop()
diff --git a/pyapp/pyapp/window/temp.py b/pyapp/pyapp/window/temp.py
new file mode 100755
index 0000000..bbe0e96
--- /dev/null
+++ b/pyapp/pyapp/window/temp.py
@@ -0,0 +1,41 @@
+import tkinter as tk
+
+def fahrenheit_to_celsius():
+ """Convert the value for Fahrenheit to Celsius and insert the
+ result into lbl_result.
+ """
+ fahrenheit = ent_temperature.get()
+ celsius = (5 / 9) * (float(fahrenheit) - 32)
+ lbl_result["text"] = f"{round(celsius, 2)} \N{DEGREE CELSIUS}"
+
+# Set up the window
+window = tk.Tk()
+window.title("Temperature Converter")
+window.resizable(width=False, height=False)
+
+# Create the Fahrenheit entry frame with an Entry
+# widget and label in it
+frm_entry = tk.Frame(master=window)
+ent_temperature = tk.Entry(master=frm_entry, width=10)
+lbl_temp = tk.Label(master=frm_entry, text="\N{DEGREE FAHRENHEIT}")
+
+# Layout the temperature Entry and Label in frm_entry
+# using the .grid() geometry manager
+ent_temperature.grid(row=0, column=0, sticky="e")
+lbl_temp.grid(row=0, column=1, sticky="w")
+
+# Create the conversion Button and result display Label
+btn_convert = tk.Button(
+ master=window,
+ text="\N{RIGHTWARDS BLACK ARROW}",
+ command=fahrenheit_to_celsius
+)
+lbl_result = tk.Label(master=window, text="\N{DEGREE CELSIUS}")
+
+# Set up the layout using the .grid() geometry manager
+frm_entry.grid(row=0, column=0, padx=10)
+btn_convert.grid(row=0, column=1, pady=10)
+lbl_result.grid(row=0, column=2, padx=10)
+
+# Run the application
+window.mainloop()
\ No newline at end of file
diff --git a/pyapp/pyapp/wsgi.py b/pyapp/pyapp/wsgi.py
new file mode 100755
index 0000000..303535b
--- /dev/null
+++ b/pyapp/pyapp/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for pyapp project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pyapp.settings')
+
+application = get_wsgi_application()
diff --git a/pyapp/pyapp_api/__init__.py b/pyapp/pyapp_api/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/pyapp/pyapp_api/admin.py b/pyapp/pyapp_api/admin.py
new file mode 100755
index 0000000..8c38f3f
--- /dev/null
+++ b/pyapp/pyapp_api/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/pyapp/pyapp_api/api-client.py b/pyapp/pyapp_api/api-client.py
new file mode 100755
index 0000000..8ffd8e3
--- /dev/null
+++ b/pyapp/pyapp_api/api-client.py
@@ -0,0 +1,10 @@
+import requests
+
+endpoint = "https://httpbin.org/status/200"
+endpoint = "https://httpbin.org/anything"
+endpoint = "http://localhost:8000/api"
+
+get_response = requests.get(endpoint) # HTTP get request
+print(get_response.text)
+
+# REST API -> Web API
\ No newline at end of file
diff --git a/pyapp/pyapp_api/apps.py b/pyapp/pyapp_api/apps.py
new file mode 100755
index 0000000..533edf7
--- /dev/null
+++ b/pyapp/pyapp_api/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class PyappApiConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'pyapp_api'
diff --git a/pyapp/pyapp_api/migrations/__init__.py b/pyapp/pyapp_api/migrations/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/pyapp/pyapp_api/migrations/__pycache__/__init__.cpython-311.pyc b/pyapp/pyapp_api/migrations/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..5f04cf2
Binary files /dev/null and b/pyapp/pyapp_api/migrations/__pycache__/__init__.cpython-311.pyc differ
diff --git a/pyapp/pyapp_api/models.py b/pyapp/pyapp_api/models.py
new file mode 100755
index 0000000..71a8362
--- /dev/null
+++ b/pyapp/pyapp_api/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/pyapp/pyapp_api/serializers.py b/pyapp/pyapp_api/serializers.py
new file mode 100644
index 0000000..88c0cbd
--- /dev/null
+++ b/pyapp/pyapp_api/serializers.py
@@ -0,0 +1,13 @@
+from rest_framework import serializers
+from pyapp.models import ShoppingItem
+from pyapp.models import Product
+
+class ShoppingItemSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = ShoppingItem
+ fields = '__all__'
+
+class ProductSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Product
+ fields = '__all__'
\ No newline at end of file
diff --git a/pyapp/pyapp_api/tests.py b/pyapp/pyapp_api/tests.py
new file mode 100755
index 0000000..7ce503c
--- /dev/null
+++ b/pyapp/pyapp_api/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/pyapp/pyapp_api/urls.py b/pyapp/pyapp_api/urls.py
new file mode 100644
index 0000000..240118b
--- /dev/null
+++ b/pyapp/pyapp_api/urls.py
@@ -0,0 +1,9 @@
+from django.urls import path,include
+from rest_framework.urlpatterns import format_suffix_patterns
+
+from pyapp_api import views
+
+urlpatterns = [
+ path('items/', views.item_list),
+ path('items//', views.item_detail),
+]
diff --git a/pyapp/pyapp_api/views.py b/pyapp/pyapp_api/views.py
new file mode 100755
index 0000000..9049942
--- /dev/null
+++ b/pyapp/pyapp_api/views.py
@@ -0,0 +1,52 @@
+from django.shortcuts import render
+
+from rest_framework.views import APIView
+from rest_framework.decorators import api_view
+from django.http.response import JsonResponse
+from rest_framework.parsers import JSONParser
+from rest_framework.response import Response
+from rest_framework import status, permissions, viewsets
+from pyapp.models import ShoppingItem, Product
+from .serializers import ShoppingItemSerializer, ProductSerializer
+
+@api_view(['GET', 'POST'])
+def item_list(request):
+ """
+ List all ShoppingItems, or create a new snippet.
+ """
+ if request.method == 'GET':
+ ShoppingItems = ShoppingItem.objects.all()
+ serializer = ShoppingItemSerializer(ShoppingItems, many=True)
+ return Response(serializer.data)
+
+ elif request.method == 'POST':
+ serializer = ShoppingItemSerializer(data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data, status=status.HTTP_201_CREATED)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+@api_view(['GET', 'PUT', 'DELETE'])
+def item_detail(request, pk):
+ """
+ Retrieve, update or delete a code snippet.
+ """
+ try:
+ ShoppingItems = ShoppingItem.objects.get(pk=pk)
+ except ShoppingItem.DoesNotExist:
+ return Response(status=status.HTTP_404_NOT_FOUND)
+
+ if request.method == 'GET':
+ serializer = ShoppingItemSerializer(ShoppingItem)
+ return Response(serializer.data)
+
+ elif request.method == 'PUT':
+ serializer = ShoppingItemSerializer(ShoppingItem, data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+ elif request.method == 'DELETE':
+ ShoppingItem.delete()
+ return Response(status=status.HTTP_204_NO_CONTENT)
\ No newline at end of file
diff --git a/pyapp/sql-scripts b/pyapp/sql-scripts
new file mode 100644
index 0000000..e87428a
--- /dev/null
+++ b/pyapp/sql-scripts
@@ -0,0 +1,19 @@
+-- database: /Users/kotyczka/repositories/kotyczka/apps/django/pyapp/db.sqlite3
+
+-- Drücken Sie die ▷-Schaltfläche oben rechts im Fenster, um die gesamte Datei auszuführen.
+
+insert into pyapp_shoppingitem
+SELECT * FROM migration_shoppingitem;
+commit;
+
+create table pyapp_shoppingitem as select * from migration_shoppingitem where 1 = 0;
+commit;
+
+drop table pyapp_product
+commit;
+
+
+
+select * from pyapp_shoppingitem;
+
+delete from pyapp_shoppingitem where name like 'Proxy';
\ No newline at end of file
diff --git a/pyapp/starter/build.sh b/pyapp/starter/build.sh
new file mode 100755
index 0000000..7a380f3
--- /dev/null
+++ b/pyapp/starter/build.sh
@@ -0,0 +1 @@
+docker build -t docker.kotyczka.ch/django-app:latest .
diff --git a/pyapp/starter/demo_native_starter.sh b/pyapp/starter/demo_native_starter.sh
new file mode 100755
index 0000000..597f8b5
--- /dev/null
+++ b/pyapp/starter/demo_native_starter.sh
@@ -0,0 +1,3 @@
+python3 manage.py runserver 9990
+
+##python3 manage.py startapp banking-app
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100755
index 0000000..9a11cdb
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+Django==5.0.1
\ No newline at end of file
diff --git a/start_composer.sh b/start_composer.sh
new file mode 100755
index 0000000..5177d11
--- /dev/null
+++ b/start_composer.sh
@@ -0,0 +1 @@
+docker-compose up -d
\ No newline at end of file
diff --git a/start_virtual.sh b/start_virtual.sh
new file mode 100755
index 0000000..845eada
--- /dev/null
+++ b/start_virtual.sh
@@ -0,0 +1 @@
+source virtualenv/bin/activate
\ No newline at end of file
diff --git a/stop_composer.sh b/stop_composer.sh
new file mode 100755
index 0000000..db5765f
--- /dev/null
+++ b/stop_composer.sh
@@ -0,0 +1,2 @@
+docker-compose down -v
+docker rmi docker.kotyczka.ch/django-app:latest
\ No newline at end of file