lk-geimfari / mimesis

Mimesis is a robust data generator for Python that can produce a wide range of fake data in multiple languages.
https://mimesis.name
MIT License
4.44k stars 336 forks source link

Mimesis Simple HTTP Server #405

Closed duckyou closed 6 years ago

duckyou commented 6 years ago

Implement very simple http server like in module http.server, which returns generated data by mimesis.

The idea is to pass template in header, and ignore body and query arguments, for future integration with another server.

For example:

Template:

{
  "id": ":uuid",
  "version": "0.1.2",
  "owner.full_name": ":name :personal.surname",
  "owner.email": {"_type": "str", "_field": ":email", "_key": "lower"},
  "owner.phones": {"_type": "list", "_count": 5, "_field": [":telephone", "other1", "other2"]}
}

Output:

{
  "id": "dfcfd2f3-0799-b519-1a94-326c978b10c6",
  "version": "0.1.2",
  "owner": {
    "full_name": "Charley Parker",
    "email": "cheetah1869@yandex.com",
    "phones": ["776.907.0588", "717.592.4382", "168.028.7210", "other1", "other2"]
  }
}

Or we can implement something like jinja2 templating system for open customize output

Some header examples:

It's may be helpful for prototyping some RESTful/GRAPHql api.

sobolevn commented 6 years ago

Why not use mimesis-cloud? https://github.com/wemake-services/mimesis-cloud That's exactly what it should do.

lk-geimfari commented 6 years ago

@duckyou Do you have checked out mimesis-cloud? Is it suitable? If yes, then I suggest improving mimesis-cloud.

lk-geimfari commented 6 years ago

Let's improving mimesis-cloud and add a section about it to documentation.

duckyou commented 6 years ago

@sobolevn @lk-geimfari Heres what i mean:

HTTP Requests:

Get 100 users:

Request:

GET /api/users?count=100 HTTP/1.1
Host: localhost:8000
Mimesis-Template: {"id": ":uuid", "email": ":email"}
Mimesis-Locale: en
Mimesis-Count: 100
Cache-Control: no-cache

Response:

HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 100500
Content-Type: application/json
Date: Tue, 13 Feb 2018 13:12:25 GMT
Server: Mimesis Server

[
  {"id": "dfcfd2f3-0799-b519-1a94-326c978b10c6", "email": "email1@mail.com"},
  {"id": "dfcfd2f3-0799-b519-1a94-326c978b10c7", "email": "email2@mail.com"},
  {"id": "dfcfd2f3-0799-b519-1a94-326c978b10c8", "email": "email3@mail.com"},
  ...
]

Add 1 user

Request:

POST /api/users HTTP/1.1
Host: localhost:8000
Mimesis-Template: {"id": ":uuid", "email": "test@mail.com"}
Mimesis-Locale: en
Mimesis-Count: 0
Content-Type: application/json

{
    "email": "test@mail.com"
}

Response:

HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 40
Content-Type: application/json
Date: Tue, 13 Feb 2018 13:16:06 GMT
Server: Mimesis Server

{"id": "dfcfd2f3-0799-b519-1a94-326c978b10c9", "email": "test@mail.com"}

Mimesis-Cloud using only graphql, if I understand correctly.

lk-geimfari commented 6 years ago

@duckyou Can we do it without extra-requirements? If not, then I suggest do it as another package.

duckyou commented 6 years ago

@lk-geimfari, yes. It can be done without third-party modules ^^

lk-geimfari commented 6 years ago

@duckyou Let's try to do it in module mimesis.http, branch server.

lk-geimfari commented 6 years ago

Of course, if @sobolevn don't mind against.

duckyou commented 6 years ago

@lk-geimfari maybe better mimesis.server? And when it will be done, we can run it like python -m mimesis.server?

We also need to discuss the template system in more detail.

lk-geimfari commented 6 years ago

@duckyou Sure!

lk-geimfari commented 6 years ago

@duckyou Illustrate your simple working demo version and we will be thinking about improving it together.

