0% found this document useful (0 votes)
60 views22 pages

Build Microservices With Python. This Article Aims To Outline The Basics - by Ashish MJ - Dev Genius

This article outlines how to build microservices with Python. It discusses microservices architecture and differences from monoliths. It provides an example of building a DealBazaar application with four microservices: a portal service, product management service, order management service, and notification gateway service.

Uploaded by

walteravelin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views22 pages

Build Microservices With Python. This Article Aims To Outline The Basics - by Ashish MJ - Dev Genius

This article outlines how to build microservices with Python. It discusses microservices architecture and differences from monoliths. It provides an example of building a DealBazaar application with four microservices: a portal service, product management service, order management service, and notification gateway service.

Uploaded by

walteravelin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Get unlimited access to the best of Medium for less than $1/week.

Become a member

Build Microservices with Python


Ashish MJ · Follow
Published in Dev Genius · 4 min read · Nov 28, 2023

1.3K 8

Build Microservices with Python

This article aims to outline the basics of Microservices based architecture


and learn how to build microservices with Python.

What is Microservices Based Architecture ?


It is an architectural style that structures a complex software system as a set Top highlight

of loosely coupled services and communicates with one another through


predefined standard (API’s). This style of architecture offers benefits such as
agility, scalability, and the ability to adapt to changing business
requirements.

Difference Between Monolith and Microservices Architecture ?


Microservices

Microservices VS Monolithic

Getting Started
We will create a simple project by building an application(DealBazaar) that
allows users to place an order and view an order. So we will have 4 services
namely —

Portal Service — A service that just renders the html content and routes
the api to other services (this service doesn’t connect to any DB)

Product Management — A service that allows creation and retrieval of


products

Order Management — A service that allows creation and retrieval of


order

Notification Gateway — A service that allows to send the notification


(email)
DealBazaar

Product Management

Product Management API’s and Model

Order Management
Order Management API’s and Model

Notification Gateway
Notification Gateway API and Models

Portal Service

Portal Service API’s

GET / home and GET /viewOrder API’s just render the html page without the
calls to other services.
GET /order API

POST /order API

POST /viewOrder API

1. Setup- Installations and Downloads


Download the couchbase server community version. Post download,
create a new cluster with 3 new buckets and 3 users. Give bucket names
and usernames of your choice and use the same names (bucketname ,
username and password) in .env file. In my case —

Couchbase setup details

Login / Signup on Mailjet website and generate the API key and API
secret . Same will be used to send the mail post order submit . Replace
the values in the .env file of notification gateway service

Install flask, mailjet_rest,couchbase, load_dotenv, flask-restx

2. Code
cb.py- script for all db operations and common for all the service

1 from couchbase.auth import PasswordAuthenticator


2 from couchbase.cluster import Cluster
3 from couchbase.diagnostics import PingState
4 from couchbase.exceptions import (
5 CouchbaseException,
6 DocumentExistsException,
7 DocumentNotFoundException,
8 )
9 from couchbase.options import ClusterOptions
10
11 class CouchbaseClient(object):
12 def __init__(self, host, bucket, scope, collection, username, pw):
13 self.host = host
14 self.bucket_name = bucket
15 self.collection_name = collection
16 self.scope_name = scope
17 self.username = username
18 self.password = pw
19
20 def connect(self, **kwargs):
21
22 conn_str = f"couchbase://{self.host}"
23 try:
24 cluster_opts = ClusterOptions( authenticator=PasswordAuthenticator(self.username, self.password) )
25 self._cluster = Cluster(conn_str, cluster_opts, **kwargs)
26 except CouchbaseException as error:
27 print(f"Could not connect to cluster. Error: {error}")
28 raise
29 self._bucket = self._cluster.bucket(self.bucket_name)
30 self._collection = self._bucket.scope(self.scope_name).collection(self.collection_name)
31
32 def get(self, key):
33 return self._collection.get(key)
34
35 def insert(self, key, doc):
36 return self._collection.insert(key, doc)
37
38 def upsert(self, key, doc):
39 return self._collection.upsert(key, doc)
40
41 def remove(self, key):
42 return self._collection.remove(key)
43
44 def query(self, strQuery, *options, **kwargs):
45 return self._cluster.query(strQuery, *options, **kwargs)

