SlideShare une entreprise Scribd logo
1  sur  100
Télécharger pour lire hors ligne
Ring
OOP
user item .

user_add_item(user, item) 

.

user_delete_item user_clear_items .

user.add_item(item) .
user item 

.

user.get_items() 

user.get_cached_items(storage) .

item . .

user.invalidate_items() user.delete_cached_items(storage)

.

Ring user.get_items.delete() .
• Ring .

• .

.
?
?
Ring
? ?
=
?
• 

• 

• 

• :




• IO ...
• IO ...
• IO ...
decorator
decorator
decorator
decorator
decorator


pure function
• 

“ 

. (... ...) .” 

( ) -
• 

“ 

. (... ...) .” 

( ) -
# 60 * 15
# cache_page: Django HTTP decorator
# 60 * 15
PyCon Django , ?
# cache_page: Django HTTP decorator
# 60 * 15
PyCon Django , ?
..?
# cache_page: Django HTTP decorator
Ring
Ring
• Sub-function control
• Methods & descriptor support

• Key Consistency

• Backend: memcache, redis, diskcache, shelve, dict

• asyncio support

• Fully customizable

• Django integration
Sub-functions
•
import ring
@ring.dict({})
def function(v):
return ...
import functools
@functools.lru_cache()
def function(v)
return ...
Ring lru_cache
Sub-functions
•
from django… 
import cache_page
@cache_page(60)
def view(request):
return ...
import ring
@ring.dict(
{}, expire=60)
def function(v):
return ...
Ring Django per-view cache
Sub-functions
• 

• &
value = function(10) value = function(10)
import ring
@ring.dict({})
def function(v):
return ...
import functools
@functools.lru_cache()
def function(v)
return ...
Ring lru_cache
Sub-functions
• • python-memcached
function.delete(10)
key = create_key(10)
client.delete(key)
Sub-functions
• • python-memcached
key = create_key(10)
value = function(10)
client.set(key)
value = 
function.update(10)
Sub-functions
• & • python-memcached
value = function(10)



value = function
.get_or_update(10)
key = create_key(10)
value = client.get(key)
if value is None:
value = function(10)
client.set(key)
Sub-functions
• & 

• 

• 

• 

• 

• ...
value = function(10)
function.delete(10)
value = function.update(10)
value = function.execute(10)
value = function.get(10)
Sub-functions
• Django
Sub-functions
• Django
Sub-functions
• get_many

• set_many, update_many, get_or_update_many …
@ring.memcache(...)
def f(a, b):
...
# getting data for f(1, 2), f(1, 3), f(a=2, b=2)
data = f.get_many((1, 2), (1, 3), {'a': 2, 'b': 2})
# data sequence(list)
Sub-functions
• get_many

• set_many, update_many, get_or_update_many …
@ring.memcache(...)
def f(a, b):
return a * 100 + b
# getting data for f(1, 2), f(1, 3), f(a=2, b=2)
data = f.get_many((1, 2), (1, 3), {'a': 2, 'b': 2})
assert data == [102, 103, 202]
Sub-functions
• get_many

• execute_many, set_many, update_many, get_or_update_many …,
@ring.memcache(...)
def f(a, b):
return a * 100 + b
# getting data for f(1, 2), f(1, 3), f(a=2, b=2)
data = f.get_many((1, 2), (1, 3), {'a': 2, 'b': 2})
assert data == [102, 103, 202]
Sub-functions
• ( ) 

• 

• ( ) namespace
Ring
• Sub-function control

• Methods & descriptor support
• Key Consistency

• Backend: memcache, redis, diskcache, shelve, dict

• asyncio support

• Fully customizable

• Django integration
Methods & Descriptors
class UserAPI(object):
url_prefix = 'https://...'
secret_key = '...'
def __init__(self, user_id):
self.user_id = user_id
# cache?
@classmethod
def api_status(cls):
return request(
f'{cls.url_prefix}/status')
# cache?
def get_user(self, n):
return request(
f'{cls.url_prefix}/users/{n}')
Methods & Descriptors
• ?