sobolevn commented 6 years ago

@duckyou nope, mimesis-cloud supports any kind of http requests: rest, graphql, whatever other.

I am strongly against adding this kind of functionality to the core package. Main reasons is over complicating functionality. One library should do one thing and do it well.

lk-geimfari commented 6 years ago

In general, I agree with @sobolevn.

I thought, and it seems to me that we will greatly complicate the support of the project if we add such resource-intensive features to one project, so it's better to create a different repository for it or something like this. Let this be an experimental project in another repository. What do you think?

lk-geimfari commented 6 years ago

@duckyou I have created mimesis-mock-server. Feel free to rename it.

lk-geimfari commented 6 years ago

Or (better) we can improve existing project mimesis-cloud.

sobolevn commented 6 years ago

+1 for improving mimesis-cloud.

duckyou commented 6 years ago

@lk-geimfari @sobolevn , here's an alpha realisation: https://github.com/duckyou/mimesis/tree/http-server

How to get:

git clone -b http-server https://github.com/duckyou/mimesis && cd mimesis
python -m mimesis.server

   _____ _               _
  |     |_|_____ ___ ___|_|___
  | | | | |     | -_|_ -| |_ -|
  |_|_|_|_|_|_|_|___|___|_|___|
   _____ _____ _____ _____    _____
  |  |  |_   _|_   _|  _  |  |   __|___ ___ _ _ ___ ___
  |     | | |   | | |   __|  |__   | -_|  _| | | -_|  _|
  |__|__| |_|   |_| |__|     |_____|___|_|  \_/|___|_|   v0.0.4

  Easy way to GET mock data at http://0.0.0.0:8080 ...

Now we can request data:

import json
import requests

url = "http://localhost:8080/this/url/"
querystring = {'does': 'not', 'affect': 'anything'}

payload = 'This body string does not affect anything to.'

template = {
    'id': ':uuid',
    'version': '0.1.2',
    'owner.full_name': ':name :personal.surname',
    'owner.email': {
        '_type': 'str',
        '_field': ':email',
        '_key': 'lower'
    },
    'owner.phones': {
        '_type': 'list',
        '_count': 5,
        '_field': [":telephone", "other1", "other2"]
    },
}
headers = {
    'Mimesis-Template': json.dumps(template),
    'Mimesis-Count': "10",
    'Mimesis-Locale': "ru"
    }

response = requests.request("POST", url, data=payload,
                            headers=headers, params=querystring)

print(json.loads(response.text))

Output:

[{'owner': {'phones': ['+7-(999)-098-16-91', '+7-(923)-459-39-61', '+7-(918)-184-74-33', 'other1', 'other2'], 'full_name': 'Фёдор Демина', 'email': 'cousins1841@yahoo.com'}, 'version': '0.1.2', 'id': 'f28f236a-f1b8-a560-f650-1514588cb322'}, {'owner': {'phones': ['+7-(978)-937-21-37', '+7-(909)-584-91-17', '+7-(968)-511-13-82', 'other1', 'other2'], 'full_name': 'Григорий Алчёв', 'email': 'dosers1979@gmail.com'}, 'version': '0.1.2', 'id': '5835bf1c-965f-7187-52c7-655b44fabb9e'}, {'owner': {'phones': ['+7-(926)-499-45-57', '+7-(926)-451-80-91', '+7-(914)-261-92-69', 'other1', 'other2'], 'full_name': 'Виктор Алексеенко', 'email': 'bird1827@yandex.com'}, 'version': '0.1.2', 'id': '3200de62-d51a-bbbc-c39d-dd12fcd2f2ef'}, {'owner': {'phones': ['+7-(968)-233-15-74', '+7-(999)-646-15-65', '+7-(963)-831-41-08', 'other1', 'other2'], 'full_name': 'Иннокентий Горелова', 'email': 'delroy1985@outlook.com'}, 'version': '0.1.2', 'id': 'f331fc1e-6ea1-6941-fa24-ceaaaef4e890'}, {'owner': {'phones': ['+7-(969)-638-05-65', '+7-(999)-019-74-62', '+7-(932)-253-65-19', 'other1', 'other2'], 'full_name': 'Тала Азерникова', 'email': 'lark1901@yandex.com'}, 'version': '0.1.2', 'id': '8503b1e3-589a-b7c2-747d-cd2b96dcb148'}, {'owner': {'phones': ['+7-(966)-507-43-74', '+7-(968)-521-80-81', '+7-(999)-510-43-77', 'other1', 'other2'], 'full_name': 'Любовь Агопов', 'email': 'debus1990@yahoo.com'}, 'version': '0.1.2', 'id': '6c3ff0f0-7cb9-17ce-39ac-581f5dabd190'}, {'owner': {'phones': ['+7-(968)-061-59-59', '+7-(964)-267-51-09', '+7-(960)-847-31-51', 'other1', 'other2'], 'full_name': 'Ириней Агеева', 'email': 'daaboul1901@gmail.com'}, 'version': '0.1.2', 'id': 'aeac06fa-5f9f-5d44-dff3-6360822422c3'}, {'owner': {'phones': ['+7-(913)-579-64-26', '+7-(916)-214-22-47', '+7-(925)-772-38-65', 'other1', 'other2'], 'full_name': 'Мирослава Астапенкова', 'email': 'bovid1825@yandex.com'}, 'version': '0.1.2', 'id': 'b73cb445-9856-b2f4-15a0-5f0840cd353e'}, {'owner': {'phones': ['+7-(923)-482-86-75', '+7-(999)-915-22-63', '+7-(999)-282-45-74', 'other1', 'other2'], 'full_name': 'Мэлор Амвросимов', 'email': 'placebos1830@gmail.com'}, 'version': '0.1.2', 'id': '66c17195-37bb-4234-c38b-d37f016ec8e7'}, {'owner': {'phones': ['+7-(926)-363-67-18', '+7-(912)-301-07-79', '+7-(912)-016-71-31', 'other1', 'other2'], 'full_name': 'Марьяна Трифонов', 'email': 'bilayer2012@outlook.com'}, 'version': '0.1.2', 'id': '60e84178-b9af-461f-f2f2-72d559e94f4c'}]

This mimesis http server may be helpful, example, for front-end devs. They can get mock data, and after back-end realise api, just delete headers and call normal data from dev server. :smirk:

sobolevn commented 6 years ago

https://stackoverflow.com/questions/3561381/custom-http-headers-naming-conventions

sobolevn commented 6 years ago

Also, is it just for alpha version that you are creating it inside the main repo?

duckyou commented 6 years ago

https://stackoverflow.com/questions/3561381/custom-http-headers-naming-convention

I read this when thinking about naming of headers. If you want to use X- preffix, then I do not mind.

Also, is it just for alpha version that you are creating it inside the main repo?

Sorry, i don't understand the question :sweat_smile:.

sobolevn commented 6 years ago

Sorry, i don't understand the question 😅.

We are discussing several possible way where to implement this new feature. These places are: mimesis-mock-server and mimesis-cloud.

That's why I am asking if you are developing this prototype in the main repo. Just to be sure that you have not missed our discussion.

duckyou commented 6 years ago

For mimesis http server i created one file server.py with 200+ lines of code. This is 'very'*100 simple feature without complicated design. Its like http.server but for mimesis.

Also about mimesis-clod. Here's an idea. What if we write not just data provider service, but something like proxy. I can explain in more detail in the mimesis-lab if you want it.

lk-geimfari commented 6 years ago

We should not want to reject proposals simply without justifying them. Therefore, if you will allow me, I will express my opinion. That's looks really useful and i like it, but we should keep in mind that Mimesis is library for generating data. We have added special section related to subject to documentation: What Mimesis is, What Mimesis is Not.

Let's create it in another repository. In this repository we will concentrate on improving the existing functional and data.

@duckyou @sobolevn If you agree with me, let's close this issue.