cb.py hosted with ❤ by GitHub view raw

cb.py

app.py- Product Management

1 import os
2 import uuid
3 from datetime import datetime
4 from dotenv import load_dotenv,find_dotenv
5 from couchbase.exceptions import (
6 CouchbaseException,
7 DocumentExistsException,
8 DocumentNotFoundException,
9 )
10 from src.cb import CouchbaseClient
11 from flask import Flask, request, jsonify
12 from flask_restx import Api, Resource, fields
13
14 app = Flask(__name__)
15
16 env_path = "./src/.env"
17 load_dotenv(env_path)
18
19 api = Api(app)
20 nsProduct = api.namespace("api/v1/products", "CRUD operations for Product")
21
22 productInsert = api.model(
23 "ProductInsert",
24 {
25 "productName": fields.String(required=True, description="Product Name"),
26 "productId": fields.String(required=True, description="Product's Unique ID"),
27 "price": fields.Float(required=True, description="Product Price"),
28 "tax": fields.Float(required=True, description="Product tax percentage"),
29 "description": fields.String(required=False, description="Description of product"),
30 "status": fields.String(required=True, description="Product Status"),
31 "url" : fields.String(required=True, description="Image Url of the Product")
32 },
33 )
34
35 product = api.model(
36 "Product",
37 {
38 "id": fields.String(required=True, description="Product's system generated Id"),
39 "productName": fields.String(required=True, description="Product Name"),
40 "productId": fields.String(required=True, description="Product's Unique ID"),
41 "price": fields.Float(required=True, description="Product Price"),
42 "tax": fields.Float(required=True, description="Product tax percentage"),
43 "description": fields.String(required=False, description="Description of product"),
44 "status": fields.String(required=True, description="Product Status"),
45 "url" : fields.String(required=True, description="Image Url of the Product"),
46 "createdAt" : fields.String(required=True, description="Time product is created")
47 },
47 },
48 )
49
50 @nsProduct.route("")
51 class Products(Resource):
52 # tag::post[]
53 @nsProduct.doc(
54 "Create Product",
55 reponses={201: "Created", 409: "Key alreay exists", 500: "Unexpected Error"},
56 )
57 @nsProduct.expect(productInsert, validate=True)
58 @nsProduct.marshal_with(product)
59 def post(self):
60 try:
61 data = request.json
62 id = uuid.uuid4().__str__()
63 data["id"] = id
64 data["createdAt"] = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
65 cb.insert(id, data)
66 return data, 201
67 except DocumentExistsException:
68 return "Key already exists", 409
69 except CouchbaseException as e:
70 return f"Unexpected error: {e}", 500
71 except Exception as e:
72 return f"Unexpected error: {e}", 500
73
74 @nsProduct.doc(
75 "Find Products",
76 reponses={200: "found", 500: "Unexpected Error"},
77 params={
78 "status": "Product is ACTIVE/INACTIVE"
79 },
80 )
81 def get(self):
82 try:
83 status = request.args.get("status","ACTIVE")
84 query = f"SELECT p.* FROM {db_info['bucket']}.{db_info['scope']}.{db_info['collection']} p WHERE p
85 result = cb.query(query, status=status)
86 products = [x for x in result]
87 return products, 200
88 except Exception as e:
89 return f"Unexpected error: {e}", 500
90
91 @nsProduct.route("/<productId>")
92 class ProductId(Resource):
93 @nsProduct.doc(
94 "Get Profile",
95 reponses={200: "Document Found", 404: "Document Not Found", 500: "Unexpected Error"},
96 )
97 def get(self, productId):
98 try:
99 query = f"SELECT p.* FROM {db_info['bucket']}.{db_info['scope']}.{db_info['collection']} p WHERE p
100 result = cb.query(query,productId=productId)
101 return list(result)[0] ,200
102 except DocumentNotFoundException:
103 return "Key not found", 404
104 except CouchbaseException as e:
105 return f"Unexpected error: {e}", 500
106
107 db_info = {
108 "host": os.getenv("DB_HOST"),
109 "bucket": os.getenv("BUCKET"),
110 "scope": os.getenv("SCOPE"),
111 "collection": os.getenv("COLLECTION"),
112 "username": os.getenv("USERNAME"),
112 "username": os.getenv("USERNAME"),
113 "password": os.getenv("PASSWORD"),
114 }
115
116 cb = CouchbaseClient(*db_info.values())
117 cb.connect()
118
119 if __name__ == "__main__":
120 app.run(debug=True,port=5002)

