Django Currency Conversion - python

Is there any facility in Django for doing currency conversions? Obviously, rates change day by day but I'm somewhat hopeful that the locale module has some sort of web-service based converter.
There's a snippet here that handles the formatting: http://www.djangosnippets.org/snippets/552/ But I need to localize the values first.

Probably more elegant ways to do this, but it works.
currency_in = 'USD'
currency_out = 'NOK'
import urllib2
req = urllib2.urlopen('http://finance.yahoo.com/d/quotes.csv?e=.csv&f=sl1d1t1&s='+currency_in+currency_out+'=X')
result = req.read()
# result = "USDNOK=X",5.9423,"5/3/2010","12:39pm"
Then you can split() the result for the modifier.

# Install google-currency package
# pip install google-currency
>>> from google_currency import convert
>>> convert('usd', 'bdt', 1)
Output:
{"from": "USD", "to": "BDT", "amount": "85.30", "converted": true}

You could use django-money app for currency conversions in Django-based projects.
It works with different rate sources and provides an interface to perform conversions & money localization:
>>> # After app setup & adding rates to the DB
>>> from djmoney.money import Money
>>> from djmoney.contrib.exchange.models import convert_money
>>> value = Money(100, 'EUR')
>>> converted = convert_money(value, 'USD')
>>> converted
<Money: 122.8184375038380800 USD>
>>> str(converted)
US$122.82
Formats are easily customizable, you could find the documentation on the project page.

You can use django-money to handle money values including the conversion of currencies as shown below. *The example below converts 100 USD to ... EUR:
# "views.py"
from django.http import HttpResponse
from app.models import MyModel
from djmoney.contrib.exchange.models import convert_money
from djmoney.money import Money
def test(request):
print(convert_money(Money(100, 'USD'), 'EUR')) # Here
return HttpResponse("Test")
You can see my answer and django-money doc which explain more about how to convert currencies.

Related

Requests Library in Python - Params Structure to Merge two json bodies

I am building a project to import crypto prices in json format that I can later parse out.
Now I have been researching and I haven't found a sure way to combine these two statements together so I can do one call instead of two. I want to do BTC and ETH like you see in one "req_params" I just dont know what the right syntax is a lot of the sites have confusing material.
import requests
import json
from datetime import datetime,timedelta
base_url = 'https://api.kucoin.com/api/v1/market/candles'
start_timestmp = datetime.strptime("2021-11-11T11:11:11","%Y-%m-%dT%H:%M:%S")
end_timestmp = start_timestmp + timedelta(minutes=1)
# How do I combine these two stamens into one call ?
req_params = {'symbol':'BTC-USDT','type':'1min',
'startAt':int(datetime.timestamp(start_timestmp)),
'endAt': int(datetime.timestamp(end_timestmp))
}
req_params2 = {'symbol':'ETH-USDT','type':'1min',
'startAt':int(datetime.timestamp(start_timestmp)),
'endAt': int(datetime.timestamp(end_timestmp))
}
url_response = requests.get(url=base_url,params=req_params)
url_response2 = requests.get(url=base_url,params=req_params2)
response_json = url_response.json()
response_json2 = url_response2.json()
# put the response in json format
closing_price = float(response_json['data'][0][2])
print(response_json)
print(response_json2)
print(closing_price)

Returning the time and date of a sent email - IMAP

New to python and I've been trying to create a program that returns the time a specific email was received and couldn't find a function anywhere that did so. (So far I've checked reddit, Stack Overflow and Automate the Boring stuff) I've been able to return the body of the email with the below but couldn't find anything on whether or not I can extract only the time from emails. Any help on if this is possible and how it can be done would be greatly appreciated.
Thanks
password = input('Enter your password')
import imapclient
server = imapclient.IMAPClient('imap-mail.outlook.com', ssl=True)
server.login('myemail#msn.com',password)
import pprint
pprint.pprint(server.list_folders())
server.select_folder('Inbox')
rawMessage = server.fetch(40111, ['BODY[]'])
import pyzmail
message = pyzmail.PyzMessage.factory(rawMessage[40111][b'BODY[]'])
messagebodyTEXT = message.text_part.get_payload().decode(message.text_part.charset)
print(messagebodyTEXT)
The library that you're using is talking the IMAP protocol. In IMAP, there's no such thing as a "time when a message was received". There's a timestamp on when that message was "stored into the mailbox (INTERNALDATE)", but that's a something else in the generic case.
You could also try to parse the Received headers which might (or might not) contain the information that you're looking for.
I see you're using the pyzmail third-party library, but did you know there's an extensive email module in the Python standard library?
Specifically I think the parser is what you'll want for extracting timestamps:
https://docs.python.org/3/library/email.parser.html
building on previous comments and answers regarding INTERNALDATE, here is the code snippet I used to retrieve the delivered date and transform it to a datetime object, with the imaplib library:
>>> import imaplib
>>> connection = imaplib.IMAP4_SSL('yourimapserver')
>>> response = connection.login('youremailaddress', 'password')
>>> connection.select('INBOX')
>>> status, data = connection.fetch(b'1', '(INTERNALDATE)') # b"1" is your uid
From there, different options depending on:
the format of the datetime your imap server provides,
whether you need a timezone aware object.
timezone naive
>>> import datetime
>>> import time
>>> data[0]
b'1 (INTERNALDATE "12-Aug-2020 16:38:19 +0200")'
>>> timestruct = imaplib.Internaldate2tuple(data[0])
>>> timestruct
time.struct_time(tm_year=2020, tm_mon=8, tm_mday=12,tm_hour=16, tm_min=38, tm_sec=19, tm_wday=2, tm_yday=225, tm_isdst=1)
>>> datetime_delivered = datetime.fromtimestamp(mktime(timestruct))
>>> datetime_delivered
datetime.datetime(2020, 8, 12, 16, 38, 19)
timezone aware (Python 3.2+)
>>> import email
>>> str_datetime = data[0].decode().split('"')[1]
>>> str_datetime
"12-Aug-2020 16:38:19 +0200"
>>> timezone_aware = email.utils.parsedate_to_datetime(str_datetime)
>>> timezone_aware
datetime.datetime(2020,8, 12, 16, 38, 19, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200)))

