diff --git a/Tech-Lab-On-Campus/Producer-And-Consumer/README.md b/Tech-Lab-On-Campus/Producer-And-Consumer/README.md new file mode 100644 index 00000000..5ee836a1 --- /dev/null +++ b/Tech-Lab-On-Campus/Producer-And-Consumer/README.md @@ -0,0 +1,24 @@ +# Problem Definition: ✨Producer And Consumer✨ + +## Instructions + +In this section, you will collaborate with a partner to instantiate the producer and consumer classes. One person will focus on the producer section while the other works on the consumer section. Afterwards, you'll exchange solutions verbally or via GitHub. We highly recommend using GitHub for this purpose, working on the same fork, and pushing your solutions. GitHub is widely used across the tech industry. You can find a GitHub file in the resource folder to assist you with this. + +Below are bullet points of the criteria: +- First ensure that each contributor is working from and has `cloned the same fork` of the BBIT-LEARNING-LABS repository. +- Second ensure that each contributor has been `added as a collaborator to the fork.` +- One person completes the `producer section.` +- One person completes the `consumer section.` +- Each contributor should then `git push` their solutions to the fork. +- Lastly, follow the `testing instructions below` to send and recieve a message to complete this section. + + +`IMPORTANT!!!` Please utlize the [Functions.md](../Resources/Functions.md) file as it contains almost all the functions you will need for this lab. Also, other helpful information can be found under the Resources folder for Python, Git, and RabbitMQ details. + +## Testing +In order to verify that the consumer and producer class was properly instantiated, we will use the provided `consume.py`, and `publish.py` file from producer and consumer folder. Follow the below instructions: +1. In the terminal window, run the `consume.py` file from the consumer sectio using the python interpreter. +2. In another terminal window, run the `publish.py` file from the producer section using the python interpreter. This will publish a message using RabbitMQ. +3. Return to the first terminal window with the consumer running. "Success! Producer And Consumer Section Complete." should now be displayed on your terminal if you instantiated & implemented the consumer class correctly. +* Note that if you are developing from the terminal in your IDE, inside the second terminal window you will need to step into the rmq_lab Docker container in order to access the python enviroment. We do this by first running the `docker exec -it [containterName\containerID] /bin/bash` command. Using the `docker ps -a` command will show all the running docker containers and their associated I.D and names. Your command could be `docker exec -it tech-lab-on-campus-rmq_lab-1 /bin/bash` or `docker exec -it 8a785d10fd7e /bin/bash` + diff --git a/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/README.md b/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/README.md new file mode 100755 index 00000000..c0a0609e --- /dev/null +++ b/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/README.md @@ -0,0 +1,36 @@ +# Problem Definition: ✨Consumer✨ + +## Instructions +Create a .py file that will contain a class that is setup to be a consumer in the RabbitMQ framework. This class will inherit from the mqConsumerInterface and consume and print a simple UTF-8 string message. + +Below are bullet points of the criteria: +- In the `solution` directory, create a file named `consumer_sol.py` +- Write your code in the `consumer_sol.py` file +- Create a class named `mqConsumer` +- Your class should inherit from our mqConsumerInterface. +- Constructor: Save the three variables needed to instantiate the class. +- Constructor: Call the setupRMQConnection function. +- setupRMQConnection Function: Establish connection to the RabbitMQ service, declare a queue and exchange, bind the binding key to the queue on the exchange and finally set up a callback function for receiving messages +- onMessageCallback: Print the UTF-8 string message and then close the connection. +- startConsuming: Consumer should start listening for messages from the queue. + + +## Testing +In order to verify that the consumer class was properly instantiated, we will use the provided `consume.py`, file. Follow the below instructions: +1. Start consumer +* To test your implementation you can run `consume.py`. It will import your newly created class from the source file `consume_sol.py` in the `solution` directory. +2. Log Into the RabbitMQ website. +* The login URL for the management web application will be http://localhost:15672/ +* Login username and password should be `guest` +3. Check Queue +* Click on tab `Queues and Streams`. +* Under this tab you should see your created Queue appropriately named `Tech Lab Queue` + +![alt text](../../../data/Images/consumerQueue.jpeg) + +4. Check Binding +* Click on the "Tech Lab Queue" +* You should see under `Bindings` that the Queue is bound to the exchange `Tech Lab Exchange` with the key `Tech Lab Key` + +![alt text](../../../data/Images/consumerBinding.jpeg) + diff --git a/Tech-Lab-On-Campus/consumer/__init__.py b/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/__init__.py similarity index 100% rename from Tech-Lab-On-Campus/consumer/__init__.py rename to Tech-Lab-On-Campus/Producer-And-Consumer/consumer/__init__.py diff --git a/Tech-Lab-On-Campus/consumer/consume.py b/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consume.py similarity index 82% rename from Tech-Lab-On-Campus/consumer/consume.py rename to Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consume.py index 8497fd98..01570ab3 100755 --- a/Tech-Lab-On-Campus/consumer/consume.py +++ b/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consume.py @@ -17,11 +17,11 @@ import os import sys -from consumer_sol import mqConsumer # pylint: disable=import-error +from solution.consumer_sol import mqConsumer # pylint: disable=import-error def main() -> None: - consumer = mqConsumer(binding_key="Routing Key",exchange_name="Exchange Name",queue_name="Queue Name") + consumer = mqConsumer(binding_key="Tech Lab Key",exchange_name="Tech Lab Exchange",queue_name="Tech Lab Queue") consumer.startConsuming() diff --git a/Tech-Lab-On-Campus/consumer/consumer_interface.py b/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consumer_interface.py similarity index 92% rename from Tech-Lab-On-Campus/consumer/consumer_interface.py rename to Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consumer_interface.py index 28ae1a51..d1ee8e65 100755 --- a/Tech-Lab-On-Campus/consumer/consumer_interface.py +++ b/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consumer_interface.py @@ -39,11 +39,15 @@ def setupRMQConnection(self) -> None: def on_message_callback( self, channel, method_frame, header_frame, body ) -> None: - # Acknowledge and print message + # Acknowledge message + + #Print message # Close channel and connection pass def startConsuming(self) -> None: + # Print " [*] Waiting for messages. To exit press CTRL+C" + # Start consuming messages pass diff --git a/Tech-Lab-On-Campus/market_watch/__init__.py b/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/solution/.gitignore old mode 100755 new mode 100644 similarity index 100% rename from Tech-Lab-On-Campus/market_watch/__init__.py rename to Tech-Lab-On-Campus/Producer-And-Consumer/consumer/solution/.gitignore diff --git a/Tech-Lab-On-Campus/producer/README.md b/Tech-Lab-On-Campus/Producer-And-Consumer/producer/README.md similarity index 80% rename from Tech-Lab-On-Campus/producer/README.md rename to Tech-Lab-On-Campus/Producer-And-Consumer/producer/README.md index 4daa2a6a..b4831e2e 100755 --- a/Tech-Lab-On-Campus/producer/README.md +++ b/Tech-Lab-On-Campus/Producer-And-Consumer/producer/README.md @@ -4,25 +4,24 @@ Create a ".py" file that will contain a class set up to be a producer in the RabbitMQ framework. This class will inherit from the mqProducerInterface and should publish a simple UTF-8 string message. Below are bullet points of the criteria: -- Your class should be named mqProducer. +- In the `solution` directory, create a file named `producer_sol.py` +- Write your code in the `producer_sol.py` file +- Create a class named `mqProducer` - Your class should inherit from our mqProducerInterface. -- The class name should be `mqProducer` & the source file should be called `producer_sol.py` - Constructor: Save the two variables needed to instantiate the class. - Constructor: Call the setupRMQConnection function. - setupRMQConnection Function: Establish connection to the RabbitMQ service. - publishOrder: Publish a simple UTF-8 string message from the parameter. -###### [Note: Utilize the following resource to help instantiate the Producer Class: [RabbitMQ Toturial](https://www.rabbitmq.com/tutorials/tutorial-one-python.html)] - ## Testing To test your producer class, we'll use Docker to set up a container running RabbitMQ. We'll then create a testing container where you can run the test code provided. To validate the messages are being sent, you'll utilize the RabbitMQ container's management web application. 1. Log Into the RabbitMQ website. * The login URL for the management web application will be http://localhost:15672/ * Login username and password should be "guest" 3. Send your message -* To test your implementation you can run `publish.py`. It will import your newly created class from the source file `producer_sol.py` +* To test your implementation you can run `publish.py`. It will import your newly created class from the source file `producer_sol.py` in the `solution` directory. 4. Check Message Rates * Return to the RabbitMQ website. * Look Under the Overview Tab for message rates to verify that a message was sent. Your message rate should look like the image below. -![alt text](./message_rate.jpeg) +![alt text](../../../data/Images/message_rate.jpeg) diff --git a/Tech-Lab-On-Campus/producer/__init__.py b/Tech-Lab-On-Campus/Producer-And-Consumer/producer/__init__.py similarity index 100% rename from Tech-Lab-On-Campus/producer/__init__.py rename to Tech-Lab-On-Campus/Producer-And-Consumer/producer/__init__.py diff --git a/Tech-Lab-On-Campus/producer/producer_interface.py b/Tech-Lab-On-Campus/Producer-And-Consumer/producer/producer_interface.py similarity index 100% rename from Tech-Lab-On-Campus/producer/producer_interface.py rename to Tech-Lab-On-Campus/Producer-And-Consumer/producer/producer_interface.py diff --git a/Tech-Lab-On-Campus/producer/publish.py b/Tech-Lab-On-Campus/Producer-And-Consumer/producer/publish.py similarity index 79% rename from Tech-Lab-On-Campus/producer/publish.py rename to Tech-Lab-On-Campus/Producer-And-Consumer/producer/publish.py index abdacbbb..1af892d4 100755 --- a/Tech-Lab-On-Campus/producer/publish.py +++ b/Tech-Lab-On-Campus/Producer-And-Consumer/producer/publish.py @@ -18,12 +18,12 @@ import sys # Update the import to match the producer class file you created if it's different then the default -from producer_sol import mqProducer # pylint: disable=import-error +from solution.producer_sol import mqProducer # pylint: disable=import-error def main() -> None: - producer = mqProducer(routing_key="Routing Key",exchange_name="Exchange Name") - producer.publishOrder("Hello World") + producer = mqProducer(routing_key="Tech Lab Key",exchange_name="Tech Lab Exchange") + producer.publishOrder("Success! Producer And Consumer Section Complete.") if __name__ == "__main__": diff --git a/Tech-Lab-On-Campus/Producer-And-Consumer/producer/solution/.gitignore b/Tech-Lab-On-Campus/Producer-And-Consumer/producer/solution/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/Tech-Lab-On-Campus/README.md b/Tech-Lab-On-Campus/README.md index f591c8f1..4ad9146b 100755 --- a/Tech-Lab-On-Campus/README.md +++ b/Tech-Lab-On-Campus/README.md @@ -4,6 +4,11 @@ The idea of this lab is to offer exposure to the RabbitMQ messaging framework, providing a basic understanding of the technology and the producer consumer relationship. During the lab you will apply your learning to create small system to setup information update on securities on interest. +## Unit Ordering List + +1. [Producer-AND-Consumer](./Producer-And-Consumer/README.md) +2. [Topic-Exchange](./Topic-Exchange/README.md) + ## Key Learning Items - Python CS Concepts @@ -20,146 +25,68 @@ The idea of this lab is to offer exposure to the RabbitMQ messaging framework, p - Docker ## Setting Up Our Environment -For this project, we're going to leverage the use of Docker to create a helpful development environment for all of the engineers. [Docker](https://docs.docker.com/desktop/) is a tool used to integrate software dependencies and allow developers to quickly spin up software builds in portable lightweight containers which provide consistent environments, ensuring applications run the same way across various platforms. Here are the steps to check that the environment is running correctly: - -1. Clone the repo into your working directory. -```sh -git clone git@github.com:bloomberg/bbit-learning-labs.git -``` - -2. Navigate to the 'Tech-Lab-On-Campus' folder. -```sh -cd bbit-learning-labs/Tech-Lab-On-Campus -``` - -3. Confirm that Docker and Docker Compose are working on your system. -```sh -docker -v && docker-compose -v -``` -* If this works correctly, you will have the versions of Docker and Docker Compose printed to the terminal. -* Note: If you encounter an error at this step navigate to advanced settings on your Docker Desktop and ensure that `System (requires password)` is selected. This tab can be found by clicking on the gear icon in the top right corner. +For this project, we're going to leverage the use of Docker to create a helpful development environment for all of the engineers. [Docker](https://docs.docker.com/desktop/) is a tool used to integrate software dependencies and allow developers to quickly spin up software builds in portable lightweight containers which provide consistent environments, ensuring applications run the same way across various platforms. + +1. Fork the repo +![fork](../data/Images/fork-1.JPG) -4. Utilize Docker to generate and execute a functional image of the project directly from the terminal within your chosen Integrated Development Environment (IDE). Whether you opt for developing the project in Jupyter Notebook or your preferred IDE, follow the steps outlined below to ensure a smooth setup and execution process: +2. Clone the forked repo into your working directory. Copy ssh. +![ssh](../data/Images/copy_ssh.PNG) -A) Jupyter Notebook -* In the terminal window of your IDE run: ```sh - docker-compose up + git clone [SSH KEY] ``` -* In the output lines produced by the command, you will find three links providing access to the server hosting your Jupyter Notebook. Click on any one of these links to open and interact with the notebook. The links should resemble the following: - ``` - rmq_lab-1 | To access the server, open this file in a browser: - rmq_lab-1 | file:///home/jovyan/.local/share/jupyter/runtime/jpserver-1-open.html - rmq_lab-1 | Or copy and paste one of these URLs: - rmq_lab-1 | http://d572024fabe2:8888/lab?token=4a07fca9cd4a66eba129533a6272f5f5443fdf3f0b7c0e5e - rmq_lab-1 | http://127.0.0.1:8888/lab?token=4a07fca9cd4a66eba129533a6272f5f5443fdf3f0b7c0e5e - ``` - -B) IDE -* In the terminal window of your IDE run: + +3. Navigate to the 'Tech-Lab-On-Campus' folder. ```sh - docker-compose up -d && docker-compose exec rmq_lab /bin/bash + cd bbit-learning-labs/Tech-Lab-On-Campus ``` -* `docker-compose up -d` : Starts our rabbitmq and python service in detached mode (-d), running them in the background. -* `docker-compose exec rmq_lab /bin/bash` : This command will open an interactive Bash shell inside the rmq_lab service container. Once you are inside the container you can run Python scripts. - -* Note: If you encounter an error such as `unix:///Users/userName/.docker/run/docker.sock. Is the docker daemon running?`, please ensure that your Docker application is running. - -5. Log Into the RabbitMQ Website. -* From your desktop, open Docker Desktop Dashboard. -* Find the Rabbitmq container and click on the URL under Port(s) for the U.I. This should open up the RabbitMQ website on your default browser. -* Login username and password should be "guest" -* Alternative: Click on one of the generated URLs in your terminal, such as "http://localhost:15672/", once your docker container is up and running. - -6. You are now ready to start the lab. Begin by navigating to the producer folder and reading the "README.md" file. Each of the three units will contain a readme file which will give you the necessary instructions to complete the lab and test your solution. The order in which the lab should be completed as well as information regarding rabbitmq can be found below. - -## Unit Ordering List - -1. Producer -2. Consumer -3. Market Watch - - -# Concepts - -### What is Rabbit MQ? - -RabbitMQ is a lightweight, language agnostic & open source messaging software that implements the [AMQP (Advanced Message Queuing Protocol)](https://www.amqp.org/about/what). It works as a message broker that supports various types of asynchronous messaging features and routing types. Using RabbitMQ you can configure your message to get from a source to destinations in a variety of ways. - -Within this lab we'll focus on setting up a basic producer-consumer framework within rabbitMQ. This is just the beginning and there are many more ways rabbitMQ can be used! For more learning opportunities check out the official rabbitMQ [Getting Started](https://www.rabbitmq.com/getstarted.html) page. - -### What is a Producer? - -A producer is a entity (object, application, etc) that creates & sends information to be distributed. In RabbitMQ producers send these messages to an exchange. You can have multiple producers which depending on the exchange will send data to 0 to N queues. For this lab we'll focus on using a single producer. Producers send messages to exchanges along with the routing key associated with that message. At a high level this routing key tells the rabbitMQ framework that the producer would like to send the associated message to queues that match a given regex string. The replication & matching of the routing key is dependant on the type of exchange (explained below). A more concrete example is, we may have a message intended for a particular set of schools that are all in the US. My routing key in that scenario would be "US" which would signal this particular message should go to queues designated as US. - -### What is a Consumer? -A consumer is an entity (object, application, etc.) receiving information from a queue. In RabbitMQ you can have multiple queues, each with the potential for various consumers. In this lab we'll focus on setting up a queue with a single consumer. - -### Exchanges - -Exchanges are the mechanism that tells RabbitMQ how messages should be directed to a queue. You can think of an exchange like different delivery services. Delivery service **Direct Delivery!** may deliver messages to queues/locations based on particular addresses "123 My Address Road, NY, NY, 10022". This would be an example of a **direct exchange** where messages are sent to queues that have a *binding key* that exactly matches the message's *routing key*. Other exchanges also exist such as the **fanout exchange** which will replicate incoming messages to all queues bound to the exchange. An excellent example of a fanout exchange would be a chat room where an incoming message is sent to all users within the chatroom. Typically, a producer needs to be made aware of the queues or consumers attached to queues. A producer is concerned with what exchange it wants to send its message to, the distribution method of that exchange, and the routing key of the message it wants to send. - -Within Python using pika an exchange can be declared similar to the following: - -```python -#Build our connection to the RMQ Connection. -#The AMPQ_URL is a string which tells pika the package the URL of our AMPQ service in this scenario RabbitMQ. -conParams = pika.URLParameters(os.environ['AMQP_URL']) -connection = pika.BlockingConnection(parameters=conParams) -channel = connection.channel() -channel.exchange_declare('Test Exchange') - -#We can then publish data to that exchange using the basic_publish method -channel.basic_publish('Test Exchange', 'Test_route', 'Hi',...) -``` - -### Topic Exchange -A **topic exchange** route messages to one or many queues based on matching between a message routing key and the pattern that was used to bind a queue to an exchange. - -Messages sent to a topic exchange must use a routing and binding key that are a list of words separated by dots (ex. `some.routing.key`). Topic exchanges are similar to **direct exchanges** in logic; a message sent with a particular routing key will be delivered to all the queues that are bound with a matching binding key. -- Using a `*` symbol in your binding key will substitute it with __exactly 1 word__ -- Using a `#` symbol in your binding key will substitute it with __0 or more words__ - -With Python and pika, an exchange can be declared similar to the following: -```py -# We'll first set up the connection and channel -connection = pika.BlockingConnection( - pika.ConnectionParameters(host='localhost')) -channel = connection.channel() - -# Declare the topic exchange -channel.exchange_declare(exchange='topic_logs', exchange_type='topic') - -# Set the routing key and publish a message with that topic exchange: -routing_key = sys.argv[1] if len(sys.argv) > 2 else 'anonymous.info' -message = ' '.join(sys.argv[2:]) or 'Hello World!' -channel.basic_publish( - exchange='topic_logs', routing_key=routing_key, body=message) -print(f" [x] Sent {routing_key}:{message}") -``` - -# Basic Financial Concepts - -### What is a Stock? - -A stock like **APPL**, is a financial instrument representing a **fractional ownership stake in a corporation** such as Google or Costco. **A unit of stock is called a "share."** "Shares"respective values are proportional to the total monetary worth of a company. - -Note that stocks for a given company are identified by a combination of letters and symbols rather than the company name; this is called its **ticker symbol.** For example, the ticker symbol for Apple is **APPL**. - -### What is a Position? -A position represents **how much of a particular stock is owned by an individual or financial firm.** Simply put, it lets you know how much of a financial asset you own. - -For example, you could have a position like this: - -A position of **2,000** shares of **MSFT**! - -### What is a Portfolio? +4. Confirm that Docker and Docker Compose are working on your system. + ```sh + docker -v && docker-compose -v + ``` +* If this works correctly, you will have the versions of Docker and Docker Compose printed to the terminal. +* Note: If you encounter an error at this step navigate to advanced settings on your Docker Desktop and ensure that `System (requires password)` is selected. This tab can be found by clicking on the gear icon in the top right corner. -A portfolio represents a **collection of all the investments an individual or entity owns.** These financial investments can be any combination of any financial assets such as **stocks, bonds,cash**, etc. +5. Utilize Docker to generate and execute a functional image of the project directly from the terminal within your chosen Integrated Development Environment (IDE). + +There are two options to work on this project. Option [A] using an IDE, we recommend using VSCode. Option [B] using the jupyter notebook. Follow the steps outlined for the desired option to ensure a smooth setup and execution process: + +* A) IDE + * In the terminal window of your IDE run: + ```sh + docker-compose up -d && docker-compose exec rmq_lab /bin/bash + ``` + * `docker-compose up -d` : Starts our rabbitmq and python service in detached mode (-d), running them in the background. + * `docker-compose exec rmq_lab /bin/bash` : This command will open an interactive Bash shell inside the rmq_lab service container. Once you are inside the container you can run Python scripts. + + * Note: If you encounter an error such as `unix:///Users/userName/.docker/run/docker.sock. Is the docker daemon running?`, please ensure that your Docker application is running. + +* B) Jupyter Notebook + * In the terminal window of your IDE run: + ```sh + docker-compose up + ``` + * In the output lines produced by the command, you will find three links providing access to the server hosting your Jupyter Notebook. Click on any one of these links to open and interact with the notebook. The links should resemble the following: + ``` + rmq_lab-1 | To access the server, open this file in a browser: + rmq_lab-1 | file:///home/jovyan/.local/share/jupyter/runtime/jpserver-1-open.html + rmq_lab-1 | Or copy and paste one of these URLs: + rmq_lab-1 | http://d572024fabe2:8888/lab?token=4a07fca9cd4a66eba129533a6272f5f5443fdf3f0b7c0e5e + rmq_lab-1 | http://127.0.0.1:8888/lab?token=4a07fca9cd4a66eba129533a6272f5f5443fdf3f0b7c0e5e + ``` +6. Here are the steps to check that the environment is running correctly: + * Log Into the RabbitMQ Website. + * From your desktop, open Docker Desktop Dashboard. + * Find the Rabbitmq container and click on the URL under Port(s) for the U.I. This should open up the RabbitMQ website on your default browser. + * Login username and password should be "guest" + + * Alternative: Click on one of the generated URLs in your terminal, such as "http://localhost:15672/", once your docker container is up and running. + + * After setting up IDE you should have access to rabbit mq management. It will look like the following. + ![rabbitmqup](../data/Images/rabbit_mq.PNG) + * You are now ready to start the lab. Begin by navigating to the [Producer-AND-Consumer](./Producer-And-Consumer/README.md) folder and reading the "README.md" file. Each of the units will contain a readme file which will give you the necessary instructions to complete the lab and test your solution. -For example, I could have a portfolio which contains the positions: -**10** shares of **MSFT USD** and **10** shares of **AAPL USD** -Hypothetically, if a stock of MSFT is worth $50 each and a stock of AAPL is worth $20 each, then the total value of the portfolio above would be $70. diff --git a/Tech-Lab-On-Campus/Resources/Finance.md b/Tech-Lab-On-Campus/Resources/Finance.md new file mode 100644 index 00000000..2a39953d --- /dev/null +++ b/Tech-Lab-On-Campus/Resources/Finance.md @@ -0,0 +1,24 @@ +# Basic Financial Concepts + +### What is a Stock? + +A stock like **APPL**, is a financial instrument representing a **fractional ownership stake in a corporation** such as Google or Costco. **A unit of stock is called a "share."** "Shares"respective values are proportional to the total monetary worth of a company. + +Note that stocks for a given company are identified by a combination of letters and symbols rather than the company name; this is called its **ticker symbol.** For example, the ticker symbol for Apple is **APPL**. + +### What is a Position? +A position represents **how much of a particular stock is owned by an individual or financial firm.** Simply put, it lets you know how much of a financial asset you own. + +For example, you could have a position like this: + +A position of **2,000** shares of **MSFT**! + +### What is a Portfolio? + +A portfolio represents a **collection of all the investments an individual or entity owns.** These financial investments can be any combination of any financial assets such as **stocks, bonds,cash**, etc. + +For example, I could have a portfolio which contains the positions: + +**10** shares of **MSFT USD** and **10** shares of **AAPL USD** + +Hypothetically, if a stock of MSFT is worth $50 each and a stock of AAPL is worth $20 each, then the total value of the portfolio above would be $70. \ No newline at end of file diff --git a/Tech-Lab-On-Campus/Functions.md b/Tech-Lab-On-Campus/Resources/Functions.md similarity index 100% rename from Tech-Lab-On-Campus/Functions.md rename to Tech-Lab-On-Campus/Resources/Functions.md diff --git a/Tech-Lab-On-Campus/Resources/Git-Commands.md b/Tech-Lab-On-Campus/Resources/Git-Commands.md new file mode 100644 index 00000000..5b01b066 --- /dev/null +++ b/Tech-Lab-On-Campus/Resources/Git-Commands.md @@ -0,0 +1,137 @@ +# Understanding Git & Github + +## What is Git? + +Git is a distributed version control system that helps developers collaborate on projects of any scale. This allows developers to bring a repo full of code down to their workstations, perform their work items, and then put it back into a central server. + +## Commands You'll Need For Today +_\# indicates a comment in bash_ + +### Check status of changes + +```bash +# See list of files changed +git status +``` +- The git **status** command displays the state of the working directory and the staging area. It lets you see which changes have been staged, which haven't, and which files aren't being tracked by Git. + +### Upload Your Changes Step 1: Add Files to be Tracked +```bash +# add files by paths +git add [fileName] +# OR add file interactively one by one +git add -p +# OR add all changed files (what you'll do more often than not) +git add --all +``` +- The git **add** command adds a change in the working directory to the staging area. It tells Git that you want to include updates to a particular file in the next commit. + + +### Upload Your Changes Step 2: Save Changes in a Commit +```bash +# Commit changes with a descriptive commit message +git commit -m "commit description" +``` +- Changes are not actually recorded after `git add` until you run `git commit`. +- A **commit** captures a snapshot of the project's currently staged changes. Committed snapshots can be thought of as “safe” versions of a project—Git will never change them unless you explicitly ask it to. + +### Upload Your Changes Step 3: Push Committed Changes to Remote Repository +```bash +# Push changes up to remote repo in whatever branch you are working in +git push + +# IF it is your first time pushing, git will show you a message of where to set the push stream +git push --set-upstream origin my-new-feature +``` +- The git **push** command is used to upload local repository content to a remote repository. Pushing is how you transfer commits from your local repository to a remote repo. + +### Get changes from origin/main to current branch + +```bash +# origin/main => local main +git pull origin main +``` +- The git **pull** command is used to fetch and download content from a remote repository and immediately update the local repository to match that content + +# An In-Depth Look at Git + +#### So why do we need version control? + +Think about a video game where you've gotten to level 16. But to beat the game completely, you have to make it to level 20. Should you only be able to finish the game if you complete flawlessly it in one try? Of course not. With a version control system you can **commit** your code, kind of like a checkpoint in a video game, before you actually push it and merge it into your codebase. With version control, you can also roll back to previous commits if you want to change something you did without having to Ctrl+Z 100 times. This is why you should _commit often_ and with detailed commit messages. + +#### Some terms you should understand about version control: + +- **Version control** - known as source control, is the practice of tracking and managing changes to software code. Version control systems are software tools that help software teams manage changes to source code over time +- **Repository or "repo"** - Each Git project is called a repository, or “repo” for short. A repo stores all the files and changes made to your project. It’s like a project with memory allowing you to move back and forward in time and observe the ways you have changed and modified your project. Thus, the repo stores data and change information. For developers it can be especially useful as they are learning version control systems to practice how to clone a GitHub repository and know how to delete a repository in GitHub. + The three big things you do with version control are commit, clone, and branch. When you commit a change, you add your latest changes to your repo and are directing information to be filed. As in life, commitment is a serious responsibility – and is why every commit needs a serious commit message. A commit message explains changes and is the primary way to communicate changes to your development team. When you commit, you push your changes to the repository, and all information heading upstream to your repo is pushed. This push propels information from your local source into the shared repository. +- **Diffs** - Every time you commit there are differences between the project from the last save point to the new one. These changes are called differences, or “diffs” for short. You can compare changes between commits by looking at the diffs. +- **Merge Conflict** - A conflict occurs when two parties change the same file and there's no automatic way to reconcile the changes. You must resolve the change by selecting which change wins. +- **Clone** - When you clone a Git repository, you create a local copy to work on and your version will match the contents of the repository at the time you cloned it. For instance, you can clone a repository on GitHub to your computer where you can compile it from source, modify it, and more. +- **Pull** - If you've been working on a clone project, you may need to catch up with changes others have made by pulling, which changes revisions from the repository to your local copy. +- **Forking** - Another way to copy a repository is called “forking,” and is more like a fork in a tree. Unlike when you clone and make a copy on your computer, forking involves making a new repository, typically on GitHub or whatever hosting site you're using. A fork has all the contents of the original, but you are now the owner of this new repository and you're starting a new development project. You're copying a project when you fork and you're working on a project when you clone. +- **Branch** - Branches let you create alternate versions of your project. When you branch you can work on new features and try new ideas without messing with your main work. Consider this – your main work may have many names and, like a tree trunk, it’s commonly called the “master,” “master branch,” or “baseline.” The trunk or master is where your team keeps its primary project development and if it’s messed with, your team will suffer. Thus, if you plan to work on something that will take a while and may break your build, be sure to branch so you don't interfere with the work of others on your team. +- [**Open Source**](https://opensource.com/resources/what-open-source) - The term open source refers to something people can modify and share because its design is publicly accessible. + +There are other distributed version control systems that are widely used, for example Mercurial. Instead of typing `git` before commands, you would use `hg` for this version control system. The three most popular DVCS (Distributed Version Control Systems) are Mercurial, Git, and Bazaar. Here, we will solely focus on Git. + + +## Creating your own Organizations and Repositories + +You can create a repository for each project you start on your personal GitHub account, _but many suggest creating a separate organization_ for projects you plan to collaborate on or make open-source. + +#### [QuickStart tutorial for Repositories](https://docs.github.com/en/repositories/creating-and-managing-repositories/quickstart-for-repositories) + +#### [README Files](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes) + +- You can add a README file to your repository to tell other people why your project is useful, what they can do with your project, and how they can use it. +- If a filed titled `README.md` file in your repository's hidden .github, root, or docs directory, GitHub will recognize and automatically surface your README to repository visitors. +- If a repository contains more than one README file, then the file shown is chosen from locations in the following order: the .github directory, then the repository's root directory, and finally the docs directory. + +## Understanding Branches & How to Collaborate + +#### [Pull Requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) + +- Pull requests let you tell others about changes you've pushed to a branch in a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before your changes are merged into the base branch. +- In order to help your team, make sure you publish your Pull Requests when they're ready with clean code and helpful descriptions``` + +#### [Merging](https://git-scm.com/docs/git-merge) + +Merging is Git's way of putting a forked history back together again. The git merge command lets you take the independent lines of development created by git branch and integrate them into a single branch. Note that all of the commands presented below merge into the current branch. + + +#### [Merge Conflicts](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/about-merge-conflicts) + +- Merge conflicts happen when you merge branches that have competing commits, and Git needs your help to decide which changes to incorporate in the final merge +- Keep your code loosely coupled and divide work appropriately to try to avoid merge conflicts as much as possible, though they will eventually be inevitable + +#### [Rebasing](https://docs.github.com/en/get-started/using-git/about-git-rebase) + +The git rebase command allows you to easily change a series of commits, modifying the history of your repository. You can reorder, edit, or squash commits together. +Typically, you would use git rebase to: + +- Edit previous commit messages +- Combine multiple commits into one +- Delete or revert commits that are no longer necessary + +## Common Commands You Should Know + +_For more, check out the [Git Cheat Sheet](https://education.github.com/git-cheat-sheet-education.pdf)_ + +#### First Time Git users + +| **Command** | **Action** | +| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `git config -l` | check your Git configuration - returns a list of information about your git configuration including user name and email | +| `git config --global user.name "Genesis"` | Set up your username | +| `git config --global user.email "genesis@gmail.com"` | This command lets you setup the user email address you'll use in your commits. | +| `git init` | initialize a git Repo | + +#### Every Day Commands + +| **Command** | **Action** | +| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| `git add [file names]` | First step in pushing changes. This adds changes in the file listed to be tracked for changes. To add all changes in all files, run `git add .` | +| `git commit -m "message"` | Commit your code with a _detailed_ message | +| [`git push`](https://docs.github.com/en/get-started/using-git/pushing-commits-to-a-remote-repository) | Push local changes up to remote git branch | +| `git checkout -b branch-name` | create new branch, branch-name | +| `git checkout branch-name` | open up the branch branch-name | diff --git a/Tech-Lab-On-Campus/Resources/Python-Basics.md b/Tech-Lab-On-Campus/Resources/Python-Basics.md new file mode 100644 index 00000000..7745727d --- /dev/null +++ b/Tech-Lab-On-Campus/Resources/Python-Basics.md @@ -0,0 +1,110 @@ +# Python Basics + +## Import Modules +To import a module, for example `sys`, use the keyword `import`: +```sh +import sys +``` +If you are trying to import only one method or a class from another file / module: +```sh +from dog_interface import DogInterface +``` + +## Creating a Class +Classes are the building blocks of object-oriented programming. In python, to create a class +we use the keyword `class` to define a class. For example, let's say I want to create a class called Animal. Within a class, there is a constructor method called `__init__` which initalizes a newly created object. +Here is an example of a simple class: +```sh +class Animal: + def __init__(self, name): + # body of constructor + self.name = name + + def eat(self): + print(self.name, "is eating.") +``` + +## Saving a Instance Variable and Calling the Variable +In python, there is a keyword, `self`, which represents an instance of a class. This keyword allows you to access variables, methods, and attributes in the class. Let's build out our Dog interface and pass in the name of a dog, and have a function named bark: +```sh +class Dog(DogInterface): + def __init__(self, name) -> None: + # Save parameters to instance variable + self.name = name + + def bark(self) -> None: + # Print {name of dog} is barking! + print(self.name, "is barking!") +``` +We can access the name initialized in the `__init__` method with `self`. When we want to create an object of this class with a name and call the method, `bark()`, it can access the name given and print out the statement. Remember, this is an example. You can initialize more variables within any of the class methods and access it through `self`! + +## Creating an Interface +Python does not have a keyword for interfaces. An interface is an abstract class that defines methods which are not implemented. An interface is implemented in the same way as a class, however, an interface will have abstract methods so you will see the keyword `pass` in those methods. That means that any subclass will construct those methods how it wants to use them. So two different classes which inherit from the same intergace will inherit the same functions, but can have different implementations. +Here is an example of a simple interface: +```sh +class DogInterface: + def __init__(self, name) -> None: + # Save parameters to class variables + pass + + def bark(self) -> None: + # Print {name of dog} is barking! + pass +``` + +## Inheritance +Inheritance allows us to define a class that can inherit methods and properties of another existing class or interface. Let us use the example DogInterface from above. Let's create a Dog class that inherits DogInterface: +```sh +class Dog(DogInterface): + def __init__(self, name): + # Save parameters to instance variable + self.name = name + + def bark(self): + # Print {name of dog} is barking! + print(self.name, "is barking!") +``` +Since `Dog` is inheriting `DogInterface`, we implement the methods according to how we want both methods to work. + +To inherit from another class would have the same initialization, but the child class can have different methods. Let's write a Dog class inheriting the class Animal that was mentioned in the Creating a Class section: +```sh +class Dog(Animal): + def __init__(self, name): + self.name = name +``` +Since `Dog` is inheriting `Animal`, we can use the method `eat()` on all `Dog` objects. +```sh +snoopy = Dog("Snoopy") +snoopy.eat() # this will print: "Snoopy is eating." +``` + +## Reading from Command Line Using sys +There are a few ways to read arguments from the command line, but we will go over using `sys`. +In this module, there is a variable, `sys.argv`, which is a list. Some things to note: + +1. since sys.argv is a list, we can get the length of arguments with len() +2. sys.argv[0] will be the name of the file given +3. All arguments are **strings**! + +**Example** + +Command: +```sh +python3 read_cmd_line.py apple banana +``` +Code: +```sh +""" +Read arguments from command line using sys.argv +""" + +import sys + +print("Name of the program using sys.argv[0]: ", sys.argv[0]) +print("Length of arguments given including program name: ", len(sys.argv)) +print("Argument list: ", sys.argv) +print("Argument list type: ", type(sys.argv)) +print("Give the first argument (after program name): ", sys.argv[1]) +``` +Output: +![alt text](../../data//Images/sys-argv-image.jpg) diff --git a/Tech-Lab-On-Campus/Resources/RabbitMQ.md b/Tech-Lab-On-Campus/Resources/RabbitMQ.md new file mode 100644 index 00000000..a4cdc758 --- /dev/null +++ b/Tech-Lab-On-Campus/Resources/RabbitMQ.md @@ -0,0 +1,63 @@ +# Concepts + +### What is Rabbit MQ? + +RabbitMQ is a lightweight, language agnostic & open source messaging software that implements the [AMQP (Advanced Message Queuing Protocol)](https://www.amqp.org/about/what). It works as a message broker that supports various types of asynchronous messaging features and routing types. Using RabbitMQ you can configure your message to get from a source to destinations in a variety of ways. + +Within this lab we'll focus on setting up a basic producer-consumer framework within rabbitMQ. This is just the beginning and there are many more ways rabbitMQ can be used! For more learning opportunities check out the official rabbitMQ [Getting Started](https://www.rabbitmq.com/getstarted.html) page. + +![direct](../../data/Images/direct-exchange.jpg) + +### What is a Producer? + +A producer is a entity (object, application, etc) that creates & sends information to be distributed. In RabbitMQ producers send these messages to an exchange. You can have multiple producers which depending on the exchange will send data to 0 to N queues. For this lab we'll focus on using a single producer. Producers send messages to exchanges along with the routing key associated with that message. At a high level this routing key tells the rabbitMQ framework that the producer would like to send the associated message to queues that match a given regex string. The replication & matching of the routing key is dependant on the type of exchange (explained below). A more concrete example is, we may have a message intended for a particular set of schools that are all in the US. My routing key in that scenario would be "US" which would signal this particular message should go to queues designated as US. + +### What is a Consumer? + +A consumer is an entity (object, application, etc.) receiving information from a queue. In RabbitMQ you can have multiple queues, each with the potential for various consumers. In this lab we'll focus on setting up a queue with a single consumer. + +### Exchanges + +Exchanges are the mechanism that tells RabbitMQ how messages should be directed to a queue. You can think of an exchange like different delivery services. Delivery service **Direct Delivery!** may deliver messages to queues/locations based on particular addresses "123 My Address Road, NY, NY, 10022". This would be an example of a **direct exchange** where messages are sent to queues that have a *binding key* that exactly matches the message's *routing key*. Other exchanges also exist such as the **fanout exchange** which will replicate incoming messages to all queues bound to the exchange. An excellent example of a fanout exchange would be a chat room where an incoming message is sent to all users within the chatroom. Typically, a producer needs to be made aware of the queues or consumers attached to queues. A producer is concerned with what exchange it wants to send its message to, the distribution method of that exchange, and the routing key of the message it wants to send. + +Within Python using pika an exchange can be declared similar to the following: + +```python +#Build our connection to the RMQ Connection. +#The AMPQ_URL is a string which tells pika the package the URL of our AMPQ service in this scenario RabbitMQ. +conParams = pika.URLParameters(os.environ['AMQP_URL']) +connection = pika.BlockingConnection(parameters=conParams) +channel = connection.channel() +channel.exchange_declare('Test Exchange') + +#We can then publish data to that exchange using the basic_publish method +channel.basic_publish('Test Exchange', 'Test_route', 'Hi',...) +``` + +### Topic Exchange +A **topic exchange** route messages to one or many queues based on matching between a message routing key and the pattern that was used to bind a queue to an exchange. + +![topic](../../data/Images/topic-exchange.jpg) + + +Messages sent to a topic exchange must use a routing and binding key that are a list of words separated by dots (ex. `some.routing.key`). Topic exchanges are similar to **direct exchanges** in logic; a message sent with a particular routing key will be delivered to all the queues that are bound with a matching binding key. +- Using a `*` symbol in your binding key will substitute it with __exactly 1 word__ +- Using a `#` symbol in your binding key will substitute it with __0 or more words__ + +With Python and pika, an exchange can be declared similar to the following: +```py +# We'll first set up the connection and channel +connection = pika.BlockingConnection( + pika.ConnectionParameters(host='localhost')) +channel = connection.channel() + +# Declare the topic exchange +channel.exchange_declare(exchange='topic_logs', exchange_type='topic') + +# Set the routing key and publish a message with that topic exchange: +routing_key = sys.argv[1] if len(sys.argv) > 2 else 'anonymous.info' +message = ' '.join(sys.argv[2:]) or 'Hello World!' +channel.basic_publish( + exchange='topic_logs', routing_key=routing_key, body=message) +print(f" [x] Sent {routing_key}:{message}") +``` \ No newline at end of file diff --git a/Tech-Lab-On-Campus/market_watch/README.md b/Tech-Lab-On-Campus/Topic-Exchange/README.md similarity index 81% rename from Tech-Lab-On-Campus/market_watch/README.md rename to Tech-Lab-On-Campus/Topic-Exchange/README.md index eaeec9ee..7de48340 100755 --- a/Tech-Lab-On-Campus/market_watch/README.md +++ b/Tech-Lab-On-Campus/Topic-Exchange/README.md @@ -1,7 +1,8 @@ # Problem Definition: ✨Topic Exchange✨ ## Instructions -In this section, we will create a [Topic Exchange](../README.md#topic-exchange). For this lab, the Producer will send messages regarding the current price of a particular stock to the exchange. The Topic Exchange will then route the messages to the appropriate Queues. For instance, a specific Queue may only subscribe to messages regarding tech stocks, while another may only receive messages regarding stock in the healthcare sector. Lastly, the Consumers will read the messages from the subscribed Queue and then acknowledge and print the information. +In this section, we will create a [Topic Exchange](../Resources/RabbitMQ.md#topic-exchange). For this lab, the Producer will send messages regarding the current price of a particular stock to the exchange. The Topic Exchange will then route the messages to the appropriate Queues. For instance, a specific Queue may only subscribe to messages regarding tech stocks, while another may only receive messages regarding stock in the healthcare sector. Lastly, the Consumers will read the messages from the subscribed Queue and then acknowledge and print the information. +* If you are unfamiliar with the concept of a stock please use this resource: [Basic Financial Concepts.](../Resources/Finance.md) Below are bullet points of the criteria: @@ -32,7 +33,7 @@ Below are bullet points of the criteria: `$ python3 consumer.py -s tech` -###### [Note: Utilize the following resource to help instantiate the [Topic Exchange](https://www.rabbitmq.com/tutorials/tutorial-five-python.html)] +###### [Note: You may also utilize the following resource to help instantiate the [Topic Exchange](https://www.rabbitmq.com/tutorials/tutorial-five-python.html)] ## Testing In order to verify that this excercise was done correctly we will need to test our service. diff --git a/Tech-Lab-On-Campus/Topic-Exchange/__init__.py b/Tech-Lab-On-Campus/Topic-Exchange/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/Tech-Lab-On-Campus/market_watch/consumer_interface.py b/Tech-Lab-On-Campus/Topic-Exchange/consumer_interface.py similarity index 100% rename from Tech-Lab-On-Campus/market_watch/consumer_interface.py rename to Tech-Lab-On-Campus/Topic-Exchange/consumer_interface.py diff --git a/Tech-Lab-On-Campus/market_watch/producer_interface.py b/Tech-Lab-On-Campus/Topic-Exchange/producer_interface.py similarity index 100% rename from Tech-Lab-On-Campus/market_watch/producer_interface.py rename to Tech-Lab-On-Campus/Topic-Exchange/producer_interface.py diff --git a/Tech-Lab-On-Campus/Topic-Exchange/solution/.gitignore b/Tech-Lab-On-Campus/Topic-Exchange/solution/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/Tech-Lab-On-Campus/market_watch/stock.py b/Tech-Lab-On-Campus/Topic-Exchange/stock.py similarity index 100% rename from Tech-Lab-On-Campus/market_watch/stock.py rename to Tech-Lab-On-Campus/Topic-Exchange/stock.py diff --git a/Tech-Lab-On-Campus/consumer/README.md b/Tech-Lab-On-Campus/consumer/README.md deleted file mode 100755 index 7eb782b0..00000000 --- a/Tech-Lab-On-Campus/consumer/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Problem Definition: ✨Consumer✨ - -## Instructions -Create a .py file that will contain a class that is setup to be a consumer in the RabbitMQ framework. This class will inherit from the mqConsumerInterface and consume and print a simple UTF-8 string message. - -Below are bullet points of the criteria: -- Your class should be named mqConsumer. -- Your class should inherit from our mqConsumerInterface. -- The class name should be `mqConsumer` & the source file should be called `consumer_sol.py` -- Constructor: Save the three variables needed to instantiate the class. -- Constructor: Call the setupRMQConnection function. -- setupRMQConnection Function: Establish connection to the RabbitMQ service, declare a queue and exchange, bind the binding key to the queue on the exchange and finally set up a callback function for receiving messages -- onMessageCallback: Print the UTF-8 string message and then close the connection. -- startConsuming: Consumer should start listening for messages from the queue. - -###### [Note: Utilize the following resource to help instantiate the Producer Class: [RabbitMQ Tutorial](https://www.rabbitmq.com/tutorials/tutorial-one-python.html)] - -## Testing -In order to verify that the consumer class was properly instantiated, we will use the provided `consume.py`, and `publish.py` file from the previous section on the producer. Follow the below instructions: -1. In the terminal window, run the `publish.py` file from the producer section using the python interpreter. This will publish a message using RabbitMQ. -2. In another terminal window, run the `consumer.py` file from the consumer section using the python interpreter. This file will import your newly created class `mqConsumer` from `consumer_sol.py`. "Hello World" should now be displayed on your terminal if you instantiated & implemented the consumer class correctly. -* Note that if you are developing from the terminal in your IDE, inside the second terminal window you will need to step into the rmq_lab Docker container in order to access the python enviroment. We do this by first running the `docker exec -it [containterName\containerID] /bin/bash` command. Using the `docker ps -a` command will show all the running docker containers and their associated I.D and names. Your command could be `docker exec -it tech-lab-on-campus-rmq_lab-1 /bin/bash` or `docker exec -it 8a785d10fd7e /bin/bash` - - - diff --git a/Tech-Lab-On-Campus/validate.py b/Tech-Lab-On-Campus/validate.py deleted file mode 100644 index 2212b002..00000000 --- a/Tech-Lab-On-Campus/validate.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -# Copyright 2024 Bloomberg Finance L.P. -# -# Licensed 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. - -from producer.solution.producer_sol import mqProducer -from consumer.solution.consumer_sol import mqConsumer -from concurrent.futures import ThreadPoolExecutor - -import time - -pool_worker = ThreadPoolExecutor(max_workers=1) - -def startUpConsumer(): - consumer = mqConsumer("Test Routing Key", "Test Queue Name", "Test Exchange Name") - consumer.startConsuming() - -def runSetup(): - #Setup consumer in thread - pool_worker.submit(startUpConsumer) - producer = mqProducer("Test Routing Key", "Test Exchange Name") - time.sleep(1) - producer.publishOrder("Setup Validation Success! You're ready to start working. Press CMD/Ctrl + C to Exit") - - -if __name__ == "__main__": - runSetup() diff --git a/data/bbit_lab.PNG b/data/Images/bbit_lab.PNG similarity index 100% rename from data/bbit_lab.PNG rename to data/Images/bbit_lab.PNG diff --git a/data/bbit_lab_2.PNG b/data/Images/bbit_lab_2.PNG similarity index 100% rename from data/bbit_lab_2.PNG rename to data/Images/bbit_lab_2.PNG diff --git a/data/Images/consumerBinding.jpeg b/data/Images/consumerBinding.jpeg new file mode 100644 index 00000000..5f5c5100 Binary files /dev/null and b/data/Images/consumerBinding.jpeg differ diff --git a/data/Images/consumerQueue.jpeg b/data/Images/consumerQueue.jpeg new file mode 100644 index 00000000..e42e4a67 Binary files /dev/null and b/data/Images/consumerQueue.jpeg differ diff --git a/data/Images/copy_ssh.PNG b/data/Images/copy_ssh.PNG new file mode 100644 index 00000000..e968d3fe Binary files /dev/null and b/data/Images/copy_ssh.PNG differ diff --git a/data/Images/direct-exchange.jpg b/data/Images/direct-exchange.jpg new file mode 100644 index 00000000..1b6b041a Binary files /dev/null and b/data/Images/direct-exchange.jpg differ diff --git a/data/Images/fork-1.JPG b/data/Images/fork-1.JPG new file mode 100644 index 00000000..95daa0f8 Binary files /dev/null and b/data/Images/fork-1.JPG differ diff --git a/Tech-Lab-On-Campus/producer/message_rate.jpeg b/data/Images/message_rate.jpeg similarity index 100% rename from Tech-Lab-On-Campus/producer/message_rate.jpeg rename to data/Images/message_rate.jpeg diff --git a/data/Images/rabbit_mq.PNG b/data/Images/rabbit_mq.PNG new file mode 100644 index 00000000..effbbf9d Binary files /dev/null and b/data/Images/rabbit_mq.PNG differ diff --git a/data/Images/sys-argv-image.jpg b/data/Images/sys-argv-image.jpg new file mode 100644 index 00000000..82ea6423 Binary files /dev/null and b/data/Images/sys-argv-image.jpg differ diff --git a/data/Images/topic-exchange.jpg b/data/Images/topic-exchange.jpg new file mode 100644 index 00000000..76199b27 Binary files /dev/null and b/data/Images/topic-exchange.jpg differ diff --git a/Tech-Lab-On-Campus/consumer/solution/consumer_sol.py b/data/solutions/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consumer_sol.py similarity index 94% rename from Tech-Lab-On-Campus/consumer/solution/consumer_sol.py rename to data/solutions/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consumer_sol.py index 0b6eda76..f0d059ad 100755 --- a/Tech-Lab-On-Campus/consumer/solution/consumer_sol.py +++ b/data/solutions/Tech-Lab-On-Campus/Producer-And-Consumer/consumer/consumer_sol.py @@ -58,8 +58,10 @@ def setupRMQConnection(self) -> None: def on_message_callback( self, channel, method_frame, header_frame, body ) -> None: - # Acknowledge And Print Message + # Acknowledge Message channel.basic_ack(method_frame.delivery_tag, False) + + # Print Message print(f" [x] Received Message: {body}") # Close channel and connection @@ -67,6 +69,9 @@ def on_message_callback( self.m_connection.close() def startConsuming(self) -> None: - # Start consuming messages + + # Print " [*] Waiting for messages. To exit press CTRL+C" print(" [*] Waiting for messages. To exit press CTRL+C") + + # Start consuming messages self.m_channel.start_consuming() diff --git a/Tech-Lab-On-Campus/producer/solution/producer_sol.py b/data/solutions/Tech-Lab-On-Campus/Producer-And-Consumer/producer/producer_sol.py similarity index 100% rename from Tech-Lab-On-Campus/producer/solution/producer_sol.py rename to data/solutions/Tech-Lab-On-Campus/Producer-And-Consumer/producer/producer_sol.py diff --git a/Tech-Lab-On-Campus/market_watch/solution/sol_consumer.py b/data/solutions/Tech-Lab-On-Campus/Topic-Exchange/sol_consumer.py similarity index 100% rename from Tech-Lab-On-Campus/market_watch/solution/sol_consumer.py rename to data/solutions/Tech-Lab-On-Campus/Topic-Exchange/sol_consumer.py diff --git a/Tech-Lab-On-Campus/market_watch/solution/sol_consumer_service.py b/data/solutions/Tech-Lab-On-Campus/Topic-Exchange/sol_consumer_service.py similarity index 100% rename from Tech-Lab-On-Campus/market_watch/solution/sol_consumer_service.py rename to data/solutions/Tech-Lab-On-Campus/Topic-Exchange/sol_consumer_service.py diff --git a/Tech-Lab-On-Campus/market_watch/solution/sol_producer.py b/data/solutions/Tech-Lab-On-Campus/Topic-Exchange/sol_producer.py similarity index 100% rename from Tech-Lab-On-Campus/market_watch/solution/sol_producer.py rename to data/solutions/Tech-Lab-On-Campus/Topic-Exchange/sol_producer.py diff --git a/Tech-Lab-On-Campus/market_watch/solution/sol_producer_service.py b/data/solutions/Tech-Lab-On-Campus/Topic-Exchange/sol_producer_service.py similarity index 100% rename from Tech-Lab-On-Campus/market_watch/solution/sol_producer_service.py rename to data/solutions/Tech-Lab-On-Campus/Topic-Exchange/sol_producer_service.py