• ( )

• 

• In-house 

class UserAPI(object):
url_prefix = 'https://...'
secret_key = '...'
def __init__(self, user_id):
self.user_id = user_id
# cache?
@classmethod
def api_status(cls):
return request(
f'{cls.url_prefix}/status')
# cache?
def get_user(self, n):
return request(
f'{cls.url_prefix}/users/{n}')
Methods & Descriptors
• Ring:
class UserAPI(object):
url_prefix = 'https://...'
secret_key = '...'
def __init__(self, user_id):
self.user_id = user_id
@ring.dict({}, expire=5)
@classmethod
def api_status(cls):
return request(
f'{cls.url_prefix}/status')
@ring.dict({}, expire=60)
def get_user(self, n):
return request(
f'{cls.url_prefix}/users/{n}')
Methods & Descriptors
• Ring: 

• (free) function

• method

• classmethod

• staticmethod

• property

• custom descriptors

• hybridmethod?
hybridproperty?

• descriptor
class UserAPI(object):
url_prefix = 'https://...'
secret_key = '...'
def __init__(self, user_id):
self.user_id = user_id
@ring.dict({}, expire=5)
@classmethod
def api_status(cls):
return request(
f'{cls.url_prefix}/status')
@ring.dict({}, expire=60)
def get_user(self, n):
return request(
f'{cls.url_prefix}/users/{n}')
Methods & Descriptors
• Q: Ring method/descriptor ?
Methods & Descriptors
• Q: Ring method/descriptor ?

• A: https://github.com/youknowone/wirerope
Ring
• Sub-function control

• Methods & descriptor support

• Key Consistency
• Backend: memcache, redis, diskcache, shelve, dict

• sync/asyncio support

• Fully customizable

• Django integration
Key consistency
• 

• (expire, invalidate)
Key consistency
• 

• (expire, invalidate)
function(1)
function(v=1)
?
@functools.lru_cache(

maxsize=64)
def function(v):
return ...
Key consistency
• 

• (expire, invalidate)
function(1)
function(v=1)@functools.lru_cache(

maxsize=64)
def function(v):
return ...
?
...
Key consistency
• 

• (expire, invalidate)
function.delete(1)
function(v=1)@ring.dict({})
def function(v):
return ...
?
Key consistency
• 

• (expire, invalidate)
function.delete(1)
function(v=1)@ring.dict({})
def function(v):
return ...
?
Key consistency
• 

• (expire, invalidate)
>>> import sample
sample.f:1:2
sample.f:1:2
sample.f:1:2
import ring
@ring.dict({})
def f(a, *, b):
return ...
print(f.key(1, b=2))
print(f.key(a=1, b=2))
print(f.key(**{'a': 1, 'b': 2}))
Key consistency
• 

• (expire, invalidate)
>>> import sample
sample.A.f:A():1
sample.A.g:A:2
sample.A.g:A:3
import ring
class A(object):
def __ring_key__(self):
return 'A()'
@ring.dict({})
def f(self, a):
pass
@ring.dict({})
@classmethod
def g(cls, a):
pass
a = A()
print(a.f.key(a=1))
print(a.g.key(a=2))
print(A.g.key(a=3))
Key policy
• 1 ( ) 

• ( )

• ( )
Ring
• Sub-function control

• Methods & descriptor support

• Key Consistency

• Backend: memcache, redis, diskcache, shelve, dict
• asyncio support

• Fully customizable

• Django integration
Backends
@ring.dict(s)

@ring.shelve(s)

@ring.memcache(s)

@ring.redis(s)

@ring.diskcache(s)

@ring.django.cache()
Backends
@ring.dict(s)

@ring.shelve(s)

@ring.memcache(s)

@ring.redis(s)