Run Python script in Django template through a button

I have a very small project in Django where I get fx_rates through a Python script (details below). These are used to convert amounts in different currencies to GBP. I would like to know how I can just have a button on the website that allows to refresh this query instead of having to run it manually in the IDE. Can I create a view for this? How would I show this in a template? Thanks
fx_rates.py
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','fx_rates_project.settings')
import django
django.setup()
from fx_rates_app.models import fx_table
import pandas_datareader.data as web
from datetime import datetime
os.environ["ALPHAVANTAGE_API_KEY"] = '#########'
fx_gbp_to_eur = web.DataReader("GBP/EUR","av-forex")
eur = float(fx_gbp_to_eur[4:5].values[0][0])
fx_gbp_to_aud = web.DataReader("GBP/AUD","av-forex")
aud = float(fx_gbp_to_aud[4:5].values[0][0])
fx_gbp_to_usd = web.DataReader("GBP/USD","av-forex")
usd = float(fx_gbp_to_usd[4:5].values[0][0])
from datetime import datetime
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
webpg1 = fx_table.objects.get_or_create(eur_to_gbp=eur,aud_to_gbp=aud,usd_to_gbp=usd,date_time=dt_string)[0]
In the template I included:
<form method="post">
{% csrf_token %}
<button type="submit" name="run_script">Refresh</button>
</form>
However, I don't think the best way to do this would be to copy the all script in views with request.POST. Is there another way to leave the script in another file and just create a view to run it (e.g. if request.method == 'POST' run fx_rates.py)?
This can be definitely done by creating a function update_fx to wrap your script and then call that function in your view.
Now for the tricky part.
Do you need the values to render them or just to update them?
Rendering will be easy, just return them from your function and you will
be able to use them in your template.
This though includes the waiting time to fetch these values. When your view will be executed you will have to wait for the function to fetch the values.
The alternative is to "trigger" a second job that updates the values from your
view. This pattern is called a task queue and there are many solutions that you can leverage already, depending on how complicated things should be (what happens if the job has an error? how many times should we retry? ...).
This also has the unfortunate effect that now you run a second python script somewhere that listens for new tasks and executes them.
As always your choice is based on tradeoffs, personally if the server has good internet connection and the request is completed fast I would not mind putting it
in my view as is.
Hope this is helpful.
Let's see an example
# update.py
from fx_rates_app.models import fx_table
import pandas_datareader.data as web
from django.conf import settings
from datetime import datetime
import os
def get_price():
os.environ["ALPHAVANTAGE_API_KEY"] = '#########'
fx_gbp_to_eur = web.DataReader("GBP/EUR","av-forex") # here we are reading stuff from the network I guess
eur = float(fx_gbp_to_eur[4:5].values[0][0])
fx_gbp_to_aud = web.DataReader("GBP/AUD","av-forex")
aud = float(fx_gbp_to_aud[4:5].values[0][0])
fx_gbp_to_usd = web.DataReader("GBP/USD","av-forex")
usd = float(fx_gbp_to_usd[4:5].values[0][0])
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
# here you have two choices,
# either you return the raw values
# or you put them into a model
return {
'timestamp': dt_string,
'value': 1,
'currency': 'gbp',
'eur': eur,
'aud': aud,
'us': us,
}
webpg1 = fx_table.objects.get_or_create(eur_to_gbp=eur,aud_to_gbp=aud,usd_to_gbp=usd,date_time=dt_string)[0]
return webpg1
# views.py
from django.http import HttpResponse
from update import get_price
def refresh_from_values(request):
data = get_price() # here we don't have a model, just data
webpg1 = fx_table.objects.get_or_create(
eur_to_gbp=data['eur'],
aud_to_gbp=data['aud'],
usd_to_gbp=data['usd'],
date_time=data['timestamp'],
)[0]
# here your render the model using the template
def refresh_from_model(request):
fx = get_price() # here we get back the model instead
# you can render again the model as you can refresh the page
In the future you might be interested in running this thing continuously
and then you would have to move to an event driven app which is more compilicated but can be very satisfying to get right. In django everything
would start with signals and more likely you would have to write some javascript to
update part of the page without refreshing it.

