SlideShare a Scribd company logo
1 of 48
Download to read offline
MAX

Realtime messaging and

activity stream engine
Carles Bruguera (@sunbit)

Víctor Fernández de Alba (@sneridagh)
Víctor
● Senior Python Developer and IT architect

● Plone Foundation member

● Plone core developer since 2010

● Author of Plone 3 intranets book (2010, PacktPub)
@sneridagh
Carles
● Python and JavaScript lover
● Working with python for the last 8 years
● Occasional Erlang coder (when on drugs)
● Regex freak
@sunbit
Python @UPCnet and @BarcelonaTech
DEMO!
History
● First commit on August, 2011
● Initially designed as the key feature for the Universitat
Politècnica de Catalunya (BarcelonaTech) university
concept of social intranet
● Today, MAX is used by more than 30.000 students and
8.000 university staff integrated in the online campus
and the institutional collaboration tools
What is MAX?
● RESTful API

● 88 (and growing) endpoints

● Multi-source user and application activity stream 

● Asynchronous messaging and conversations
● GPL Licensed
Old styled forums
Forum Topic Post Post Post
What is a context?
Context (unique URI)
Forum Topic Post
Posts
Subscriptions
Post Post
Contexts
● Identified by unique URIs

● Permissions per context

o read

o write

o subscribe

o unsubscribe

● Multiple context types based on permissions variations

● Granular permissions per user

o Overriding the default ones defined by the context

o Grant / Revoke
o invite

o kick

o delete

o flag
Real life examples
Communities site
Alumni
Sell your stuff
Institutional events
Institutional news
Online campus
Compilers
Faculty news
Applied maths III
Signal theory
Real life examples (II)
Community types
Open Closed Institutional
Everyone can
join and leave
at will
The owner
should invite me
to join and I can
leave at will
The site admin
subscribes
people, no one
can leave
Features
Activity Stream
● Stores activity from users and applications
● Usual social actions

○ Comments

○ Likes

○ Favorites

● Images and files support
Features
Conversations
● Realtime conversations and private messaging
● One to one

● Groups
● Images and files support
Features
JS
Javascript
UI widget
Notifications
● Platform specific push notifications





● Internal notifications

○ Double check

○ others
Features
Features
External sources aggregation
Features
Fully deployable on premises
● Addresses any security concerns