app.py hosted with ❤ by GitHub view raw

app.py- Product Management

app.py- Notification Gateway

1 import os
2 import uuid
3 from datetime import datetime
4 from dotenv import load_dotenv
5 from couchbase.exceptions import DocumentExistsException
6 from src.cb import CouchbaseClient
7 from flask import Flask, request
8 from flask_restx import Api, Resource, fields
9
10 from mailjet_rest import Client
11
12 app = Flask(__name__)
13
14 env_path = "./src/.env"
15 load_dotenv(env_path)
16
17 senderMail = os.getenv("SENDER_MAIL")
18 mailjet = Client(auth=(os.getenv("API_KEY"), os.getenv("API_SECRET")), version='v3.1')
19 api = Api(app)
20 nsProduct = api.namespace("api/v1/email", "Send Email")
21
22 emailInsert = api.model(
23 "emailInsert",
24 {
25 "orderId": fields.String(required=True, description="Order ID"),
26 "name": fields.String(required=True, description="Name of Customer"),
27 "mailId": fields.String(required=True, description="Mail Id of customer"),
28 "totalCost" : fields.Float(required=True, description="Total cost of order"),
29 },
30 )
31
32 emailResponse = api.model(
33 "emailResponse",
34 {
35 "id": fields.String(required=True, description="Audit for email sent"),
36 "orderId": fields.String(required=True, description="Order ID"),
37 "mailId": fields.String(required=True, description="Mail Id of customer"),
38 "status" : fields.String(required=True, description="Email Status"),
39 "deliveredAt" : fields.String(required=True, description="Time email is delivered"),
40 "statusCode" : fields.Integer(required=True, description="Status code of SMTP")
41 },
42 )
43
44
45 @nsProduct.route("/sendMail")
46 class Email(Resource):
47 # tag::post[]
48 @nsProduct.doc(
49 "Send Email",
50 reponses={200: "Success", 500: "Unexpected Error"},
51 )
52 @nsProduct.expect(emailInsert, validate=True)
53 @nsProduct.marshal_with(emailResponse)
54 def post(self):
55 reqData = request.json
56 print(reqData)
57 data = {
58 'Messages': [
59 {
60 "From": {
61 "Email": senderMail,
62 "Name": senderMail
63 },
64 "To": [
65 {
66 "Email": reqData["mailId"],
67 "Name": reqData["name"]
68 }
69 ],
70 "Subject": "Greetings from DealBazaar",
71 "TextPart": f"Your Order {reqData['orderId']} successfully placed !",
72 "HTMLPart": f"<h3>Dear {reqData['name']} , Your order {reqData['orderId']} is successful
73 }
74 ]
75 }
76 response = {}
77 rep = mailjet.send.create(data=data)
78 if rep.status_code==200:
79 response["status"] = "SUCCESS"
80 response["deliveredAt"] = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
81 else:
82 response["status"] = "FAILURE"
83 response["deliveredAt"] = None
84 id = uuid.uuid4().__str__()
85 response["id"] = id
86 response["mailId"] = reqData["mailId"]
87 response["orderId"] = reqData["orderId"]
88 response["statusCode"] = rep.status_code
89 try :
90 cb.insert(id, response)
91 return response, 202
92 except DocumentExistsException:
93 return "Key already exists", 409
94 except Exception as e:
95 return f"Unexpected error: {e}", 500
96
97 db_info = {
98 "host": os.getenv("DB_HOST"),
99 "bucket": os.getenv("BUCKET"),
100 "scope": os.getenv("SCOPE"),
101 "collection": os.getenv("COLLECTION"),
102 "username": os.getenv("USERNAME"),
103 "password": os.getenv("PASSWORD")
104 }
105
106 cb = CouchbaseClient(*db_info.values())
107 cb.connect()
108
109 if __name__ == "__main__":
110 app.run(debug=True,port=5004)

app.py hosted with ❤ by GitHub view raw


app.py- Notification Gateway

app.py- Order Management