Problem publishing JSON output to PubSub. A 'u' is being added to every field

I have a script that pulls from the city if Chicago and grabs a json file and then published to Pub Sub. Once the data gets into pub sub I have a dataflow template that pulls the data into Google Big Query. The final data move to BQ is failing and when I print the output in the script. I am getting a u' in front of all the fields which I believe is messing up the field match. Has anyone else had this issue and know what is wrong with my code and how to possibly remove the 'u'. I have tried multiple fix but none of them have worked. A sample out put is listed below:
('_last_updt', '2010-07-21 14:50:53.0'), ('_length', '0.69'), ('_lif_lat', '41.985032613'),
My code is listed below:
from __future__ import unicode_literals
from sodapy import Socrata
import json
from io import StringIO
from google.oauth2 import service_account
from oauth2client.client import GoogleCredentials
from google.cloud import pubsub_v1
import time
import datetime
import urllib
import urllib.request
import argparse
import base64
credentials = GoogleCredentials.get_application_default()
# change project to your Project ID
project="xxxx"
# change topic to your PubSub topic name
topic="xxxx"
res = urllib.request.urlopen('https://data.cityofchicago.org/resource/8v9j-bter.json')
res_body = res.read()
traffic=json.loads(res_body)
publisher = pubsub_v1.PublisherClient()
topicName = 'projects/' + project + '/topics/' + topic
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path(project,topic)
for key in traffic:
publisher.publish(topicName,str.encode(str(key)))
print(key.items())
You are describing a Python construction: Unicode strings are shown with a u' prefix.
See:
What's the u prefix in a Python string?
For example, building an array with a "normal" string and an unicode one:
>>> [u'a', 'a']
[u'a', 'a']
Don't worry too much about it, they are identical strings:
>>> u'a' == 'a'
True
Now when you say "I am getting a u' in front of all the fields which I believe is messing up the field match." Where do you see this? Is this part of the Python code, or do you see these u' show up on the BigQuery web UI too?
Looking at the code you posted, is seems to be forcing all strings to be Unicode with from __future__ import unicode_literals:
>>> "a"
'a'
>>> from __future__ import unicode_literals
>>> "a"
u'a'
https://python-future.org/unicode_literals.html

Trying to Parse JSON date to POST to another System (Python)

I am trying to write a script to GET project data from Insightly and post to 10000ft. Essentially, I want to take any newly created project in one system and create that same instance in another system. Both have the concept of a 'Project'
I am extremely new at this but I only to GET certain Project parameters in Insightly to pass into the other system (PROJECT_NAME, LINKS:ORGANIZATION_ID, DATE_CREATED_UTC) to name a few.
I plan to add logic to only POST projects with a DATE_CREATED_UTC > yesterday, but I am clueless on how to setup the script to grab the JSON strings and create python variables (JSON datestring to datetime). Here is my current code. I am simply just printing out some of the variables I require to get comfortable with the code.
import urllib, urllib2, json, requests, pprint, dateutil
from dateutil import parser
import base64
#Set the 'Project' URL
insightly_url = 'https://api.insight.ly/v2.1/projects'
insightly_key =
api_auth = base64.b64encode(insightly_key)
headers = {
'GET': insightly_url,
'Authorization': 'Basic ' + api_auth
}
req = urllib2.Request(insightly_url, None, headers)
response = urllib2.urlopen(req).read()
data = json.loads(response)
for project in data:
project_date = project['DATE_CREATED_UTC']
project_name = project['PROJECT_NAME']
print project_name + " " + project_date
Any help would be appreciated
Edits:
I have updated the previous code with the following:
for project in data:
project_date = datetime.datetime.strptime(project['DATE_CREATED_UTC'], '%Y-%m-%d %H:%M:%S').date()
if project_date > (datetime.date.today() - datetime.timedelta(days=1)):
print project_date
else:
print 'No New Project'
This returns every project that was created after yesterday, but now I need to isolate these projects and post them to the other system
Here is an example of returning a datetime object from a parsed string. We will use the datetime.strptime method to accomplish this. Here is a list of the format codes you can use to create a format string.
>>> from datetime import datetime
>>> date_string = '2014-03-04 22:30:55'
>>> format = '%Y-%m-%d %H:%M:%S'
>>> datetime.strptime(date_string, format)
datetime.datetime(2014, 3, 4, 22, 30, 55)
As you can see, the datetime.strptime method returns a datetime object.

Categories