GithubHelp home page GithubHelp logo

miguelgrinberg / apifairy Goto Github PK

View Code? Open in Web Editor NEW
320.0 13.0 29.0 367 KB

A minimalistic API framework built on top of Flask, Marshmallow and friends.

License: MIT License

Python 93.69% HTML 4.35% Shell 1.96%
api marshmallow flask-httpauth apispec

apifairy's People

Contributors

greyli avatar gustavmauler avatar miguelgrinberg avatar yuxiaoy1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apifairy's Issues

Disable validation

Hey Miguel, do you have something in the oven for disabling validation?
There are some cases (mostly for responses) where you don't want that overhead in production

making documentation recognize two parameters in an endpoint route

Miguel,

This is a much needed library! Thanks for sharing this.

I just have a quick question. How would we get the extension to pickup two parameters in a route like this:

@bp.route("/<int:id>/<int:version>", methods=["GET"])

When I elect to use the Swagger UI in my configuration, and select "Try it out" in Swagger, the Swagger UI only asks for the version value. (So there is no way that I'm aware of to enter the id from the Swagger UI).

This isn't so much about the Swagger UI, I'm more just wondering how we make the extension recognize both parameters. Should we use the @arguments decorator? Or is there a way for the extension to "just know" that there are two parameters in the route/endpoint?

Thanks!

Explanation to the error situation

The api must include an entity or json that contains an explanation to the error situation. For example, a 400 because a field is missing or a 400 because a tuple with the same value of a field already exists, etc. Is it possible to configure the other_responses decorator for it?

Multiple API Versions

Hey Miguel! Thanks for this extensions. I have a question, how would I manage multiple API versions? I'm using a blueprint for each version of my API (don't know if it's the best approach), how can I get a the docs for each version?

How to return an error?

I don't think I could love this package any more, thank you so so much!

I'm just stuck on trying to return a failure response. I've got the authentication, request body, and success responses working fine. I just can't find in the docs exactly how I'm supposed to respond an error response (like 400, 401, etc). I was trying to follow this walkthrough to see how I can return a non-success response by making a post request to create a duplicate Thing, but I am getting the following error:

RuntimeError: The @response decorator cannot handle Response objects.

Here is my route:

@things.route('/create', methods=['POST'])
@authenticate(auth)
@body(NewThingSchema(unknown=ma.EXCLUDE))
@response(ThingSchema, status_code=201, description='Created a thing.')
@other_responses({400: "thing name already exists"})
def create_thing(args):
    db = Session()
    thing_name = args.get('thing_name')
    existing = db.query(Thing).filter_by(thing_name=thing_name).first()
    if existing:
        resp = {"err": "thing by that name already exists."}
        db.close()
        abort(400)
        ...


I could return a ThingSchema instead of abort so it would align with the regular @response, but I want to return error code with it since it's not a successful creation. I just can't figure out how to send back a response that is in the @other_responses.

How can I return a different response from the success one? Ideally one with a message.

File upload

How would you document file upload using APIFairy ?

I'm using Flask and something like:

file = request.files['file']

Would you put the file content in a JSON and use @body ?

"Unknown authentication scheme" when using multi_auth

I'm using the following for auth:

basic_auth = HTTPBasicAuth()
token_auth = HTTPTokenAuth('Bearer')
multi_auth = MultiAuth(basic_auth, token_auth)

Then when using authenticate:

@authenticate(multi_auth)

I get the following error:

192.168.223.1 - - [30/Jun/2021 20:53:01] "GET /apispec.json HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/flask/app.py", line 2088, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.handle_exception(e)
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/flask/app.py", line 2070, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/flask/app.py", line 1515, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/flask/app.py", line 1513, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/flask/app.py", line 1499, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/apifairy/core.py", line 51, in json
    return dumps(self.apispec), 200, \
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/apifairy/core.py", line 82, in apispec
    self._apispec = self._generate_apispec().to_dict()
  File "/home/spacekbnueve/.local/share/virtualenvs/project-X5mbx1aO/lib/python3.6/site-packages/apifairy/core.py", line 162, in _generate_apispec
    raise RuntimeError('Unknown authentication scheme')
RuntimeError: Unknown authentication scheme

Am I doing something wrong or multi auth is not supported ?

Incorrect rendering of long descriptions

While rendering some long descriptions I could see some additional spaces which is not stripped down (If we are following default indentation in docstring). So I forked and tried instead these lines

something like:

if len(docs) > 1:
    operation['description'] = '\n'.join([''.join(docstr).strip() for docstr in docs[1:]])

Then it works fine. Can you please check that out? I am not making PR because there might be a better way to solve this issue.

Response Decorator needs Jsonify method on schema?

The documentation does say:

The decorator performs the serialization of the returned object or dictionary to JSON through the schema’s jsonify() method.
Looking at the Microblog API project however it seems to work in a different way?

Is it correct to say that the implementation of the jsonify method is not always required and if not how does it work?
Interesting when doing a flask-sqlalchemy query.all() and if the jsonify method is not implemented it returns {} but if using query.first() then it serializes just fine (and also applies the @post_dump decorator just fine).

How would one go about doing the same for a schema with a nested schema (list). It is possible without implement the jsonify method?

ref: #32

undeclared response 204 appeared in docs

Why does code 204 appear in Responses (docs) when it has not been declared as @other_response?

Code:

@campaigns_blueprint.route('/api/campaign', methods=['POST'])
@body(CampaignsSchema)
@other_responses({201: 'Campaign was added!', 400: 'Invalid request.'})
def add_campaig(campaign):
    """
    Create a campaign

    This endpoint create a campaign.
    """
    post_data = request.get_json()
    response_object = {
        'status': 'fail',
        'message': 'Invalid payload.'
    }
    name = post_data.get('name')
    description = post_data.get('description')
    fund = post_data.get('fund')
    try:
        campaign = Campaigns.query.filter_by(name=name).first()
        if not campaign:
            db.session.add(
                Campaigns(name=name, description=description, fund=fund))
            db.session.commit()
            response_object['status'] = 'success'
            response_object['message'] = 'Campaign was added!'
            return response_object, 201
        else:
            response_object['message'] = 'Sorry. That campaign name already exists.'
            return response_object, 400
    except exc.IntegrityError as e:
        db.session.rollback()
        return response_object, 400

how to use 2 schemas for 1 api endpoint (returning error details)

My API endpoint returns users so I used @response with the user schema.

Now in case of error I would also like to return something like:

{
  "error": {
    "message": "Lorem ipsum", 
    "type": "foobar"
  }
}

Obviously that does not match the user schema and my endpoint returns {} when an error happens.
What would be the best way to achieve what I want to do ?

Thanks for your help.

How to specify type when using custom marshmallow field

I'm using mongodb and I created a custom marschmallow field to serialize and deserialize mongodb ids which are ObjectId.
Basically they get serialize to string when returned by the API.
However in the documentation they appear as type null:

image

Would you know what I should do so that the shown type is string ?

Below the code for the custom field:

class ObjectId(fields.Field):
    '''
    Used to serialize and deserialize mongodb ObjectId with marshmallow
    '''
    def _deserialize(self, value, attr, data, **kwargs):
        try:
            return bson.ObjectId(value)
        except Exception:
            raise ValidationError("invalid ObjectId `%s`" % value)

    def _serialize(self, value, attr, obj, **kwargs):
        if value is None:
            return ''
        return str(value)

specify schema for @other_responses

in the @other_responses decorator i can only specify string description but not the whole response body, that is only supported for the primary response.

Would be nice if i could also specify the other responses more closely so the user knows what data to expect even on failure.

Docs endpoint issue

Some basic questions here:

  1. Why am I getting duplicate endpoints in docs as seen here
    image

  2. How can I order the endpoints in docs the way I want, They seem scartered.

Registered endpoints
image

How they are shown in docs
image

Somehow, I want them to be in order in which they are registered

templates folder is missing

I installed apifairy using pip and wrote a simple flask app. Afterwards, when i put a get request in localhost/docs it throws an error

raise TemplateNotFound(template)

when i looked in apifary source folder inside virtualenv (for me it's venv/lib/python3.7/site-packages/apifairy)

i couldn't find templates folder in there

to solve this error i manually have to download templates folder from github and placed it in there it works fine

Disable Schemas

Hello, not sure Im asking this correctly. Is it possible to disable or hide the "SCHEMAS" section of the docs? I want to keep only the Endpoints.

UI does not render without APISPEC

when APIFAIRY_APISPEC_PATH is set to None the UI can not render as it needs to have apifairy.json endpoint defined.

the error is as:

[...]
  File "[...]/apifairy/templates/apifairy/redoc.html", line 17, in top-level template code
    <redoc spec-url="{{ url_for('apifairy.json') }}"></redoc>
[...]
werkzeug.routing.BuildError: Could not build url for endpoint 'apifairy.json'. Did you mean 'apifairy.docs' instead?

could be easily fixed by checking whether the API spec endpoint is enabled or not.

Documentation not updated with guniron

Hi Miguel, I am working on a project and I decided to use APIFairy for documentation. Every time i make changes to the application while running the application with gunicorn, the changes are not reflect for the APIFairy_title and version in the config file. My compose file configuration;

    build: .
    command: gunicorn --bind 0.0.0.0:5000 --access-logfile - --reload "run:app"
    ports:
      - "5000:5000"
    restart: always
    env_file:
      - .env.dev
    volumes:
      - .:/usr/src/app
    depends_on:
      - db
      - celery```
My config file;

`
# apifairy documentation
APIFAIRY_TITLE = 'User Service API'
APIFAIRY_VERSION = '1.0'
`

Whenever I run it without using gunicorn, the changes are reflected in the doc on web browser.

Adding addtional documentation to `Query Parameters` for endpoints

Is this possible at all?

I want to add a comment with explicit instructions for the query params, along with, possibly, extra information for each individual parameter.

Thoughts:

  • overall comment could be added to the docstring of the schema.
  • comments for each param could be added to the metadata attribute of each field.

OpenAPI 3 specs have:

  • a description field for the Parameter Object which could house the comments for each parameter. It does, however, say it should be brief.
  • each Operation Object has a "description" field which could hold the overall description of the params. Currently you are only populating the "summary" field. It the specs it says:

A verbose explanation of the operation behavior. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.

as i'm sure you know - I found this information all here.

Multiple API Versions - documentation

Issue #23 does say it was implemented using blueprints. However it does not say how to fix (if required) the default generated documentation.

image

Assuming we have two blueprints (V1 and V2) is there a way, on the documentation of the API not to name the endpoint with the version prefix eg endpoint_1 instead of v2_endpoint_1?

Add pagination to response.

I need you help If I can.
I am working on a project for api.
I am using apifairy for your reference.
It is very good and simple.
The company wants me to display a data in a format

return Response({
           'result': plants_schema.dump(plants.items),
            'pagination':{
                'count':plants.total,
                'pages':plants.pages,
                'page':plants.page,
                # 'per_page':plants.per_page,
                # 'has_next':plants.has_next,
                # 'has_prev':plants.has_prev,
            },
            'message':"Plants retrieved successfully!"

        }), status=200)

I now can't to add pagination to my schema

{
        "arrival_date": "2022-09-17 20:36Z",
        "id": 1,
        "location": "cairo",
        "name": "honda",
        "package": "yes",
        "price": 50.0,
        "quantity": 12,
        "status": "active",
 
        "total_quantity": 40,
        "type": "seeds"
    },

I tried to follow your pagination decorator in microblog api
but I am in a trouble.
It is a high level and I can't understand well. and I am using sqlalchemy model
If I could ask, If there a simple way for me I could use to solve this problem.
sorry for some unclarifications.

Originally posted by @Muhammad-Nasr in #49 (comment)

Pagination links

How would you go about implementing pagination links for an endpoint?

Let's say I have this endpoint: /api/users

from apifairy import arguments

class PaginationSchema(ma.Schema):
   page = ma.Int(missing=1)
   per_page = ma.Int(missing=10)

class UserSchema(ma.Schema):
    id = ma.Int()
    username = ma.Str(required=True)
    email = ma.Str(required=True)

@app.route('/api/users/')
@arguments(PaginationSchema)
@response(UserSchema(many=True))
def get_users(pagination, id):
    page = pagination['page']
    per_page = pagination['per_page']
   
   return User.query.paginate(page, per_page, False).items

My goal is to have pagination links in my response, something like this:

'_links': {
     'next': '/api/users?page=3,
     'prev': '/api/users?page=1
}

Marking a Request Body Object as required

Hi,

I notice that when I use @body(MyObjSchema), and then use the schema generated by APIFairy to generate a python client, I'm getting definitions like: def my_operation(request_body=Optional[MyObj] = None) instead of my intended my_operation(request_body=MyObj).

The OpenAPI 3 Request Body Object has an optional parameter, required, which defaults to false.
APIFairy doesn't set this parameter, hence the extra qualifier.

Here is the code that generates the Request Body Object:

 		if view_func._spec.get('body'):
                    operation['requestBody'] = {
			'content': {
                            'application/json': {
				'schema': view_func._spec['body'],
                            }
			}
                    }

Would it be possible to add an option to the body decorator to feed through to this part of the API generator?

authentication for api specification

i would love to expose the API documentation out, but only for authenticated users.

currently hacked it around like this

import apifairy as apifairy_module

template_folder = os.path.join(os.path.dirname(apifairy_module.__file__), 'templates')
apifairy_bp = Blueprint('apifairy', 'apifairy', template_folder=template_folder)

@apifairy_bp.route('/docs/api.json', endpoint='json')  # dont actually care about json, just need the endpoint
@login_required
def apifairy_docs():
    return dumps(apifairy.apispec), 200, {'Content-Type': 'application/json'}

@apifairy_bp.route('/docs/api', endpoint='docs')
@login_required
def apifairy_docs():
    # noinspection PyUnresolvedReferences
    return render_template(f'apifairy/{apifairy.ui}.html', title=apifairy.title, version=apifairy.version)

app.register_blueprint(apifairy_bp)

it would be nice, if the render functions json and doc from APIFairy.create_app were exposed (even as underscore functions) so they could be used from the outside to add the required authentication, caching and so on.

Add authentication to docs

I would like to add login to the apifairy.docs so that only allowed/logged on users can access the documentation for my API.

I had tried adding @login_required on

@app.route('/') 
@login_required 
    def index():
        return redirect(url_for('apifairy.docs'))

but this couldn't find the set url on the login.login_view = "dev_auth.login"

What could be a better away to achive this as this is my first major API project and can't seem to find a work around

@body without schema ?

Hey @miguelgrinberg great work on this lib I'm a big fan

I'm fast scaffolding an API and I think it would be useful if the body decorator could return just the request.data
like:

@controller.post("/create/<string:UUID>")
@body()
@response(some_schema)
@other_responses(
    {400: "dashboard creation failed", 404: "dashboard template not found"}
)
def create_uuid(json_body,UUID)
    bla bla
    bla bla

I think It would be useful not only for fast scaffolding but for writing test tests also
of course I could be getting body the old way in the function but I will need to change the function footprint when adding @Body(schema) decorator

Thanks in advance!

How to use @response and set_cookie()?

As the @response decorator can`t aceept response objects, how can I create a route thats uses the set_cookie() function, and also has the @response decorator?

@api.route("/foo")
@response(BarSchema)
def foo(bar):
    data = bar.get("foo")
    token = "123"
    response = jsonify(data)
    response.set_cookie(
        "fooToken",
        token,
        secure=False,
        httponly=True,
        samesite="Strict",
        path="/api/foo/tokens",
    )

    return response

This code return error:

The @response decorator cannot handle Response objects.

OpenAPI Info block - additional information not mandatory by spec.

After uploading an apispec file generated through APIFairy to Stoplight it does warn that the info block is missing the contact object.

Looking at the OpenAPI (Swagger) spec such block is not mandatory.
image

Even minding this is not mandatory, would this something of added value to be added to config variables of APIFairy?
And if yes, would termsOfService and license also be adding value?

As this is really my requirement, I'm happy to do a PR with that update.

Rendered Doc live url is 'http://' when served behind load balancer

The servers property in the docs seems to be generated from the request here. When the docs are served behind a load balancer wherein SSL is terminated, the live url is rendered as http:// which may not be supported depending on the deployment.

Options seem to be:

  • deploy docs separately
  • fork project and rewrite scheme from http:// to https:// based on some config, etc

This may be a feature request but I wanted to verify my reasoning first.

Is there anything missing or incorrect here?

How to generate the Response Body API documentation without using Response decorator?

I want to document the Response body in the API documentation of the view function but I can not use the Response decorator since the response is already parsed and using the Response decorator raises the following exception.
RuntimeError: The @response decorator cannot handle Response objects.
To solve the issue, I modified the Response decorator, and instead of raising an Exception when a Response object is encountered, I returned the object.

@wraps(f)
def _response(*args, **kwargs):
  rv = f(*args, **kwargs)
  if isinstance(rv, Response):  # pragma: no cover
      #raise RuntimeError(
          #'The @response decorator cannot handle Response objects.')
     return rv # Returning the response object instead of raising an Exception
          

This works fine now but is there any better way to do this?

'UserResponse' object has no attribute 'jsonify'

Hi,

When I use the @response(UserResponseSchema) decorator I get the error 'UserResponse' object has no attribute 'jsonify'.

Am I creating the Schema wrong or is APIFairy looking for a jsonify which isn't there?
I've tried creating Schemas using just the Marshmallow package and without marshmallow_dataclass but it still doesn't work.

I've created a similar example project (shown below) to the one here response decorator

Full Error:

test_users.py:67 (test_should_get_users_as_snake_case)
client = <FlaskClient <Flask 'src.app'>>

    def test_should_get_users_as_snake_case(client):
        # act
>       response = client.get('/api/users/1?isSnakeCase=true')

test_users.py:70: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../venv/lib/python3.9/site-packages/werkzeug/test.py:1127: in get
    return self.open(*args, **kw)
../../venv/lib/python3.9/site-packages/flask/testing.py:216: in open
    return super().open(  # type: ignore
../../venv/lib/python3.9/site-packages/werkzeug/test.py:1072: in open
    response = self.run_wsgi_app(request.environ, buffered=buffered)
../../venv/lib/python3.9/site-packages/werkzeug/test.py:943: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
../../venv/lib/python3.9/site-packages/werkzeug/test.py:1229: in run_wsgi_app
    app_rv = app(environ, start_response)
../../venv/lib/python3.9/site-packages/flask/app.py:2088: in __call__
    return self.wsgi_app(environ, start_response)
../../venv/lib/python3.9/site-packages/flask/app.py:2073: in wsgi_app
    response = self.handle_exception(e)
../../venv/lib/python3.9/site-packages/flask/app.py:2070: in wsgi_app
    response = self.full_dispatch_request()
../../venv/lib/python3.9/site-packages/flask/app.py:1515: in full_dispatch_request
    rv = self.handle_user_exception(e)
../../venv/lib/python3.9/site-packages/flask/app.py:1513: in full_dispatch_request
    rv = self.dispatch_request()
../../venv/lib/python3.9/site-packages/flask/app.py:1499: in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (), kwargs = {'id': 1}, rv = (<Response 47 bytes [200 OK]>, 200)

    @wraps(f)
    def _response(*args, **kwargs):
        rv = f(*args, **kwargs)
        if isinstance(rv, Response):  # pragma: no cover
            raise RuntimeError(
                'The @response decorator cannot handle Response objects.')
        if isinstance(rv, tuple):
>           json = schema.jsonify(rv[0])
E           AttributeError: 'UserResponse' object has no attribute 'jsonify'

../../venv/lib/python3.9/site-packages/apifairy/decorators.py:77: AttributeErro

Code Snippets from Flask Api Starter Kit

routes/users.py

from http import HTTPStatus

from flask import Blueprint, jsonify
from flask import request
from apifairy import body, response, other_responses, arguments

from src.config import DefaultConfig
from src.requests.user import CreateUserRequestSchema, CreateUserRequest, GetUserRequest, GetUserRequestSchema
from src.responses.user import UserResponseSchema
from src.dtos.user import UserDto
from src.services import queue_client
from src.services.pascal_to_snake_serializer import JSONSerializer as ToSnakeJson
from src.services.snake_to_pascal_serializer import JSONSerializer as ToPascalJson


@users_api.route('users/<int:id>', methods=['GET'])
@response(UserResponseSchema, HTTPStatus.OK.value, "Get Users")
@arguments(GetUserRequestSchema())
def get_all_users(get_user_request: GetUserRequest, id: int):
    if request.method == 'GET':

        user = UserDto(user_name=DefaultConfig.DEFAULT_USERNAME)

        if get_user_request.isSnakeCase:
            return jsonify(user), 200

        serialized = ToPascalJson.serialize(user)
        return jsonify(serialized), 200

responses/users.py

from dataclasses import field, dataclass
from typing import List

import marshmallow_dataclass
from marshmallow import Schema


@dataclass
class UserResponse:
    UserName: str


UserResponseSchema = marshmallow_dataclass.class_schema(UserResponse, base_schema=Schema)

services/snake_to_pascal_serializer.py

from dataclasses_serialization.serializer_base import noop_serialization, noop_deserialization, dict_serialization, \
    dict_deserialization, list_deserialization, Serializer


def snake_to_pascal_case(obj):
    parts = iter(obj.split("_"))
    return "".join(i.title() for i in parts)


def snake_to_pascal_case_list_map(obj):
    obj_dict = obj.__dict__
    key = next(iter(obj_dict))
    parts = iter(key.split('_'))
    new_key = "".join(i.title() for i in parts)
    return {new_key: obj_dict.get(key)}


JSONSerializer = Serializer(
    serialization_functions={
        dict: lambda dct: dict_serialization(dct, key_serialization_func=snake_to_pascal_case,
                                             value_serialization_func=JSONSerializer.serialize),
        list: lambda lst: list(map(snake_to_pascal_case_list_map, lst)),
        (str, int, float, bool, type(None)): noop_serialization
    },
    deserialization_functions={
        dict: lambda cls, dct: dict_deserialization(cls, dct, key_deserialization_func=JSONSerializer.deserialize,
                                                    value_deserialization_func=JSONSerializer.deserialize),
        list: lambda cls, lst: list_deserialization(cls, lst, deserialization_func=JSONSerializer.deserialize),
        (str, int, float, bool, type(None)): noop_deserialization
    }
)

Provide support for JWT auth

Actual:
Current implementation only works with basic auth and the decorator authentication specifically uses flask_httpauth.
Expected:
The authentication decorator should provide option to use jwt token validation

Question about authenticate notation.

For routes to be protected in my application, I created a middleware and added it to my app.

$ app = Flask(__name__)
$ ...
$ app.wsgi_app = AuthMiddleware(app.wsgi_app)
$ ...

However, this way it is not documented in the API that needs to be authenticated. For this I need to put the @authenticate(handler) notation in each route, but will I have to pass the handler to verify the token, in each route. Is there no way to use my middleware, without having to check each route?

Flask Session with Alchemical

I see in APIFairy another variant of SQLAlchemy is being used; Alchemical. How do I set Flask Session to use Alchemical DB with APIFairy since Flask Session has already predifined SESSION_TYPEs which are:

null: NullSessionInterface (default)
redis: RedisSessionInterface
memcached: MemcachedSessionInterface
filesystem: FileSystemSessionInterface
mongodb: MongoDBSessionInterface
sqlalchemy: SqlAlchemySessionInterface

Support for multiple server URL

Hi @miguelgrinberg I see in the core file there's support for multiple Server URLs or if I am mistaken with this line

# servers
        servers = [{'url': request.url_root}]

How do I set the second URL for instance if I want to set a sandbox and live server URL.

Documetation not update with @arguments

Hi Miguel, I am working on a project and I decided to use APIFairy for documentation. Here is an example.

I have this schema for input and output for my endpoint and I use arguments decorator to describe input and output:

class MyModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String())

class MySchema(ma.SQLAlchemySchema):
    class Meta:
        model = MyModel
        load_instance = True
        include_fk = True

    id = ma.auto_field()
    title = ma.auto_field()

And I define my endpoint:

@bp.route("/index", methods=["POST"])
@arguments(MySchema, location="form")
@response(MySchema)
def index(x):
    print(x)
    return x

After I run server, apifairy.docs works as usually but I don't see input describe for Request.
I don't know how to config it, please help me!

Screenshot for @arguments(MySchema, location="form") (No describe for Request, works fine with location="query")
image

New_Android_OS_Requirements

Some your code isn't support for the new android version i.e., Android 11 & 12 .I'm unable to use your codes in this new versions .

APIFairy listing schemas that don't exist?

I'm not understanding what is happening. I created a folder for each module, I have two modules that have one to one relationship. The problem is that in the documentation APIFairy is putting more than one schema for the User and for the Project.

image

What is User1 and Project1 ?

I have only these classes: class UserSchema(ma.SQLAlchemySchema) and class ProjecSchema(ma.SQLAlchemySchema)

UserSchema have this:

from app.modules.project.schema import  ProjecSchema

    ...
    default_project = ma.Nested(
        ProjecSchema(only=("id", "tfs_id", "tfs_description")), many=False
    )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.