@ring.diskcache(s)

@ring.django.cache()
dict

shelve.Shelf

memcache.Client (python-memcached)

pylibmc.Client

pymemcache.client.Client

aiomcache.Client

redis.Client

aioredis.Client

diskcache.Cache

django.core.cache.caches
Ring
• Sub-function control

• Methods & descriptor support

• Key Consistency

• Backend: memcache, redis, diskcache, shelve, dict

• asyncio support
• Fully customizable

• Django integration
Backends
@ring.dict(s)

@ring.shelve(s)

@ring.memcache(s)

@ring.redis(s)

@ring.diskcache(s)
dict
shelve.Shelf
memcache.Client (python-memcached)

pylibmc.Client

pymemcache.client.Client

aiomcache.Client
redis.Client

aioredis.Client
diskcache.Cache
Backends
• Q: ?

• A: 30
Backends
• Q: ?

• A: 30
class MemcacheStorage(
fbase.CommonMixinStorage, fbase.StorageMixin, BulkStorageMixin):
def get_value(self, key):
value = self.backend.get(key)
if value is None:
raise fbase.NotFound
return value
def set_value(self, key, value, expire):
self.backend.set(key, value, expire)
def delete_value(self, key):
self.backend.delete(key)
def touch_value(self, key, expire):
self.backend.touch(key, expire)
def get_many_values(self, keys):
values = self.backend.get_multi(keys)
return [values.get(k, fbase.NotFound) for k in keys]
def set_many_values(self, keys, values, expire):
self.backend.set_multi({k: v for k, v in zip(keys, values)}, expire)
def delete_many_values(self, keys):
return self.backend.delete_multi(keys)
Ring
• Sub-function control

• Methods & descriptor support

• Key Consistency

• Backend: memcache, redis, diskcache, shelve, dict

• asyncio support

• Fully customizable
• Django integration
Storage Key
• Q: Ring
Storage Key
sample.article:42

@ring.memcache(client)
def article(id):
return ...
print(article.key(42))
Storage Key
sample.article:42

new_prefix:42
@ring.memcache(client)
def article(id):
return ...
print(article.key(42))
@ring.memcache(client,
key_prefix='new_prefix')
def article(id):
return ...
print(article.key(42))
case1: prefix config
Storage Key
sample.article:42

a42e
@ring.memcache(client)
def article(id):
return ...
print(article.key(42))
@article.ring.key
def article_key(id):
return f'a{id}e'
print(article.key(42))
case2: key function override
Data Encoder
• Q: , ?

•
Data Encoder
dict(id=42, name='Name')

dict(id=42, name='Name')
@ring.dict({})
def user1(id):
return {
'id': id,
'name': 'Name'}
print(user1(42))
@ring.dict(
{}, coder='json')
def user2(id):
return {
'id': id,
'name': 'Name'}
print(user2(42))
Data Encoder
dict(id=42, name='Name')

# = json.dumps(user1(42))

b'{"id": id, "name": "Name"}'
d1 = {}
@ring.dict(d1)
def user1(id):
return {
'id': id,
'name': 'Name'}
print(d1[42])
d2 = {}
@ring.dict(d2, coder='json')
def user2(id):
return {
'id': id,
'name': 'Name'}
print(d2[42])
Data Encoder
• Q: 

•
Data Encoder
• json, pickle 

•
Data Encoder
# = json.dumps(user1(42))

'{"id": id, "name": "Name"}'
d1 = {}
@ring.dict(d1)
def user1(id):
return {
'id': id,
'name': 'Name'}
@user1.ring.encode
def user_encode(v):
return json.dumps(v)
@user1.ring.decode
def user_decode(v):
return json.loads(v)
print(d1[42])
case1: single function coder
Data Encoder
import json
import ring
ring.coder.register(
'json', (json.dumps, json.loads))
import pickle
import ring
ring.coder.register(
'pickle', (pickle.dumps, pickle.loads))
case2: reusable coder
Strategy
• __call__, get, update, delete ?

