diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..618899bd7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,31 @@
+# Arquivos e pastas gerados pelo Python
+__pycache__/
+*.pyc
+*.pyo
+*.pyd
+*.db
+*.sqlite3
+
+# Ambiente virtual
+venv/
+env/
+ENV/
+
+# Arquivos de log e saída
+*.log
+*.log.*
+logs/
+log.txt
+log/
+
+# Cache de dependências
+__pycache__/
+.cache/
+
+# Arquivos de configuração
+*.ini
+*.conf
+
+# Arquivos de ambiente
+.env
+.env.*
\ No newline at end of file
diff --git a/README.md b/README.md
index 22af01577..492f4e5fc 100644
--- a/README.md
+++ b/README.md
@@ -1,82 +1,61 @@
-#
Bravo Challenge
+# Conversor de Moedas
-[[English](README.md) | [Portuguese](README.pt.md)]
+
+
+
-Build an API, which responds to JSON, for currency conversion. It must have a backing currency (USD) and make conversions between different currencies with **real and live values**.
+Esse projeto é um sistema de conversão de moedas reais e ficticias.
-The API must convert between the following currencies:
+## Pré-requisitos
-- USD
-- BRL
-- EUR
-- BTC
-- ETH
+Antes de começar, certifique-se de que você tenha o seguinte software instalado em seu ambiente:
-Other coins could be added as usage.
+- Python 3.x
+- FastApi
+- Redis
-Ex: USD to BRL, USD to BTC, ETH to BRL, etc...
+## Instalação
-The request must receive as parameters: The source currency, the amount to be converted and the final currency.
+1. **Clonando o repositório**
-Ex: `?from=BTC&to=EUR&amount=123.45`
+ Clone este repositório para o seu ambiente local:
-Also build an endpoint to add and remove API supported currencies using HTTP verbs.
+ ```
+ git clone https://github.com/gabrielgimenez98/challenge-bravo.git
+ cd challenge-bravo
-The API must support conversion between FIAT, crypto and fictitious. Example: BRL->HURB, HURB->ETH
+2. **Criando Ambiente Virtual**
-"Currency is the means by which monetary transactions are effected." (Wikipedia, 2021).
+ Clone este repositório para o seu ambiente local:
-Therefore, it is possible to imagine that new coins come into existence or cease to exist, it is also possible to imagine fictitious coins such as Dungeons & Dragons coins being used in these transactions, such as how much is a Gold Piece (Dungeons & Dragons) in Real or how much is the GTA$1 in Real.
+ ```
+ python3 -m venv venv
+ source venv/bin/activate # No Windows, use "venv\Scripts\activate"
-Let's consider the PSN quote where GTA$1,250,000.00 cost R$83.50 we clearly have a relationship between the currencies, so it is possible to create a quote. (Playstation Store, 2021).
+3. **Instalando dependências**
-Ref:
-Wikipedia [Institutional Website]. Available at: . Accessed on: 28 April 2021.
-Playstation Store [Virtual Store]. Available at: . Accessed on: 28 April 2021.
+ Instale as dependências usando
-You can use any programming language for the challenge. Below is the list of languages that we here at Hurb have more affinity:
+ ```
+ pip install -r requirements.txt
+
+4. **Rodando o projeto localmente**
-- JavaScript (NodeJS)
-- Python
-- Go
-- Ruby
-- C++
-- PHP
+ ```
+ uvicorn views:app --reload
+ ```
-## Requirements
+ Após isso é possível encontrar o swagger na rota ```\docs```
-- Fork this challenge and create your project (or workspace) using your version of that repository, as soon as you finish the challenge, submit a _pull request_.
- - If you have any reason not to submit a _pull request_, create a private repository on Github, do every challenge on the **main** branch and don't forget to fill in the `pull-request.txt` file. As soon as you finish your development, add the user `automator-hurb` to your repository as a contributor and make it available for at least 30 days. **Do not add the `automator-hurb` until development is complete.**
- - If you have any problem creating the private repository, at the end of the challenge fill in the file called `pull-request.txt`, compress the project folder - including the `.git` folder - and send it to us by email.
-- The code needs to run on macOS or Ubuntu (preferably as a Docker container)
-- To run your code, all you need to do is run the following commands:
- - git clone \$your-fork
- - cd \$your-fork
- - command to install dependencies
- - command to run the application
-- The API can be written with or without the help of _frameworks_
- - If you choose to use a _framework_ that results in _boilerplate code_, mark in the README which piece of code was written by you. The more code you make, the more content we will have to rate.
-- The API needs to support a volume of 1000 requests per second in a stress test.
-- The API needs to include real and current quotes through integration with public currency quote APIs
+5. **Rodando os testes unitários**
-## Evaluation criteria
+ ```
+ pytest -s tests/
+ ```
-- **Organization of code**: Separation of modules, view and model, back-end and front-end
-- **Clarity**: Does the README explain briefly what the problem is and how can I run the application?
-- **Assertiveness**: Is the application doing what is expected? If something is missing, does the README explain why?
-- **Code readability** (including comments)
-- **Security**: Are there any clear vulnerabilities?
-- **Test coverage** (We don't expect full coverage)
-- **History of commits** (structure and quality)
-- **UX**: Is the interface user-friendly and self-explanatory? Is the API intuitive?
-- **Technical choices**: Is the choice of libraries, database, architecture, etc. the best choice for the application?
+6. **Rodando os testes de carga**
-## Doubts
-
-Any questions you may have, check the [_issues_](https://github.com/HurbCom/challenge-bravo/issues) to see if someone hasn't already and if you can't find your answer, open one yourself. new issue!
-
-Godspeed! ;)
-
-
-
-
+ ```
+ locust -f tests/stress_test.py --headless -u 1000 -r 100
+ ```
+ Os testes de carga são úteis para avaliar o desempenho da API sob carga simulada. Os parâmetros `-u` e `-r` definem o número de usuários e a taxa de aumento de usuários, respectivamente.
diff --git a/README.pt.md b/README.pt.md
deleted file mode 100644
index 0159db9f0..000000000
--- a/README.pt.md
+++ /dev/null
@@ -1,82 +0,0 @@
-#
Desafio Bravo
-
-[[English](README.md) | [Português](README.pt.md)]
-
-Construa uma API, que responda JSON, para conversão monetária. Ela deve ter uma moeda de lastro (USD) e fazer conversões entre diferentes moedas com **cotações de verdade e atuais**.
-
-A API precisa converter entre as seguintes moedas:
-
-- USD
-- BRL
-- EUR
-- BTC
-- ETH
-
-Outras moedas podem ser adicionadas conforme o uso.
-
-Ex: USD para BRL, USD para BTC, ETH para BRL, etc...
-
-A requisição deve receber como parâmetros: A moeda de origem, o valor a ser convertido e a moeda final.
-
-Ex: `?from=BTC&to=EUR&amount=123.45`
-
-Construa também um endpoint para adicionar e remover moedas suportadas pela API, usando os verbos HTTP.
-
-A API deve suportar conversão entre moedas fiduciárias, crypto e fictícias. Exemplo: BRL->HURB, HURB->ETH
-
-"Moeda é o meio pelo qual são efetuadas as transações monetárias." (Wikipedia, 2021).
-
-Sendo assim, é possível imaginar que novas moedas passem a existir ou deixem de existir, é possível também imaginar moedas fictícias como as de Dungeons & Dragons sendo utilizadas nestas transações, como por exemplo quanto vale uma Peça de Ouro (D&D) em Real ou quanto vale a GTA$ 1 em Real.
-
-Vamos considerar a cotação da PSN onde GTA$ 1.250.000,00 custam R$ 83,50 claramente temos uma relação entre as moedas, logo é possível criar uma cotação. (Playstation Store, 2021).
-
-Ref:
-Wikipedia [Site Institucional]. Disponível em: . Acesso em: 28 abril 2021.
-Playstation Store [Loja Virtual]. Disponível em: . Acesso em: 28 abril 2021.
-
-Você pode usar qualquer linguagem de programação para o desafio. Abaixo a lista de linguagens que nós aqui do Hurb temos mais afinidade:
-
-- JavaScript (NodeJS)
-- Python
-- Go
-- Ruby
-- C++
-- PHP
-
-## Requisitos
-
-- Forkar esse desafio e criar o seu projeto (ou workspace) usando a sua versão desse repositório, tão logo acabe o desafio, submeta um _pull request_.
- - Caso você tenha algum motivo para não submeter um _pull request_, crie um repositório privado no Github, faça todo desafio na branch **main** e não se esqueça de preencher o arquivo `pull-request.txt`. Tão logo termine seu desenvolvimento, adicione como colaborador o usuário `automator-hurb` no seu repositório e o deixe disponível por pelo menos 30 dias. **Não adicione o `automator-hurb` antes do término do desenvolvimento.**
- - Caso você tenha algum problema para criar o repositório privado, ao término do desafio preencha o arquivo chamado `pull-request.txt`, comprima a pasta do projeto - incluindo a pasta `.git` - e nos envie por email.
-- O código precisa rodar em macOS ou Ubuntu (preferencialmente como container Docker)
-- Para executar seu código, deve ser preciso apenas rodar os seguintes comandos:
- - git clone \$seu-fork
- - cd \$seu-fork
- - comando para instalar dependências
- - comando para executar a aplicação
-- A API pode ser escrita com ou sem a ajuda de _frameworks_
- - Se optar por usar um _framework_ que resulte em _boilerplate code_, assinale no README qual pedaço de código foi escrito por você. Quanto mais código feito por você, mais conteúdo teremos para avaliar.
-- A API precisa suportar um volume de 1000 requisições por segundo em um teste de estresse.
-- A API precisa contemplar cotações de verdade e atuais através de integração com APIs públicas de cotação de moedas
-
-## Critério de avaliação
-
-- **Organização do código**: Separação de módulos, view e model, back-end e front-end
-- **Clareza**: O README explica de forma resumida qual é o problema e como pode rodar a aplicação?
-- **Assertividade**: A aplicação está fazendo o que é esperado? Se tem algo faltando, o README explica o porquê?
-- **Legibilidade do código** (incluindo comentários)
-- **Segurança**: Existe alguma vulnerabilidade clara?
-- **Cobertura de testes** (Não esperamos cobertura completa)
-- **Histórico de commits** (estrutura e qualidade)
-- **UX**: A interface é de fácil uso e auto-explicativa? A API é intuitiva?
-- **Escolhas técnicas**: A escolha das bibliotecas, banco de dados, arquitetura, etc, é a melhor escolha para a aplicação?
-
-## Dúvidas
-
-Quaisquer dúvidas que você venha a ter, consulte as [_issues_](https://github.com/HurbCom/challenge-bravo/issues) para ver se alguém já não a fez e caso você não ache sua resposta, abra você mesmo uma nova issue!
-
-Boa sorte e boa viagem! ;)
-
-
-
-
diff --git a/__pycache__/views.cpython-310.pyc b/__pycache__/views.cpython-310.pyc
new file mode 100644
index 000000000..f97c8be0f
Binary files /dev/null and b/__pycache__/views.cpython-310.pyc differ
diff --git a/inputs.py b/inputs.py
new file mode 100644
index 000000000..13916fd92
--- /dev/null
+++ b/inputs.py
@@ -0,0 +1,8 @@
+from pydantic import BaseModel
+from typing import Optional
+
+class Currency(BaseModel):
+ currency_name: str
+ is_fictional: Optional[bool]
+ backing: Optional[str]
+ backing_amount: Optional[float]
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 000000000..26aefa280
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,45 @@
+annotated-types==0.6.0
+anyio==4.3.0
+async-timeout==4.0.3
+blinker==1.7.0
+Brotli==1.1.0
+certifi==2024.2.2
+charset-normalizer==3.3.2
+click==8.1.7
+ConfigArgParse==1.7
+exceptiongroup==1.2.0
+fastapi==0.109.2
+Flask==3.0.2
+Flask-Cors==4.0.0
+Flask-Login==0.6.3
+gevent==24.2.1
+geventhttpclient==2.0.11
+greenlet==3.0.3
+h11==0.14.0
+idna==3.6
+iniconfig==2.0.0
+itsdangerous==2.1.2
+Jinja2==3.1.3
+locust==2.23.1
+MarkupSafe==2.1.5
+msgpack==1.0.7
+packaging==23.2
+pluggy==1.4.0
+psutil==5.9.8
+pydantic==2.6.1
+pydantic_core==2.16.2
+pytest==8.0.1
+pyzmq==25.1.2
+redis==5.0.1
+requests==2.31.0
+roundrobin==0.0.4
+six==1.16.0
+sniffio==1.3.0
+starlette==0.36.3
+tomli==2.0.1
+typing_extensions==4.9.0
+urllib3==2.2.1
+uvicorn==0.27.1
+Werkzeug==3.0.1
+zope.event==5.0
+zope.interface==6.2
diff --git a/services/__init__.py b/services/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/services/__pycache__/__init__.cpython-310.pyc b/services/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 000000000..6d3d953e0
Binary files /dev/null and b/services/__pycache__/__init__.cpython-310.pyc differ
diff --git a/services/__pycache__/awesome_api.cpython-310.pyc b/services/__pycache__/awesome_api.cpython-310.pyc
new file mode 100644
index 000000000..d6be9f135
Binary files /dev/null and b/services/__pycache__/awesome_api.cpython-310.pyc differ
diff --git a/services/awesome_api.py b/services/awesome_api.py
new file mode 100644
index 000000000..b558cc1df
--- /dev/null
+++ b/services/awesome_api.py
@@ -0,0 +1,12 @@
+import requests
+
+class AwesomeApiService():
+ def __init__(self):
+ self.url = "https://economia.awesomeapi.com.br/last/"
+ def get_bid_value_from_api(self, from_currency: str, to_currency: str):
+ path = from_currency.upper() + "-" + to_currency.upper()
+ response = requests.get(self.url + path)
+ json_response = response.json()
+ return json_response[from_currency.upper()+ to_currency.upper()]["bid"]
+
+
diff --git a/services/redis.py b/services/redis.py
new file mode 100644
index 000000000..5530486e9
--- /dev/null
+++ b/services/redis.py
@@ -0,0 +1,47 @@
+import redis
+
+
+r = redis.Redis(host='localhost', port=6379, db=7, decode_responses=True)
+
+class Redis():
+ def add_currency(self, currency: dict):
+ if currency.get("is_fictional", False):
+ mounted_currency = {
+ "currency_name": currency["currency_name"].upper(),
+ "is_fictional": "True",
+ "backing": currency["backing"].upper(),
+ "backing_amount": currency["backing_amount"],
+ }
+
+ r.hmset(currency["currency_name"].upper(), mounted_currency)
+
+ currency_name_upper = currency["currency_name"].upper()
+ r.rpush("available_currencies", currency_name_upper)
+ return r.lrange("available_currencies", 0, -1)
+
+ def update_currency(self, currency: dict):
+ currency_name = currency.get("currency_name")
+ is_fictional = "True" if currency.get("is_fictional") else "False"
+ mounted_currency = {
+ "currency_name": currency["currency_name"].upper(),
+ "is_fictional": is_fictional,
+ "backing": currency["backing"].upper(),
+ "backing_amount": currency["backing_amount"],
+ }
+ r.hmset(currency_name.upper(), mounted_currency)
+
+
+ return self.get_currency(currency_name)
+
+ def get_currency(self, currency_name: str):
+
+ return r.hgetall(currency_name)
+
+ def get_avaliable_currencies(self):
+
+ return r.lrange("available_currencies", 0, -1)
+
+ def remove_currency_from_list(self, currency_name: str):
+ r.lrem("available_currencies", 0, currency_name.upper())
+
+ return r.lrange("available_currencies", 0, -1)
diff --git a/services/utils.py b/services/utils.py
new file mode 100644
index 000000000..71482307f
--- /dev/null
+++ b/services/utils.py
@@ -0,0 +1,50 @@
+from services.awesome_api import AwesomeApiService
+from services.redis import Redis
+def is_currency_fictional(currency_name: str):
+ currency = Redis().get_currency(currency_name=currency_name)
+ return currency.get("is_fictional", "false") == "True"
+
+def is_currency_avaliable (currency_name: str):
+ avaliable_currencies = Redis().get_avaliable_currencies()
+
+ return currency_name in avaliable_currencies
+
+def has_fictional_currency_flow(from_currency: str, to_currency: str, amount: int):
+ from_currency_backing,from_currency_backing_amount = _extract_backing_and_backing_amount(from_currency)
+ to_currency_backing,to_currency_backing_amount = _extract_backing_and_backing_amount(to_currency)
+ bid_value = _get_bid_value(from_currency=from_currency_backing, to_currency=to_currency_backing)
+ converted_value = ((float(bid_value) * float(from_currency_backing_amount))/float(to_currency_backing_amount)) * amount
+ output = _mount_output(float(bid_value), converted_value)
+ return output
+
+def not_fictional_currency_flow(from_currency: str, to_currency: str, amount: int):
+ bid_value = _get_bid_value(from_currency,to_currency)
+ converted_value = float(bid_value) * amount
+ output = _mount_output(float(bid_value), converted_value)
+ return output
+
+def _get_bid_value(from_currency: str, to_currency: str):
+ try:
+ awesome_api_service = AwesomeApiService()
+ bid_value = awesome_api_service.get_bid_value_from_api(from_currency=from_currency, to_currency=to_currency)
+ return bid_value
+ except Exception as e:
+ raise e
+
+def _extract_backing_and_backing_amount(currency_name):
+ currency = Redis().get_currency(currency_name=currency_name)
+
+ if not currency.get("is_fictional", "false") == "True":
+ return currency_name,1
+
+ return currency.get("backing"), currency.get("backing_amount")
+
+def _mount_output(bid_value:float, converted_value: float):
+ return {
+ "bid_value": bid_value,
+ "converted_value": converted_value,
+ }
+
+
+
+
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/stress_test.py b/tests/stress_test.py
new file mode 100644
index 000000000..df1b86c8f
--- /dev/null
+++ b/tests/stress_test.py
@@ -0,0 +1,9 @@
+from locust import HttpUser, between, task
+
+class MyUser(HttpUser):
+ wait_time = between(0.1, 0.5)
+ host = "http://localhost:8000"
+
+ @task
+ def my_task(self):
+ self.client.get("/convert?from_currency=USD&to_currency=BRL&amount=2")
\ No newline at end of file
diff --git a/tests/test_utils.py b/tests/test_utils.py
new file mode 100644
index 000000000..5fd5a4658
--- /dev/null
+++ b/tests/test_utils.py
@@ -0,0 +1,55 @@
+from unittest import TestCase
+from unittest.mock import patch
+from services.utils import is_currency_avaliable, is_currency_fictional, has_fictional_currency_flow, not_fictional_currency_flow
+
+class TestTasks(TestCase):
+
+ @patch("services.utils.Redis")
+ def test_is_currency_fictional(self,mock_redis):
+ mock_redis.return_value.get_currency.return_value = {'currency_name': 'TESTE', 'is_fictional': 'True', 'backing': 'NOT', 'backing_amount': '1.0'}
+ response = is_currency_fictional("TESTE")
+ self.assertEqual(response,True)
+
+ @patch("services.utils.Redis")
+ def test_is_currency_fictional_false(self,mock_redis):
+ mock_redis.return_value.get_currency.return_value = {'currency_name': 'TESTE', 'is_fictional': 'false', 'backing': 'NOT', 'backing_amount': '1.0'}
+ response = is_currency_fictional("TESTE")
+ self.assertEqual(response,False)
+
+ @patch("services.utils.Redis")
+ def test_is_currency_avaliable(self,mock_redis):
+ mock_redis.return_value.get_avaliable_currencies.return_value = ["TESTE"]
+ response = is_currency_avaliable("TESTE")
+ self.assertEqual(response,True)
+
+ @patch("services.utils.Redis")
+ def test_is_currency_avaliable_false(self,mock_redis):
+ mock_redis.return_value.get_avaliable_currencies.return_value = ["TESTE222"]
+ response = is_currency_avaliable("TESTE")
+ self.assertEqual(response,False)
+
+ @patch("services.utils.Redis")
+ def test_is_currency_avaliable_false(self,mock_redis):
+ mock_redis.return_value.get_avaliable_currencies.return_value = ["TESTE222"]
+ response = is_currency_avaliable("TESTE")
+ self.assertEqual(response,False)
+
+ @patch("services.utils.AwesomeApiService")
+ def test_not_fictional_flow(self,mock_api):
+ expected_response = {
+ "bid_value": 1,
+ "converted_value": 1,
+ }
+ mock_api.return_value.get_bid_value_from_api.return_value = 1
+ response = not_fictional_currency_flow("TESTE","TESTE",1)
+ self.assertEqual(response,expected_response)
+
+ @patch("services.utils.AwesomeApiService")
+ def test_fictional_flow(self,mock_api):
+ expected_response = {
+ "bid_value": 1,
+ "converted_value": 1,
+ }
+ mock_api.return_value.get_bid_value_from_api.return_value = 1
+ response = has_fictional_currency_flow("TESTE","TESTE",1)
+ self.assertEqual(response,expected_response)
diff --git a/tests/test_views.py b/tests/test_views.py
new file mode 100644
index 000000000..21fb0e688
--- /dev/null
+++ b/tests/test_views.py
@@ -0,0 +1,43 @@
+from unittest import TestCase
+from unittest.mock import patch
+from inputs import Currency
+from views import create_currency, convert, delete_currency
+
+class TestTasks(TestCase):
+
+ @patch("views.Redis")
+ def test_create_currency(self,mock_redis):
+ currency = Currency(currency_name="TESTE",is_fictional="True", backing="NOT", backing_amount="1.0")
+ mock_redis.return_value.add_currency.return_value = ["TESTE"]
+ response = create_currency(currency)
+ self.assertEqual(response[0],["TESTE"])
+
+ @patch("views.is_currency_avaliable")
+ @patch("views.is_currency_fictional")
+ @patch("views.has_fictional_currency_flow")
+ def test_convert(self,mock_has_fictional_currency_flow,mock_is_currency_fictional, mock_is_currency_avaliable):
+ mock_has_fictional_currency_flow.return_value = {
+ "bid_value": 1,
+ "converted_value": 1,
+ }
+ mock_is_currency_fictional.return_value = True
+ mock_is_currency_avaliable.return_value = True
+ response = convert(from_currency="TESTE", to_currency="TESTE", amount=1)
+ expected_response = {
+ "bid_value": 1,
+ "converted_value": 1,
+ }
+ self.assertEqual(response[0],expected_response)
+
+ @patch("views.Redis")
+ def test_edit_currency(self,mock_redis):
+ currency = Currency(currency_name="TESTE",is_fictional="True", backing="NOT", backing_amount="1.0")
+ mock_redis.return_value.add_currency.return_value = {'currency_name': 'TESTE', 'is_fictional': 'True', 'backing': 'NOT', 'backing_amount': '1.0'}
+ response = create_currency(currency)
+ self.assertEqual(response[0],{'currency_name': 'TESTE', 'is_fictional': 'True', 'backing': 'NOT', 'backing_amount': '1.0'})
+
+ @patch("views.Redis")
+ def test_delete_currency(self,mock_redis):
+ mock_redis.return_value.remove_currency_from_list.return_value = ["TESTE2"]
+ response = delete_currency(currency_name="TESTE")
+ self.assertEqual(response[0],["TESTE2"])
diff --git a/views.py b/views.py
new file mode 100644
index 000000000..61974b620
--- /dev/null
+++ b/views.py
@@ -0,0 +1,42 @@
+import json
+from fastapi import FastAPI
+from inputs import Currency
+
+from services.redis import Redis
+from services.utils import is_currency_avaliable, is_currency_fictional, has_fictional_currency_flow, not_fictional_currency_flow
+
+app = FastAPI()
+
+@app.get("/convert")
+def convert(from_currency: str, to_currency:str, amount: float):
+ if not is_currency_avaliable(from_currency) or not is_currency_avaliable(to_currency):
+ return {"message": "Moedas não disponíveis, por favor insira no banco de dados"}, 404
+ if is_currency_fictional(from_currency) or is_currency_fictional(to_currency):
+ output = has_fictional_currency_flow(from_currency=from_currency, to_currency=to_currency, amount=amount)
+ else:
+ output = not_fictional_currency_flow(from_currency=from_currency, to_currency=to_currency, amount=amount)
+
+
+ return output, 200
+
+@app.post("/currency")
+def create_currency(request: Currency):
+
+ payload = json.loads(request.json())
+ redis_service = Redis()
+ response = redis_service.add_currency(payload)
+ return response, 200
+
+@app.put("/currency")
+def edit_currency(request: Currency):
+
+ payload = json.loads(request.json())
+ redis_service = Redis()
+ response = redis_service.update_currency(payload)
+ return response, 200
+
+@app.delete("/currency")
+def delete_currency(currency_name: str):
+ redis_service = Redis()
+ response = redis_service.remove_currency_from_list(currency_name)
+ return response, 200
\ No newline at end of file