● Absolute customer data privacy
and ownership
● “Corporate whatsapp”
Features Summary
JS
Components overview
iOs App
Plone
Moodle
android App
REST Api
“MAX”
OAuth Server
“Osiris”
Messaging
“Maxbunny”
NGINX
max.ui.js
RabbitMQ MongoDB
LDAP
Sync services
“Hub”
Twitter listener
“MaxTweety”
Osiris
● Minimal OAuth2 server implementation
● Build on top of pyramid
● Resource Owner Credentials Flow
● Tokens stored on MongoDB
● /token endpoint to generate token for a user
● /checktoken endpoint to verify a token
● Base LDAP user storage implementation
● Pluggable repoze.who based alternative user
storage implementations
NGINX
Pyramid + gevent
MongoDB
WSGI (Chausette)
MAX
● REST(ful) api
● Also build on top of pyramid
● Hybrid URL-dispatch + traversal routing
● ACL policy with fine-grained permissions per
endpoint
● Customized venusian decorator to configure
endpoints
● Tweens used for several tasks
● Per-exception catching to provide detailed JSON
error messages
● Per-request caching of variables
NGINX
Pyramid + Gevent
MongoDB
WSGI (Chausette)
RabbitMQ
MAX (Routing)
● Route definition
RESOURCES['avatar'] = dict(route='/people/{username}/
avatar', filesystem=True, category='User', name='User
avatar', traverse='/people/{username}')
● Endpoint definition
@endpoint(route_name='avatar', request_method='POST',
permission=modify_avatar)
def postUserAvatar(user, request):
"""
Upload user avatar
"""
MAX (Tweens)
● exception catcher
● post tunneling
● compatibility check
def compatibility_checker_factory(handler, registry):
def compatibility_checker_tween(request):
requested_compat_id = request.headers.get('X-Max-Compat-ID', None)
if requested_compat_id is None:
response = handler(request)
return response
expected_compat_id = str(request.registry.settings.get('max.compat_id'))
if expected_compat_id == requested_compat_id:
response = handler(request)
return response
else:
return JSONHTTPPreconditionFailed(
error=dict(
objectType='error',
error="CompatibilityIDMismatch",
error_description='X-Max-Compat-ID header value mismatch, {} was
expected'.format(expected_compat_id)))
return compatibility_checker_tween
MAX (Exception handling)
● Known error use cases are raised as custom
exceptions:
raise ObjectNotFound("User {} doesn't have role {}".format(user, role))
● And rendered as a JSON message
@view_config(context=ObjectNotFound)
def object_not_found(exc, request):
return JSONHTTPNotFound(error=dict(objectType='error',
error=ObjectNotFound.__name__, error_description=exc.message))
● Non-handled exceptions are logged with request
information
RabbitMQ & messaging
● Exchange-to-exchange routing
● STOMP over WS using rabbitmq plugins
● “Public” end-user stomp endpoints
● Message delivery and security through
routing key bindings
● Oauth authentication via erlang plugin
● Easy plug-in of temp queues for debugging
NGINX
Queues & exchanges
RabbitMQ
Websockets
STOMP AMQP
Oauth Authentication
Oauth2
activity
type=topic
conversations
type=topic
userid.subscribe
type=fanout
userid.publish
type=direct
...
Mobile
Apps
Other
clients
pushmessages
dynamic
queue
dynamic
queue
MAX
Messaging Design
internal
id.*
id.*
*.messages
*.notifi
cations
id
MaxCarrot
{"uuid": "005fab55bee84",
"user": {
"username": "johndoe",
"displayname" : "John Doe"
},
"action": "add",
"object": "message",
"data": {
"text": "Hello world!"
},
"source": "ios",
"domain": "demo",
"version": "4.0.1",
"published": "2015-07-21"}
MaxCarrot
● JSON based message format
● Used on messages routed through RabbitMQ
● Packed and unpacked versions
● Metadata/debugging fields
● Purpose related fields
● Encapsulates messaging logic
MaxCarrot
(Rules)
● Map field combinations to actions
● Pack messages following spec
● Ignore any message not matching any mapping
"source": {
"id": "s",
"type": "char",
"values": {
"ios": { "id”: "c" },
(...)
"max": { "id”: "m" }
}
"version": {
"id": "v",
"type": "string",
}
MaxCarrot
(human-readable)
{"uuid": "005fab55bee84",
"user": {
"username": "johndoe",
"displayname" : "John Doe"
},
"action": "add",
"object": "message",
"data": {
"text": "Hello world!"
},
"source": "ios",
"domain": "demo",
"version": "4.0.1",
"published": "2015-07-21"}
MaxCarrot
(nerd-readable)
{‘a’:'a','d':
{'text':'Helloworld
!'},'g':'005fab55be
e84','i':'demo','o'
:'m','p':'2015-07-2
1','s':'i','u':
{'u':'johndoe','d':
'JohnDoe'},'v':'4.0
.1'}
MaxBunny
● Pluggable multiprocess domain-aware
queue consumer
● A multiprocess runner runs N process for
each consumer defined.
● Each consumer binds to a queue and
consumes messages
● Runner provides a shared pool of WSGI
MaxClient instances, one for each
domain.MongoDB
RabbitMQ
MAX
MaxBunny Runner
& Consumers
WSGI MaxClient
MaxClient
● Opinionated Wrapper for REST api’s
● Wraps endpoint resources based on endpoint list definition.
RESOURCES[‘activity’] = dict(route=’/people/{username}/activities’)
● Accesses endpoints in a pythonic way
>>> client.people[‘username’].activities.get(qs={‘limit’:2})
● Creates json bodies from “nested” kwargs (with optional
sensible defaults)
>>> client.activities.post(object_content=’Hello’)
{
“object”: {
“objectType”: “note”,
“content”: “Hello”
}}
MaxClient
● Raises a custom RequestError exception on 5xx and
4xx responses
● Returns None on 404 responses
● Returns parsed JSON body on success responses
WSGI MaxClient
● WSGI version
● Subclassed MaxClient that makes calls to a “fake” wsgi
server
● Actual MAX Codebase is run by the client
● Requests don’t stress main api servers, only database
● Limitations:
o User must have privileges on “real” max server
o Computer from where client is run must have access to
storage backed
Twitter external aggregation
● Backend process listens twitter streaming service
● Selected tweets are queued and processed
● Valid tweets are injected into max activity stream
● Max users linked with twitter usernames
● Aggregation of content as a context
Current integrations
UPCnet uLearn Communities
UPCnet uLearn Campus
iOS & Android apps
Potential integrations
<place your web|app|whatever thingy name here>
<place the screenshots here>
Whishlist
● Social interactions (Follow/share)

● Finish & polish documentation

● Microservices / Dockerization

● Redis backed cache

● RabbitMQ SSL without NGINX

● Python3 / asyncio

● Explore JSON-LD (HATEOAS)

● Encryption
Community building?
Absolutely!

Let’s do it!
Contact us, PR are welcome!
Resources
https://upcnet.github.io/max

https://github.com/UPCnet/max

https://github.com/UPCnet/maxserver
Thanks / Gràcies
@sunbit

@sneridagh

More Related Content

What's hot

Nk API - examples
Nk API - examplesNk API - examples
Nk API - examples
nasza-klasa
 
RESTfull with RestKit
RESTfull with RestKitRESTfull with RestKit
RESTfull with RestKit
Taras Kalapun
 

What's hot (20)

MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
 
Introduction to Restkit
Introduction to RestkitIntroduction to Restkit
Introduction to Restkit
 
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema
[MongoDB.local Bengaluru 2018] Just in Time Validation with JSON Schema
 
Mongoose: MongoDB object modelling for Node.js
Mongoose: MongoDB object modelling for Node.jsMongoose: MongoDB object modelling for Node.js
Mongoose: MongoDB object modelling for Node.js
 
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...
 
Mongo db tutorials
Mongo db tutorialsMongo db tutorials
Mongo db tutorials
 
Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8
 
Data Management 3: Bulletproof Data Management
Data Management 3: Bulletproof Data ManagementData Management 3: Bulletproof Data Management
Data Management 3: Bulletproof Data Management
 
Data Management 2: Conquering Data Proliferation
Data Management 2: Conquering Data ProliferationData Management 2: Conquering Data Proliferation
Data Management 2: Conquering Data Proliferation
 
Learn Learn how to build your mobile back-end with MongoDB
Learn Learn how to build your mobile back-end with MongoDBLearn Learn how to build your mobile back-end with MongoDB
Learn Learn how to build your mobile back-end with MongoDB
 
Consume Spring Data Rest with Angularjs
Consume Spring Data Rest with AngularjsConsume Spring Data Rest with Angularjs
Consume Spring Data Rest with Angularjs
 
Mongoose and MongoDB 101
Mongoose and MongoDB 101Mongoose and MongoDB 101
Mongoose and MongoDB 101
 
Nk API - examples
Nk API - examplesNk API - examples
Nk API - examples
 
Introduction to JSON & AJAX
Introduction to JSON & AJAXIntroduction to JSON & AJAX
Introduction to JSON & AJAX
 
RESTfull with RestKit
RESTfull with RestKitRESTfull with RestKit
RESTfull with RestKit
 
Webinar: Developing with the modern App Stack: MEAN and MERN (with Angular2 a...
Webinar: Developing with the modern App Stack: MEAN and MERN (with Angular2 a...Webinar: Developing with the modern App Stack: MEAN and MERN (with Angular2 a...
Webinar: Developing with the modern App Stack: MEAN and MERN (with Angular2 a...
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
Joker'15 Java straitjackets for MongoDB
Joker'15 Java straitjackets for MongoDBJoker'15 Java straitjackets for MongoDB
Joker'15 Java straitjackets for MongoDB
 
Webinar: Back to Basics: Thinking in Documents
Webinar: Back to Basics: Thinking in DocumentsWebinar: Back to Basics: Thinking in Documents
Webinar: Back to Basics: Thinking in Documents
 
Conceptos básicos. Seminario web 5: Introducción a Aggregation Framework
Conceptos básicos. Seminario web 5: Introducción a Aggregation FrameworkConceptos básicos. Seminario web 5: Introducción a Aggregation Framework
Conceptos básicos. Seminario web 5: Introducción a Aggregation Framework
 

Viewers also liked

Viewers also liked (7)

June 2014 - Building Rabbit MQ based chat on Android
June 2014 - Building Rabbit MQ based chat on AndroidJune 2014 - Building Rabbit MQ based chat on Android
June 2014 - Building Rabbit MQ based chat on Android
 
분석과 설계
분석과 설계분석과 설계
분석과 설계
 
RabbitMQ Data Ingestion
RabbitMQ Data IngestionRabbitMQ Data Ingestion
RabbitMQ Data Ingestion
 
Dissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal ArchitectureDissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal Architecture
 
2015 스타트업 투자동향보고서_platum
2015 스타트업 투자동향보고서_platum2015 스타트업 투자동향보고서_platum
2015 스타트업 투자동향보고서_platum
 
The Best Way to Fund your Startup
The Best Way to Fund your StartupThe Best Way to Fund your Startup
The Best Way to Fund your Startup
 
Unit of Value: A Framework for Scaling
Unit of Value: A Framework for ScalingUnit of Value: A Framework for Scaling
Unit of Value: A Framework for Scaling
 

Similar to Max euro python 2015

Serverless Apps - droidcon london 2012
Serverless Apps - droidcon london 2012Serverless Apps - droidcon london 2012
Serverless Apps - droidcon london 2012
Friedger Müffke
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWARE
FIWARE
 

Similar to Max euro python 2015 (20)

Five android architecture
Five android architectureFive android architecture
Five android architecture
 
Serverless Apps - droidcon london 2012
Serverless Apps - droidcon london 2012Serverless Apps - droidcon london 2012
Serverless Apps - droidcon london 2012
 
Mail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyMail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - Italy
 
Web App Prototypes with Google App Engine
Web App Prototypes with Google App EngineWeb App Prototypes with Google App Engine
Web App Prototypes with Google App Engine
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
 
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
 
Rapid prototyping using azure functions - A walk on the wild side
Rapid prototyping using azure functions - A walk on the wild sideRapid prototyping using azure functions - A walk on the wild side
Rapid prototyping using azure functions - A walk on the wild side
 
Siddhi - cloud-native stream processor
Siddhi - cloud-native stream processorSiddhi - cloud-native stream processor
Siddhi - cloud-native stream processor
 
When GenAI meets with Java with Quarkus and langchain4j
When GenAI meets with Java with Quarkus and langchain4jWhen GenAI meets with Java with Quarkus and langchain4j
When GenAI meets with Java with Quarkus and langchain4j
 
Advanced android app development
Advanced android app developmentAdvanced android app development
Advanced android app development
 
Elasticsearch an overview
Elasticsearch   an overviewElasticsearch   an overview
Elasticsearch an overview
 
JS Fest 2019/Autumn. Виталий Кухар. Сравнение кластеризации HTTP, TCP и UDP н...
JS Fest 2019/Autumn. Виталий Кухар. Сравнение кластеризации HTTP, TCP и UDP н...JS Fest 2019/Autumn. Виталий Кухар. Сравнение кластеризации HTTP, TCP и UDP н...
JS Fest 2019/Autumn. Виталий Кухар. Сравнение кластеризации HTTP, TCP и UDP н...
 
JS Fest 2019: Comparing Node.js processes and threads for clustering HTTP, TC...
JS Fest 2019: Comparing Node.js processes and threads for clustering HTTP, TC...JS Fest 2019: Comparing Node.js processes and threads for clustering HTTP, TC...
JS Fest 2019: Comparing Node.js processes and threads for clustering HTTP, TC...
 
Revealing ALLSTOCKER
Revealing ALLSTOCKERRevealing ALLSTOCKER
Revealing ALLSTOCKER
 
Introduction to REST API with Node.js
Introduction to REST API with Node.jsIntroduction to REST API with Node.js
Introduction to REST API with Node.js
 
Dragoncraft Architectural Overview
Dragoncraft Architectural OverviewDragoncraft Architectural Overview
Dragoncraft Architectural Overview
 
Google apps script
Google apps scriptGoogle apps script
Google apps script
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWARE
 
Android GRPC
Android GRPCAndroid GRPC
Android GRPC
 

Recently uploaded

Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
drm1699
 

Recently uploaded (20)

Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14
 
UNI DI NAPOLI FEDERICO II - Il ruolo dei grafi nell'AI Conversazionale Ibrida
UNI DI NAPOLI FEDERICO II - Il ruolo dei grafi nell'AI Conversazionale IbridaUNI DI NAPOLI FEDERICO II - Il ruolo dei grafi nell'AI Conversazionale Ibrida
UNI DI NAPOLI FEDERICO II - Il ruolo dei grafi nell'AI Conversazionale Ibrida
 
Rapidoform for Modern Form Building and Insights
Rapidoform for Modern Form Building and InsightsRapidoform for Modern Form Building and Insights
Rapidoform for Modern Form Building and Insights
 
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdfThe Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
 
Your Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | EvmuxYour Ultimate Web Studio for Streaming Anywhere | Evmux
Your Ultimate Web Studio for Streaming Anywhere | Evmux
 
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AI
 
Incident handling is a clearly defined set of procedures to manage and respon...
Incident handling is a clearly defined set of procedures to manage and respon...Incident handling is a clearly defined set of procedures to manage and respon...
Incident handling is a clearly defined set of procedures to manage and respon...
 
Encryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key ConceptsEncryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key Concepts
 
Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea Goulet
 
Automate your OpenSIPS config tests - OpenSIPS Summit 2024
Automate your OpenSIPS config tests - OpenSIPS Summit 2024Automate your OpenSIPS config tests - OpenSIPS Summit 2024
Automate your OpenSIPS config tests - OpenSIPS Summit 2024
 
Abortion Clinic In Springs ](+27832195400*)[ 🏥 Safe Abortion Pills in Springs...
Abortion Clinic In Springs ](+27832195400*)[ 🏥 Safe Abortion Pills in Springs...Abortion Clinic In Springs ](+27832195400*)[ 🏥 Safe Abortion Pills in Springs...
Abortion Clinic In Springs ](+27832195400*)[ 🏥 Safe Abortion Pills in Springs...
 
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
Workshop -  Architecting Innovative Graph Applications- GraphSummit MilanWorkshop -  Architecting Innovative Graph Applications- GraphSummit Milan
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
 
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
Abortion Pills For Sale WhatsApp[[+27737758557]] In Birch Acres, Abortion Pil...
 
The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)
 
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jGraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
 
Lessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdfLessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdf
 
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
 
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit MilanWorkshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
 

Max euro python 2015

  • 1. MAX Realtime messaging and activity stream engine Carles Bruguera (@sunbit) Víctor Fernández de Alba (@sneridagh)
  • 2. Víctor ● Senior Python Developer and IT architect ● Plone Foundation member ● Plone core developer since 2010 ● Author of Plone 3 intranets book (2010, PacktPub) @sneridagh
  • 3. Carles ● Python and JavaScript lover ● Working with python for the last 8 years ● Occasional Erlang coder (when on drugs) ● Regex freak @sunbit
  • 4. Python @UPCnet and @BarcelonaTech
  • 6. History ● First commit on August, 2011 ● Initially designed as the key feature for the Universitat Politècnica de Catalunya (BarcelonaTech) university concept of social intranet ● Today, MAX is used by more than 30.000 students and 8.000 university staff integrated in the online campus and the institutional collaboration tools
  • 7. What is MAX? ● RESTful API ● 88 (and growing) endpoints ● Multi-source user and application activity stream ● Asynchronous messaging and conversations ● GPL Licensed
  • 8. Old styled forums Forum Topic Post Post Post
  • 9. What is a context? Context (unique URI) Forum Topic Post Posts Subscriptions Post Post
  • 10. Contexts ● Identified by unique URIs ● Permissions per context o read o write o subscribe o unsubscribe ● Multiple context types based on permissions variations ● Granular permissions per user o Overriding the default ones defined by the context o Grant / Revoke o invite o kick o delete o flag
  • 11. Real life examples Communities site Alumni Sell your stuff Institutional events Institutional news Online campus Compilers Faculty news Applied maths III Signal theory
  • 12. Real life examples (II) Community types Open Closed Institutional Everyone can join and leave at will The owner should invite me to join and I can leave at will The site admin subscribes people, no one can leave
  • 13. Features Activity Stream ● Stores activity from users and applications ● Usual social actions ○ Comments ○ Likes ○ Favorites ● Images and files support
  • 14. Features Conversations ● Realtime conversations and private messaging ● One to one ● Groups ● Images and files support
  • 16. Notifications ● Platform specific push notifications
 
 
 ● Internal notifications ○ Double check ○ others Features
  • 18. Features Fully deployable on premises ● Addresses any security concerns ● Absolute customer data privacy and ownership ● “Corporate whatsapp”
  • 20. Components overview iOs App Plone Moodle android App REST Api “MAX” OAuth Server “Osiris” Messaging “Maxbunny” NGINX max.ui.js RabbitMQ MongoDB LDAP Sync services “Hub” Twitter listener “MaxTweety”
  • 21. Osiris ● Minimal OAuth2 server implementation ● Build on top of pyramid ● Resource Owner Credentials Flow ● Tokens stored on MongoDB ● /token endpoint to generate token for a user ● /checktoken endpoint to verify a token ● Base LDAP user storage implementation ● Pluggable repoze.who based alternative user storage implementations NGINX Pyramid + gevent MongoDB WSGI (Chausette)
  • 22. MAX ● REST(ful) api ● Also build on top of pyramid ● Hybrid URL-dispatch + traversal routing ● ACL policy with fine-grained permissions per endpoint ● Customized venusian decorator to configure endpoints ● Tweens used for several tasks ● Per-exception catching to provide detailed JSON error messages ● Per-request caching of variables NGINX Pyramid + Gevent MongoDB WSGI (Chausette) RabbitMQ
  • 23. MAX (Routing) ● Route definition RESOURCES['avatar'] = dict(route='/people/{username}/ avatar', filesystem=True, category='User', name='User avatar', traverse='/people/{username}') ● Endpoint definition @endpoint(route_name='avatar', request_method='POST', permission=modify_avatar) def postUserAvatar(user, request): """ Upload user avatar """
  • 24. MAX (Tweens) ● exception catcher ● post tunneling ● compatibility check def compatibility_checker_factory(handler, registry): def compatibility_checker_tween(request): requested_compat_id = request.headers.get('X-Max-Compat-ID', None) if requested_compat_id is None: response = handler(request) return response expected_compat_id = str(request.registry.settings.get('max.compat_id')) if expected_compat_id == requested_compat_id: response = handler(request) return response else: return JSONHTTPPreconditionFailed( error=dict( objectType='error', error="CompatibilityIDMismatch", error_description='X-Max-Compat-ID header value mismatch, {} was expected'.format(expected_compat_id))) return compatibility_checker_tween
  • 25. MAX (Exception handling) ● Known error use cases are raised as custom exceptions: raise ObjectNotFound("User {} doesn't have role {}".format(user, role)) ● And rendered as a JSON message @view_config(context=ObjectNotFound) def object_not_found(exc, request): return JSONHTTPNotFound(error=dict(objectType='error', error=ObjectNotFound.__name__, error_description=exc.message)) ● Non-handled exceptions are logged with request information
  • 26.
  • 27. RabbitMQ & messaging ● Exchange-to-exchange routing ● STOMP over WS using rabbitmq plugins ● “Public” end-user stomp endpoints ● Message delivery and security through routing key bindings ● Oauth authentication via erlang plugin ● Easy plug-in of temp queues for debugging NGINX Queues & exchanges RabbitMQ Websockets STOMP AMQP Oauth Authentication Oauth2
  • 29. MaxCarrot {"uuid": "005fab55bee84", "user": { "username": "johndoe", "displayname" : "John Doe" }, "action": "add", "object": "message", "data": { "text": "Hello world!" }, "source": "ios", "domain": "demo", "version": "4.0.1", "published": "2015-07-21"}
  • 30. MaxCarrot ● JSON based message format ● Used on messages routed through RabbitMQ ● Packed and unpacked versions ● Metadata/debugging fields ● Purpose related fields ● Encapsulates messaging logic
  • 31. MaxCarrot (Rules) ● Map field combinations to actions ● Pack messages following spec ● Ignore any message not matching any mapping "source": { "id": "s", "type": "char", "values": { "ios": { "id”: "c" }, (...) "max": { "id”: "m" } } "version": { "id": "v", "type": "string", }
  • 32. MaxCarrot (human-readable) {"uuid": "005fab55bee84", "user": { "username": "johndoe", "displayname" : "John Doe" }, "action": "add", "object": "message", "data": { "text": "Hello world!" }, "source": "ios", "domain": "demo", "version": "4.0.1", "published": "2015-07-21"}
  • 34. MaxBunny ● Pluggable multiprocess domain-aware queue consumer ● A multiprocess runner runs N process for each consumer defined. ● Each consumer binds to a queue and consumes messages ● Runner provides a shared pool of WSGI MaxClient instances, one for each domain.MongoDB RabbitMQ MAX MaxBunny Runner & Consumers WSGI MaxClient
  • 35. MaxClient ● Opinionated Wrapper for REST api’s ● Wraps endpoint resources based on endpoint list definition. RESOURCES[‘activity’] = dict(route=’/people/{username}/activities’) ● Accesses endpoints in a pythonic way >>> client.people[‘username’].activities.get(qs={‘limit’:2}) ● Creates json bodies from “nested” kwargs (with optional sensible defaults) >>> client.activities.post(object_content=’Hello’) { “object”: { “objectType”: “note”, “content”: “Hello” }}
  • 36. MaxClient ● Raises a custom RequestError exception on 5xx and 4xx responses ● Returns None on 404 responses ● Returns parsed JSON body on success responses
  • 37. WSGI MaxClient ● WSGI version ● Subclassed MaxClient that makes calls to a “fake” wsgi server ● Actual MAX Codebase is run by the client ● Requests don’t stress main api servers, only database ● Limitations: o User must have privileges on “real” max server o Computer from where client is run must have access to storage backed
  • 38. Twitter external aggregation ● Backend process listens twitter streaming service ● Selected tweets are queued and processed ● Valid tweets are injected into max activity stream ● Max users linked with twitter usernames ● Aggregation of content as a context
  • 39. Current integrations UPCnet uLearn Communities UPCnet uLearn Campus iOS & Android apps
  • 40.
  • 41.
  • 42.
  • 43.
  • 44. Potential integrations <place your web|app|whatever thingy name here> <place the screenshots here>
  • 45. Whishlist ● Social interactions (Follow/share) ● Finish & polish documentation ● Microservices / Dockerization ● Redis backed cache ● RabbitMQ SSL without NGINX ● Python3 / asyncio ● Explore JSON-LD (HATEOAS) ● Encryption
  • 46. Community building? Absolutely! Let’s do it! Contact us, PR are welcome!