• ?

• ex: 

• ?

• ex: expire hit 

•
Strategy
• __call__, get, update, delete ?

• ?

• ex: 

• ?

• ex: expire hit 

• UserInterface
Low-level Interface
• Q: UserInterface ?
Ring ?
Ring ?
Low-level Interface
@ring.memcache(client, key_prefix='article')
def article(id):
return ...
Low-level Interface
@ring.memcache(client, key_prefix='article')
def article(id):
return ...
key = article.key(42) # key
encoded = client.get(key) # memcache get
data = article.decode(encoded) #
Low-level Interface
@ring.memcache(client, key_prefix='article')
def article(id):
return ...
key = article.key(42) # key
encoded = client.get(key) # memcache get
data = article.decode(encoded) #
data = article.get(42) # 3
Low-level Interface
• : 

•
Ring
inspect.signature
• parameters & return annotation

• Python 3.3+

• Backport: https://pypi.org/project/inspect2/
inspect.signature
In [1]: def f(a, b, *args, x, y=10, **kw):
...: pass
...:
In [2]: import inspect
In [3]: s = inspect.signature(f)
Out[4]: <Signature (a, b, *args, x, y=10, **kw)>
In [6]: for name, parameter in s.parameters.items():
...: print(name, parameter.kind, parameter.default)
...:
a POSITIONAL_OR_KEYWORD <class 'inspect._empty'>
b POSITIONAL_OR_KEYWORD <class 'inspect._empty'>
args VAR_POSITIONAL <class 'inspect._empty'>
x KEYWORD_ONLY <class 'inspect._empty'>
y KEYWORD_ONLY 10
kw VAR_KEYWORD <class 'inspect._empty'>
qualname
• / 



• 

(py2 im_class !)

• Python 3.3+
>>> class C:
... def f(): pass
... class D:
... def g(): pass
...
>>> C.__qualname__
'C'
>>> C.f.__qualname__
'C.f'
>>> C.D.__qualname__
'C.D'
>>> C.D.g.__qualname__
'C.D.g'
annotation
• def f(a: int, b: int) -> int:

return a + b

print(f.__annotations__)

