Howto relation of data in Python (pickle datas)? - python

I'm new in python environment,
so I created an example small project to try this:
creating of phone brand and save into brands.pkl
text fields: "brand name"
creating of phone model with selecting a brand from previous created brand via dropdown
and save into models.pkl
text fields: phone name
dropdown: brand from created.
But I haven't found a solution to relation it (in sql I can use foreign key by id).
Thank you.
Here is my example code:
def phones(self):
saved_phones= util.load_phones()
return json.dumps(saved_phones)
#cherrypy.expose
def new_brands(self, *args, **kwargs):
try:
saved_brands = util.load_brands()
brand = {'name': kwargs['brand_name']}
try:
brand['id'] = saved_brands[-1]['id'] + 1
except IndexError:
brand['id'] = 1
saved_brands.append(brand)
util.save_brands(saved_brands)
return json.dumps(brand)
except Exception as e:
return json.dumps({'error': str(e)})
#cherrypy.expose
def new_phones(self, *args, **kwargs):
try:
saved_phones = util.load_phones()
phone = {'model': kwargs['phone_model']}
try:
phone['id'] = saved_module[-1]['id'] + 1
except IndexError:
phone['id'] = 1
saved_phones.append(phone)
util.save_phones(saved_phones)
return json.dumps(phone)
except Exception as e:
return json.dumps({'error': str(e)})
def save_phones(phones):
pickle.dump(phones, open('phones.pkl', 'wb'))
def load_phones():
try:
saved_phones = pickle.load(open('phones.pkl', 'rb'))
except IOError:
saved_phones = []
return saved_phones
def get_modul(phones, phone_id):
for phone in phones:
if phone['id'] == phone_id:
return phone
# if
# for
return None
def save_brands(brands):
pickle.dump(brands, open('brands.pkl', 'wb'))
def load_brands():
try:
saved_brands = pickle.load(open('brands.pkl', 'rb'))
except IOError:
saved_brands = []
return saved_brands
def get_modul(brands, brand_id):
for brand in brands:
if brand['id'] == brand_id:
return brand
# if
# for
return None

pickle might be a lousy fit for the problem you seem to be trying to solve. pickle makes some sense when you want to persist or transmit a bundle of related objects all in one shot.
maybe you really do want a sql database? sqlite3 bindings are provided with python out of the box, and you can transition to a more robust database when the time comes with minimal effort.

Related

Hi ! need help in choice of class with a customer - appointment table

I'm trying to build a "customer" menu textbased to make automatic appointments and manage conflicts. I'm using Python but so far I've been using procedural programming (I'm a newbie), but it's getting too complicated to maintain. I would like to use a CSV file to keep all the contact (up to a thousand) and calcurse to manage my calendar.
Basically, I would like to check if the contact is approved and then send him my availabilities. I try to use the datefinder module to get a date & time, check if available, and ask for the order.
I'd like to know what class I need to create:
import csv
import datetime
import time
class Contact:
def __init__(self, index, name, last_time, last_level='unreliable', appdate=None, apporder=None, appnote=None):
self.index = index
self.name = name
self.last_time = last_time #last time I received a message from this person to unlogg if it's
over 5min agoo
self.last_level = last_level # can be unreliable,main,date,order,note as
# unreliable= don't even send availibities
# main=the person is logged send availibities
# date=ask for date, order=ask for order, note=ask for note
self.appdate = datetime.datetime.strptime(appdate, '%Y-%m-%d %H:%M').date()
self.apporder = apporder
self.appnote = appnote
class Appointment:
# I'd like to create a class for all the appointments from the calcurse file listing all the appointments to be able to check for instances if any conflicts with any new appointments.
def __init__(self, name, appdate, apporder, appnote):
self.name = name
self.appdate = datetime.datetime.strptime(appdate, '%Y-%m-%d %H:%M')
self.apporder = apporder
self.appnote = appnote
def find_contact_in_file(name):
try:
with open("contact", 'r') as csvfile:
reader = csv.reader(csvfile)
index = 0
for line in reader:
index += 1
if line[0] == name:
print(index, line)
contact = Contact(index, line[0], line[1], line[2], line[3], line[4], line[5])
return contact
return contact.Contact(index + 1, name, int(time.time()), "unreliable", None, None, None)
except IOError:
print("I/O error")
Do I need a class Reply to make the reply from the message I get from the customer?

Attribute Error Nonetype has o attribute 'Name'

