Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

challenge-bravo_Gabriel-Gimenez-De-Lima #305

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -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.*
101 changes: 40 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,61 @@
# <img src="https://avatars1.githubusercontent.com/u/7063040?v=4&s=200.jpg" alt="Hurb" width="24" /> Bravo Challenge
# Conversor de Moedas

[[English](README.md) | [Portuguese](README.pt.md)]
![Redis](https://img.shields.io/badge/redis-%23DD0031.svg?style=for-the-badge&logo=redis&logoColor=white)
![FastAPI](https://img.shields.io/badge/FastAPI-005571?style=for-the-badge&logo=fastapi)
![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54)

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: <https://pt.wikipedia.org/wiki/Currency>. Accessed on: 28 April 2021.
Playstation Store [Virtual Store]. Available at: <https://store.playstation.com/pt-br/product/UP1004-CUSA00419_00-GTAVCASHPACK000D>. 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! ;)

<p align="center">
<img src="ca.jpg" alt="Challange accepted" />
</p>
```
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.
82 changes: 0 additions & 82 deletions README.pt.md

This file was deleted.

Binary file added __pycache__/views.cpython-310.pyc
Binary file not shown.
8 changes: 8 additions & 0 deletions inputs.py
Original file line number Diff line number Diff line change
@@ -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]
45 changes: 45 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -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
Empty file added services/__init__.py
Empty file.
Binary file added services/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file added services/__pycache__/awesome_api.cpython-310.pyc
Binary file not shown.
12 changes: 12 additions & 0 deletions services/awesome_api.py
Original file line number Diff line number Diff line change
@@ -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"]


47 changes: 47 additions & 0 deletions services/redis.py
Original file line number Diff line number Diff line change
@@ -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)
Loading