{'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}

• inspect.signature(f).return_annotation

int

• inspect.signature(f.get).return_annotation

Optional[int]

• inspect.signature(f.key).return_annotation

str
pickle, shelve
• pickle: serialize 

• shelve: pickle dict DB

•
Methods & Descriptors
• Q: Ring method/descriptor ?

• A: https://github.com/youknowone/wirerope

• Rope: 

(unbound Rope )

• Wire: (method),

(classmethod) 

( bind Wire )

• hybridmethod, hybridproperty
Descriptor analysis
• :

• ?

• descriptor ?

• method property ?

• descriptor ?

(= method classmethod - hybrid )

• descriptor ?

• ?
Descriptor analysis
• :

• ?

• descriptor ?

• method property ?

• descriptor ?

(= method classmethod - hybrid )

• descriptor ?

• ?




2.7, 3.4-3.7 / PyPy2 PyPy3
def _f(owner):
return owner
Django app in single file
• Django ...

• ?

• 30 Django app 

• https://github.com/youknowone/django-app-in-single-file

Contenu connexe

Tendances

Desarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móvilesDesarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móviles
Luis Curo Salvatierra
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
Jeremy Kendall
 
Pry, the good parts
Pry, the good partsPry, the good parts
Pry, the good parts
Conrad Irwin
 
Обзор фреймворка Twisted
Обзор фреймворка TwistedОбзор фреймворка Twisted
Обзор фреймворка Twisted
Maxim Kulsha
 
MongoDB全機能解説2
MongoDB全機能解説2MongoDB全機能解説2
MongoDB全機能解説2
Takahiro Inoue
 

Tendances (18)

The (unknown) collections module
The (unknown) collections moduleThe (unknown) collections module
The (unknown) collections module
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding Horrors
 
Desarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móvilesDesarrollo de módulos en Drupal e integración con dispositivos móviles
Desarrollo de módulos en Drupal e integración con dispositivos móviles
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Php 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodPhp 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the Good
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Saving Gaia with GeoDjango
Saving Gaia with GeoDjangoSaving Gaia with GeoDjango
Saving Gaia with GeoDjango
 
Django101 geodjango
Django101 geodjangoDjango101 geodjango
Django101 geodjango
 
Ansible, voyage au centre de l'automatisation
Ansible, voyage au centre de l'automatisationAnsible, voyage au centre de l'automatisation
Ansible, voyage au centre de l'automatisation
 
Pry, the good parts
Pry, the good partsPry, the good parts
Pry, the good parts
 
PHP Loves MongoDB - Dublin MUG (by Hannes)
PHP Loves MongoDB - Dublin MUG (by Hannes)PHP Loves MongoDB - Dublin MUG (by Hannes)
PHP Loves MongoDB - Dublin MUG (by Hannes)
 
Rapid and Scalable Development with MongoDB, PyMongo, and Ming
Rapid and Scalable Development with MongoDB, PyMongo, and MingRapid and Scalable Development with MongoDB, PyMongo, and Ming
Rapid and Scalable Development with MongoDB, PyMongo, and Ming
 
Обзор фреймворка Twisted
Обзор фреймворка TwistedОбзор фреймворка Twisted
Обзор фреймворка Twisted
 
Using Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer ArchitectureUsing Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer Architecture
 
MongoDB全機能解説2
MongoDB全機能解説2MongoDB全機能解説2
MongoDB全機能解説2
 
The Ring programming language version 1.3 book - Part 42 of 88
The Ring programming language version 1.3 book - Part 42 of 88The Ring programming language version 1.3 book - Part 42 of 88
The Ring programming language version 1.3 book - Part 42 of 88
 
php plus mysql
php plus mysqlphp plus mysql
php plus mysql
 

Similaire à 2018 PyCon Korea - Ring

Similaire à 2018 PyCon Korea - Ring (20)

Extjs + Gears
Extjs + GearsExtjs + Gears
Extjs + Gears
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disqus
 
Go Web Development
Go Web DevelopmentGo Web Development
Go Web Development
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
Django Overview
Django OverviewDjango Overview
Django Overview
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
Django cryptography
Django cryptographyDjango cryptography
Django cryptography
 
國民雲端架構 Django + GAE
國民雲端架構 Django + GAE國民雲端架構 Django + GAE
國民雲端架構 Django + GAE
 
Ruby is Awesome
Ruby is AwesomeRuby is Awesome
Ruby is Awesome
 
ORM in Go. Internals, tips & tricks
ORM in Go. Internals, tips & tricksORM in Go. Internals, tips & tricks
ORM in Go. Internals, tips & tricks
 
Performance patterns
Performance patternsPerformance patterns
Performance patterns
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYC
 
Web2.0 with jQuery in English
Web2.0 with jQuery in EnglishWeb2.0 with jQuery in English
Web2.0 with jQuery in English
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapper
 
Learning How To Use Jquery #5
Learning How To Use Jquery #5Learning How To Use Jquery #5
Learning How To Use Jquery #5
 
Nodejs - A quick tour (v4)
Nodejs - A quick tour (v4)Nodejs - A quick tour (v4)
Nodejs - A quick tour (v4)
 
Python Development (MongoSF)
Python Development (MongoSF)Python Development (MongoSF)
Python Development (MongoSF)
 
Nodejs - A quick tour (v5)
Nodejs - A quick tour (v5)Nodejs - A quick tour (v5)
Nodejs - A quick tour (v5)
 

Dernier

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Dernier (20)

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 

2018 PyCon Korea - Ring