1 import os
2 import uuid
3 import requests
4 from datetime import datetime
5 from dotenv import load_dotenv
6 from couchbase.exceptions import (
7 CouchbaseException,
8 DocumentExistsException,
9 DocumentNotFoundException,
10 )
11 from src.cb import CouchbaseClient
12 from flask import Flask, request
13 from flask_restx import Api, Resource, fields
14
15 app = Flask(__name__)
16
17 env_path = "./src/.env"
18 load_dotenv(env_path)
19
20 api = Api(app)
21 nsOrder = api.namespace("api/v1/orders", "CRUD operations for Orders")
22
23 contact = api.model(
24 "Contact",
25 {
26 "name": fields.String(required=True, description="Customer Name"),
27 "emailId": fields.String(required=True, description="emailId of customer"),
28 "phone": fields.String(required=True, description="Phone number of customer"),
29 "address": fields.String(required=True, description="Address of customer")
30 },
31 )
32
33 product = api.model(
34 "Product",
35 {
36 "productName": fields.String(required=True, description="Product Name"),
37 "productId": fields.String(required=True, description="Product's Unique ID"),
38 "price": fields.Float(required=True, description="Product Price"),
39 "tax": fields.Float(required=True, description="Product tax percentage"),
40 "quantity" : fields.Integer(required=True,description="Item count")
41 },
42 )
43
44 orderInsert = api.model(
45 "orderInsert",
46 {
47 "orderItems": fields.List(fields.Nested(product)),
48 "contact": fields.Nested(contact)
49 },
50 )
51
52 order = api.model(
53 "Order",
54 {
55 "id": fields.String(required=True, description="Product's system generated Id"),
56 "orderId": fields.String(required=True, description="Order Id"),
57 "orderItems": fields.List(fields.Nested(product)),
58 "contact": fields.Nested(contact),
59 "totalCost": fields.Float(required=True, description="Total cost of order"),
59 "totalCost": fields.Float(required=True, description="Total cost of order"),
60 "submittedAt" : fields.String(required=True, description="Time order is submitted"),
61 },
62 )
63
64 @nsOrder.route("/submitOrder")
65 class Orders(Resource):
66
67 @nsOrder.doc(
68 "Create Product",
69 reponses={200: "Success", 409: "Key alreay exists", 500: "Unexpected Error"},
70 )
71 @nsOrder.expect(orderInsert, validate=True)
72 @nsOrder.marshal_with(order)
73 def post(self):
74 try:
75 data = request.json
76 print(data)
77 data["id"] = uuid.uuid4().__str__()
78 data["submittedAt"] = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
79 orderId = cb.get(os.getenv("ORDERID_KEY"))
80 cb.upsert( os.getenv("ORDERID_KEY"), orderId.value+1)
81 orderId = "ORD-"+str(orderId.value)
82 data["orderId"] = orderId
83 totalCost=0
84 for cost in data["orderItems"]:
85 totalCost += (cost["price"] * cost["quantity"]) + (cost["price"] * (cost["tax"])/100) * cost["qu
86 data["totalCost"] = totalCost
87 cb.insert(orderId, data)
88 requestData={}
89 requestData["orderId"] = data["orderId"]
90 requestData["name"] = data["contact"]["name"]
91 requestData["mailId"] = data["contact"]["emailId"]
92 requestData["totalCost"] = data["totalCost"]
93 url = "http://"+os.getenv("NG_BASEURL")+":"+os.getenv("NG_PORT")+os.getenv("NG_URL")
94 response = requests.post(url,json=requestData)
95 return data, 200
96 except DocumentExistsException:
97 return "Key already exists", 409
98 except CouchbaseException as e:
99 return f"Unexpected error: {e}", 500
100 except Exception as e:
101 return f"Unexpected error: {e}", 500
102
103 @nsOrder.route("/<orderId>")
104 class ProductId(Resource):
105 @nsOrder.doc(
106 "Get Profile",
107 reponses={200: "Document Found", 404: "Document Not Found", 500: "Unexpected Error"},
108 )
109 def get(self, orderId):
110 try:
111 result = cb.get(orderId)
112 return result.value ,200
113 except DocumentNotFoundException:
114 return "Key not found", 404
115 except CouchbaseException as e:
116 return f"Unexpected error: {e}", 500
117
118 db_info = {
119 "host": os.getenv("DB_HOST"),
120 "bucket": os.getenv("BUCKET"),
121 "scope": os.getenv("SCOPE"),
Search Write
122 "collection": os.getenv("COLLECTION"),
123 "username": os.getenv("USERNAME"),
124 "password": os.getenv("PASSWORD"),
124 "password": os.getenv("PASSWORD"),
125 }
126
127 cb = CouchbaseClient(*db_info.values())
128 cb.connect()
129 try:
130 cb.get(os.getenv("ORDERID_KEY"))
131 except DocumentNotFoundException:
132 cb.insert(os.getenv("ORDERID_KEY"),int(os.getenv("ORDERID_BASE")))
133
134 if __name__ == "__main__":
135 app.run(debug=True,port=5003)

app.py hosted with ❤ by GitHub view raw

app.py- Order Management

app.py- Portal Service

1 import os
2 from dotenv import load_dotenv
3 import requests
4 from flask import Flask, request, jsonify,render_template
5
6 app = Flask(__name__)
7
8 env_path = "./src/.env"
9 load_dotenv(env_path)
10
11
12 @app.route('/')
13 @app.route('/home')
14 def home():
15 return render_template('home.html')
16
17
18 @app.route('/order',methods=['GET','POST'])
19 def order():
20 url = "http://" + os.getenv("PM_BASEURL") + ":" + os.getenv("PM_PORT") + os.getenv("PM_GETPRODUCT_URL")
21 response = requests.get(url).json()
22 if request.method == 'POST':
23 data={}
24 orderItems = []
25 contact = {}
26 for item in response:
27 orderItem ={}
28 if int(request.form[item['productId']]):
29 orderItem["quantity"] = int(request.form[item['productId']])
30 orderItem["productName"] = item["productName"]
31 orderItem["price"] = item["price"]
32 orderItem["productId"] = item["productId"]
33 orderItem["tax"] = item["tax"]
34 orderItems.append(orderItem)
35
36 contact["name"] = request.form["name"]
37 contact["address"] = request.form["address"]
38 contact["emailId"] = request.form["email"]
39 contact["phone"] = request.form["mobile"]
40 data["orderItems"] = orderItems
41 data["contact"] = contact
42
43 url = "http://" + os.getenv("OM_BASEURL") + ":" + os.getenv("OM_PORT") + os.getenv("OM_SUBMITORDER_URL")
44 response = requests.post(url, json=data)
45 return render_template('orderView.html',data=response.json())
46 return render_template('order.html',data=response)
47
48 @app.route('/viewOrder',methods=['GET','POST'])
49 def viewOrder():
50 if request.method == 'POST':
51 orderId = request.form['orderId']
52 url = "http://" + os.getenv("OM_BASEURL") + ":" + os.getenv("OM_PORT") + os.getenv("OM_GETORDER_URL") + o
53 response = requests.get(url).json()
54 return render_template('orderView.html',data=response)
55 return render_template('view.html')
56
57 if __name__ == "__main__":
58 app.run(debug=True,port=5001)

app.py hosted with ❤ by GitHub view raw

app.py- Portal Service

3. Run
Make sure you are running each service on a different port . In my case —

Service and port on which it is running

Run each of the services using the below command

python app.py

Open a terminal and lets create few products by executing the below curl

curl -H 'Content-Type: application/json' -d '{ "productName":"Neutron Gen Track","productId":"DV0001", "pr

curl -H 'Content-Type: application/json' -d '{ "productName":"Proton Gen Track","productId":"DV0002", "pri

1342734683/photo/an-accessory-for-men.jpg?s=612x612&w=0&k=20&c=KRrVxbNC34_dGQZmB7GmihvTB30S]z2oKNs5RLrlsBQ=" •"status":"ACTIVE"}»