new to flask, i'm not so sure why I am getting this name error: 'Nontype' object has no attribute value 'name'.
(PLease ignore: "It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
")
Here is what it looks like in the console
File "/Users/thomashunt/projects/ct-platform-api/apis/student_api.py", line 448, in put
return StudentService.student_WorkShadow(submission)
File "/Users/thomashunt/projects/ct-platform-api/services/students.py", line 234, in student_WorkShadow
AddressService.set_address_info(submission.student_detail.location_address)
File "/Users/thomashunt/projects/ct-platform-api/services/addresses.py", line 18, in set_address_info
address_description = address.address_description(country.name)
AttributeError: 'NoneType' object has no attribute 'name'
services/students
#staticmethod
def student_WorkShadow(submission: StudentWorkShadowEdit) -> Person:
repo = PersonData()
advisor = repo.find_by_email(submission.advisor_email)
email = submission.email.lower()
student = repo.find_by_email(email)
if not student:
raise RecordNotFoundException('No Record with this email in the database')
if not advisor:
raise RecordNotFoundException('No Record with this advisor email in the database')
# Forced re-write of Address entered by Student
student.student_detail.location_address = \
AddressService.set_address_info(submission.student_detail.location_address)
submission.set_model(student)
files = StudentService.promote_student_files(advisor, submission.file_ids, student.id)
# Forced re-write of Address entered by Student
repo.save(student, advisor.id)
repo.session.commit()
student_statement = 'student workshadow details updated'
reference_fields = [EventItemReferenceField('updated_workshadowDetails', 'Updated workshadow Details'),
EventItemReferenceField('form_action', 'confidential_updated')]
reference_content = [student_statement]
MessagingActivityService.create_student_event_for_action(student.id, None, student,
True,
ActionTypes.Student.value.InternalNote,
student_statement,
reference_fields,
reference_content, files, None,
None, None, True, True)
StudentService.re_index(student)
return student
API Endpoints
#ns.route('/StudentWorkShadow')
class StudentWorkShadowEndpoint(Resource):
#SecurityService.requires_system
#ns.expect(student_workshadow_model, validate=True)
#ns.marshal_with(student_person_model)
def put(self):
logging.info('student workshadow details updated')
submission = StudentWorkShadowEdit.from_dict(request.json)
return StudentService.student_WorkShadow(submission)
services/address
import logging
from models import Address
from resources import AddressEdit
from utility import GoogleUtility
from .data import CountryData
class AddressService:
#staticmethod
def set_address_info(address: Address):
countries = CountryData()
country = countries.load_country(address.country_code)
if address.suburb is not None and address.state is not None:
address.location_description = address.suburb + ', ' + address.state
address_description = address.address_description(country.name)
maps_result = GoogleUtility.resolve_coords(address_description)
try:
first_result = maps_result[0]
print(first_result)
address.latitude = first_result['geometry']['location']['lat']
address.longitude = first_result['geometry']['location']['lng']
address.raw_location = first_result
address.formatted_address = first_result['formatted_address']
except TypeError:
print(maps_result.error)
logging.error(maps_result.error)
except IndexError:
logging.error('No result for address resolution')
return address
#staticmethod
def has_address_changed(old_address: Address, new_address: AddressEdit):
if not old_address and new_address:
return True
return not (old_address.line_1 == new_address.line_1
and old_address.line_2 == new_address.line_2
and old_address.suburb == new_address.suburb
and old_address.postcode == new_address.postcode
and old_address.country_code == new_address.country_code)
country/data outputs:
import json
from resources import Country
class CountryData:
with open('services/data/countries.json') as json_data:
source = json.load(json_data)
countries = [Country.from_dict(l) for l in source]
def load_country(self, country_code: str):
result = None
for country in self.countries:
if country.country_code == country_code:
result = country
return result
def load_state(self, country_code: str, short_title: str):
result = None
country = self.load_country(country_code)
for state in country.states:
if state.short_title == short_title:
result = state
return result
def list_states(self, country_code: str):
return self.load_country(country_code).states
My suspicion is that the value you pass for country_code does not match against any country.country_code attribute.
My advice is to put a debug print line in the method like this:
class CountryData:
...
def load_country(self, country_code: str):
result = None
for country in self.countries:
if country.country_code == country_code:
result = country
print(result, country.country_code) # this line added
return result
...
Doing this, you should be able to see if result is ever set to a value other than None, and you can observe exactly which country code triggers it. Moreover, this will print all available country codes (one per line). If your country_code is not one of these, that is the problem.

Custom Python Model constructor

I have built a custom model that allows me to save to Airtable from a MySQL query. The goal is to pass the base name and key from a loop of base keys and table names, and have the model use the save function which was working before the last adjustment. I cannot figure out what the change was, I have commented out everything but:
daily_kpi=Daily_KPI(base_key=base['base_key'], table_name=base['table_name'])
And I still get an error.
class Daily_KPI(at.AT):
base_key=None
table_name='Daily'
#Fields
#property
def ID(self):
dt=datetime.strptime(self.date, '%Y-%m-%d').strftime('%m/%d/%y')
return str(dt)+" "+self.sku+" "+self.account
date=at.ATField(field_name="date", at_field_name="Date")
asin=at.ATField(field_name="asin", at_field_name="ASIN")
account=at.ATField(field_name="account", at_field_name="Account")
# country=at.ATField(field_name="country", at_field_name="Country")
sessions=at.ATField(field_name="sessions", at_field_name="Sessions")
session_pct=at.ATField(field_name="session_pct", at_field_name="Session Pct")
page_views=at.ATField(field_name="page_views", at_field_name="Page Views")
page_view=at.ATField(field_name="page_view", at_field_name="Page View")
buy_box=at.ATField(field_name="buy_box", at_field_name="Buy Box")
units_ordered=at.ATField(field_name="units_ordered", at_field_name="Units Ordered")
units_ord_b2b=at.ATField(field_name="units_ord_b2b", at_field_name="Units Ord B2B")
unit_session=at.ATField(field_name="unit_session", at_field_name="Unit Session")
ord_prod=at.ATField(field_name="ord_prod", at_field_name="Ord Prod")
ord_prod_b2b=at.ATField(field_name="ord_prod_b2b", at_field_name="Ord Prod B2B")
tot_ord_items=at.ATField(field_name="tot_ord_items", at_field_name="Tot Ord Items")
tot_ord_b2b=at.ATField(field_name="tot_ord_b2b", at_field_name="Tot Ord B2B")
bsr=at.ATField(field_name="bsr", at_field_name="B.S.R")
actual_sales=at.ATField(field_name="actual_sales", at_field_name="Actual Sales")
selling_price=at.ATField(field_name="selling_price", at_field_name="Selling Price")
notes=at.ATField(field_name="notes", at_field_name="Notes")
unit_sess_b2b=at.ATField(field_name="unit_sess_b2b", at_field_name="Unit Sess B2B")
sku=at.ATField(field_name="sku", at_field_name="SKU")
def __init__(self, base_key, table_name):
super(Daily_KPI, self).__init__(base_key=base_key, table_name=table_name)
When I try to use the model,
def save_data(self):
try:
print ('hello')
#wp_table=Airtable(BASE_KEY, 'Weekly Profitability Development copy', API_KEY)
results = self.results
print(len(results))
for base in settings.DAILY_AIRTABLE:
for row in self.results:
try:
daily_kpi=Daily_KPI(base_key=base['base_key'], table_name=base['table_name'])
daily_kpi.date=str(date.today())
# daily_kpi.sku = row['ItemSKU']
# daily_kpi.asin = row['ASIN']
# daily_kpi.account = row['Account']
# daily_kpi.sessions = row['Sessions']
# daily_kpi.session_pct = row['Session_Pct']
# daily_kpi.page_view = row['Page_Views']
# daily_kpi.page_view_pct = row['Page_Views_Pct']
# daily_kpi.buy_box = row['Buy_Box_Pct']
# daily_kpi.units_ordered = row['Units_Ordered']
# daily_kpi.units_ordered_b2b = row['Units_Ordered_B2B']
# daily_kpi.unit_session_pct=row['Unit_Session_Pct']
# daily_kpi.unit_session_pct_b2b= row['Unit_Session_Pct_B2B']
# daily_kpi.ord_prod=row['Ordered_Product_Sales']
# daily_kpi.ord_prod_b2b=row['Ordere_Product_Sales_B2B']
# daily_kpi.tot_ord_items=row['Total_Order_Items']
# daily_kpi.tot_ord_b2b=row['Total_Order_Items_B2B']
# daily_kpi.bsr=row['BSR']
# daily_kpi.actual_sales
# daily_kpi.selling_price
# daily_kpi.notes
# daily_kpi.unit_sess_b2b
# daily_kpi.sku
daily_kpi.save()
except Exception as e:
print(e)
I get error: super() argument 1 must be type, not classobj
I am not quite sure how to adjust the constructor so that it accepts the parameters and creates an object. I tried
def __init__(self, base_key, table_name):
super(Daily_KPI, self).__init__(self, base_key=base_key, table_name=table_name)
I made a simple airtable Pytbon client. It would be fairly easy to do what you described with it:
https://github.com/gtalarico/airtable-python-wrapper

More elegant way to deal with multiple KeyError Exceptions

I have the following function, which reads a dict and affects some values to local variables, which are then returned as a tuple.
The problem is that some of the desired keys may not exist in the dictionary.
So far I have this code, it does what I want but I wonder if there is a more elegant way to do it.
def getNetwork(self, search):
data = self.get('ip',search)
handle = data['handle']
name = data['name']
try:
country = data['country']
except KeyError:
country = ''
try:
type = data['type']
except KeyError:
type = ''
try:
start_addr = data['startAddress']
except KeyError:
start_addr = ''
try:
end_addr = data['endAddress']
except KeyError:
end_addr = ''
try:
parent_handle = data['parentHandle']
except KeyError:
parent_handle = ''
return (handle, name, country, type, start_addr, end_addr, parent_handle)
I'm kind of afraid by the numerous try: except: but if I put all the affectations inside a single try: except: it would stop to affect values once the first missing dict key raises an error.
Just use dict.get. Each use of:
try:
country = data['country']
except KeyError:
country = ''
can be equivalently replaced with:
country = data.get('country', '')
You could instead iterate through the keys and try for each key, on success append it to a list and on failure append a " ":
ret = []
for key in {'country', 'type', 'startAddress', 'endAddress', 'parentHandle'}:
try:
ret.append(data[key])
except KeyError:
ret.append([" "])
Then at the end of the function return a tuple:
return tuple(ret)
if that is necessary.
Thx ShadowRanger, with you answer I went to the following code, which is indeed more confortable to read :
def getNetwork(self, search):
data = self.get('ip',search)
handle = data.get('handle', '')
name = data.get('name', '')
country = data.get('country','')
type = data.get('type','')
start_addr = data.get('start_addr','')
end_addr = data.get('end_addr','')
parent_handle = data.get('parent_handle','')
return (handle, name, country, type, start_addr, end_addr, parent_handle)

Separating "user-owned" from "other" data in Django template

I have an Openstack-powered, Django-modified application that shows the disk images and snapshots available for a user to launch. The user currently sees both snapshots they created and ones they did not. I would like to separate the current table into two based on whether they are owned by the user or not.
My two table definitions are as follows (note I altered row_actions accordingly):
class UserSnapshotsTable(OldSnapshotsTable):
cloud = tables.Column(get_cloud, verbose_name=_("Cloud"))
class Meta:
name = "usersnapshots"
verbose_name = _("User Snapshots")
table_actions = (DeleteSnapshot,)
row_actions = (LaunchSnapshot, LaunchCluster, EditImage, DeleteSnapshot)
pagination_param = "snapshot_marker"
row_class = UpdateRow
status_columns = ["status"]
class OtherSnapshotsTable(OldSnapshotsTable):
cloud = tables.Column(get_cloud, verbose_name=_("Cloud"))
class Meta:
name = "othersnapshots"
verbose_name = _("Other Snapshots")
table_actions = (DeleteSnapshot,)
row_actions = (LaunchSnapshot, LaunchCluster)
pagination_param = "snapshot_marker"
row_class = UpdateRow
status_columns = ["status"]
I have altered the HTML template to pull the "UserSnapshotsTable" and "OtherSnapshotsTable" tables (I copied the original table and renamed both), but both full tables still generate under the respective headings. There are two functions generating the data:
def get_usersnapshots_data(self):
req = self.request
marker = req.GET.get(UserSnapshotsTable._meta.pagination_param, None)
try:
usersnaps, self._more_snapshots = api.snapshot_list_detailed(req,
marker=marker)
except:
usersnaps = []
exceptions.handle(req, _("Unable to retrieve user-owned snapshots."))
return usersnaps
def get_othersnapshots_data(self):
req = self.request
marker = req.GET.get(OtherSnapshotsTable._meta.pagination_param, None)
try:
othersnaps, self._more_snapshots = api.snapshot_list_detailed(req,
marker=marker)
except:
othersnaps = []
exceptions.handle(req, _("Unable to retrieve non-user-owned snapshots."))
return othersnaps
There are also Edit/Delete options defined for images, and imported for snapshots, that seem to have a key comparison. Here's the "Delete" one (line 7):
class DeleteImage(tables.DeleteAction):
data_type_singular = _("Image")
data_type_plural = _("Images")
def allowed(self, request, image=None):
if image:
return image.owner == request.user.tenant_id
# Return True to allow table-level bulk delete action to appear.
return True
def delete(self, request, obj_id):
api.image_delete(request, obj_id)
How can I separate those tables out? This is my first time asking a question here, so please let me know if I can provide further information. Apologies for the length of it.
As far as I see you are using glanceclient. If that so you can use extra_filters parameter of snapshot_list_detailed() to filter only user images like this:
usersnaps, self._more_snapshots = api.snapshot_list_detailed(
req,
marker = marker,
extra_filters = {"owner": "user_name"}
)
Under cover snapshot_list_detailed uses GET images of Openstack Image Service API.

Categories