ohtt:/cathost:502/ap/u/produet://media.stockphoto.com/d/
IN-C02FD6T3ML7H:~ashish.mj$curl-H'Content-Type:application/son'-d'{"productName":"NeutronGenTrack","productId":"DV0001", "price":15000

"id":"9147ea02-2e81-4bb2-8c2d-69961430b2f3",
"productName":"NeutronGenTrack",
"productId":"DV0001",
"price":15000.0,
"tax":18.9,
"description":null,
//d.istockphoto.com/10/1342734683/photo/an-acessory-for-men.g
"createdAt":"27/11/202300:31:56"
6122612020
016 512651500
IN-C02D6T3ML7H:~ashish.mj$curl-H'Content-Type:application/json'-d'{"productName":"ProtonGenTrack","productId":"DV0002",

"id":"467400a0-8095-40c-9ca4-117276ab2c7b*,
"productName":"ProtonGenTrack",
"productid":"DV0002",
"price":10000.0,
"tax":10.0,
"description":nu11,
"status":"ACTIVE",
"url":"https://cdn1.ethoswatches.com/media/catalog/product/cache/5b6ffe97254a86fab5749cb594365e70/h/u/hublot-shaped-821-ox-0180-rx.jpg",
"createdAt":"27/11/202300:33:08"

Curl execution for product creation


Open any browser and type http:://127.0.0.1:5001/. The home page of the
DealBazaar will be rendered.

Home page- DealBazaar

3. Sanity Test
Submit an order- Click on Order Now button in the home page and select
the products , quantity , fill in the details (name , address , email phone )
and click on submit button
Submitting an order
Results of Order submission

View an order- Click on View Order button in the home page and enter
the orderId and click on search button
View an order

Conclusion
In this story, we have seen the basics of microservices architecture and
learnt how to build microservices using python in simple steps. Hope
everything is clear !

Thanks for reading!

Github Website Linkedin

Additional Resource
Flask

Rest API’s

Python Microservices Flask Microservice Architecture Rest Api


Written by Ashish MJ Follow

632 Followers · Writer for Dev Genius

A Software Engineer with a demonstrated history of working in the IT .A keen learner, who
always strives to feed curiosity and learn about new technologies.

More from Ashish MJ and Dev Genius

Ashish MJ in Dev Genius Anusha SP in Dev Genius

Mastering ELK with Python Java 8 Coding and Programming


This article aims to outline the basics of ELK Interview Questions and Answers
(Elasticsearch, Logstash, Kibana) stack and It has been 8 years since Java 8 was released.
learn to integrate ELK stack with python.. I have already shared the Java 8 Interview
Questions and Answers and also Java 8
5 min read · Mar 24, 2024 6 · Jan 31, 2023
min readAPI…
Stream

194 904 11

Tomas Svojanovsky in Dev Genius Ashish MJ in Dev Genius

Pytest Fixtures: Your Secret Implementing gRPC In Python


Weapon for Writing Powerful Tests This article aims to outline the basics of gRPC
Exploring Pytest Fixtures: Setup, Teardown, and create a simple project by building
Scopes, and Best Practices endpoints using gRPC.

· 6 min read · Apr 15, 2024 4 min read · Feb 1, 2024

381 4 574 3

See all from Ashish MJ See all from Dev Genius


Recommended from Medium

Jason Roell in Stackademic Tushar Aggarwal in Python in Plain English

Ultimate Python Cheat Sheet: 101 Python Automation Scripts:


Practical Python For Everyday Streamlining Tasks and Boosting
Tasks
(My Other Ultimate Guides) Productivity
#1 of 101-Awesome Python Guides by Tushar
Aggarwal

34 min read · Jan 29, 2024 106 min read · Apr 12, 2024

4.5K 39 1.1K 7

Lists

Coding & Development Predictive Modeling w/


11 stories · 605 saves Python
20 stories · 1181 saves

Practical Guides to Machine ChatGPT


Learning 21 stories · 629 saves
10 stories · 1426 saves
Liu Zuo Lin Dario Radečić in Towards Data Science

You’re Decent At Python If You Can Python One Billion Row Challenge
Answer These 7 Questions —From 10 Minutes to 4 Seconds
Correctly
# No cheating pls!! The one billion row challenge is exploding in
popularity. How well does Python stack up?

· 6 min read · Mar 6, 2024 · 10 min read · 5 days ago

3.8K 20 1.99K 31

Aserdargun Alexander obidiegwu

Advanced OOP in Python 10 Hard Python Projects For


Classes and objects: Class instantiation, self, Intermediates To Boost Your
data attributes, UML, methods, __str__, Python Skills
Timeline to finish & Portfolio.
each project—1 month
__repr__
72 min read · Jan 14, 2024 5 min read · Dec 25, 2023

1.2K 15 1.1K 6

See more recommendations

Help Status About Careers Blog Privacy Terms Text to speech Teams

You might also like