web.py is a web framework for python that is as simple as it is powerful.

Related tags

Web Frameworkswebpy
Overview

web.py is a web framework for Python that is as simple as it is powerful.

Visit http://webpy.org/ for more information.

build status Codecov Test Coverage

The latest stable release 0.62 only supports Python >= 3.5. To install it, please run:

# For Python 3
python3 -m pip install web.py==0.62

If you are still using Python 2.7, then please use web.py version 0.51 which is intended to be our last release that supports Python 2.

# For Python 2.7
python2 -m pip install web.py==0.51

You can also download it from GitHub Releases page, then install it manually:

unzip webpy-0.62.zip
cd webpy-0.62/
python3 setup.py install

Note: 0.5x (e.g. 0.50, 0.51) are our last releases which support Python 2. Note: 0.6x (e.g. 0.60, 0.61, 0.62) are our last releases which support Python 3.5.

Comments
  • When should we make the next release to PyPI?

    When should we make the next release to PyPI?

    https://pypi.org/project/web.py#history The last production release to PyPI was made in February 2018 and it does not fully support Python 3. Given that the current code in this repo does support Python 3 and given that Python 2 end of life is in 110 days, it seems like a good time for us to make a new production release to PyPI so that projects that depend on web.py can use a production release.

    1. Are there any objections to making such a release?
    2. Are there any open issues or PRs that are showstoppers to making such a release?
    3. Do we have a documented process for how to make a release to PyPI?
    4. Do we have the access rights (logins, passwords, certs, etc.) to make are release to PyPI?
    py3 
    opened by cclauss 34
  • Release version 0.61

    Release version 0.61

    setup.py: Add python_requires='>=3.5'

    This prevents installation on legacy Python and other versions < Python 3.5 as discussed in https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires

    Tasks for making a new release.

    • [x] Reread Packaging Python Projects to make sure you miss no steps...
    • [x] Bump the version in web/__init__.py
    • [x] Update ChangeLog.txt and mark the release date in ChangeLog.txt
    • [x] Check setup.py and update if necessary
    • [x] Check README.md and update if necessary
    • [x] Check MANIFEST.in and update if necessary #628
    • [x] Tag the version and mark it as a release in GitHub
    • [x] python3 -m pip install --upgrade pip setuptools wheel # Important for PyPI page rendering
    • [x] Run python3 setup.py sdist under webpy source code directory to generate package file used to publish to PyPI
    • [x] Run tar tf dist/web.py-<version>.tar.gz to make sure all required files are included.
    • [x] Publish package on PyPI with command python3 setup.py sdist upload
    • [x] Update the documentation on the website (see webpy.github.com repo) webpy/webpy.github.com#137
    • [ ] Announce it on the mailing list
    • [x] Update the API docs if required (not required)
    opened by cclauss 31
  • No module named `flup.server.fcgi`

    No module named `flup.server.fcgi`

    I am trying to run this old code and there is an error coming from the depths of 0.51 web.py

    ✗ python index.py                
    Traceback (most recent call last):
      File "index.py", line 687, in <module>
        app.run()  # standalone run
      File "/virtualenvs/OpenStreetMap.by-MOXOekcf/lib/python2.7/site-packages/web/application.py", line 375, in run
        return wsgi.runwsgi(self.wsgifunc(*middleware))
      File "index.py", line 685, in <lambda>
        web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr)
      File "/virtualenvs/OpenStreetMap.by-MOXOekcf/lib/python2.7/site-packages/web/wsgi.py", line 17, in runfcgi
        import flup.server.fcgi as flups
    ImportError: No module named flup.server.fcgi
    
    opened by abitrolly 19
  • PEP8: Remove wildcard imports like

    PEP8: Remove wildcard imports like "from db import *"

    Fixes: #604 This needs careful review because it might have put enough imports in place to pass the tests but other apps might be looking for other imports.

    opened by cclauss 17
  • TypeError: write() argument must be str, not bytes

    TypeError: write() argument must be str, not bytes

    web.py release: 0.40 Python release: 3.7.3 (Debian buster)

    While porting a project from Python 2 to Python 3 (thanks for the 0.40 release!), I immediately encountered a bug in web.input(). Apparently, when a POST is sent by requests (as opposed to a web browser), web.py emits an error:

    TypeError: write() argument must be str, not bytes

    If debug is enabled, the default, then a stream of errors occur with the a similar error. See this issue for more information https://github.com/webpy/webpy/issues/448.

    Sure enough, setting web.config.debug = False will prevent the stream of errors, yet the originating error still exists. (Also, I want error handling, I'll address that later).

    The source of the error is in cgi.py, as it tries and copy the BytesIO object web.py created into a TemporaryFile that was created without wb+.

    Here is the cgi.py write error: https://github.com/python/cpython/blob/ef4ec6ed12d6c6200a85068f60483723298b6ff4/Lib/cgi.py#L704

    Here is the web.py BytesIO creation: https://github.com/webpy/webpy/blob/fa27cc510e39af9c32e015c8daf51023a6e80007/web/webapi.py#L443-L444

    I am able fix this by monkey patching cgi.py, as the source of the error is make_file: https://github.com/python/cpython/blob/ef4ec6ed12d6c6200a85068f60483723298b6ff4/Lib/cgi.py#L814-L842

    Here is a test case:

    import cgi
    import web
    import json
    import tempfile
    
    urls = (
        '/', 'index'
    )
    
    class index:
        def POST(self):
            inputs = web.input()
            data = json.loads(web.data())
            print(inputs, data)
            return "Hello, world!"
    
    def make_file(self):
        return tempfile.TemporaryFile("wb+")
    
    # Comment out this line to reproduce the error                                                                                                                               
    cgi.FieldStorage.make_file = make_file
    
    if __name__ == "__main__":
        # Comment this line to see the stream of errors. Note, make_file
        # also needs to be the default, not patched, version.
        web.config.debug = False
        app = web.application(urls, globals())
        app.run()
    

    You may test this with httpie:

    $ http -v POST localhost:8080 a=b
    

    One last comment, when monkey patching cgi.py, the debugging error page works again.

    Is there anything else I can submit to help solve this?

    opened by kjmph 17
  • len doesn't work on query result

    len doesn't work on query result

    With web.py current master, using len on db results is not working.

    $ git log -n 1 --oneline
    e90573e (HEAD -> master, origin/master, origin/HEAD, anandology/master) Reformat with Black :(
    
    $ python
    Python 3.7.4 (v3.7.4:e09359112e, Jul  8 2019, 14:54:52)
    [Clang 6.0 (clang-600.0.57)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import web
    
    >>>
    >>> db = web.database(dbn="postgres", db="webpy")
    >>>
    >>> len(db.query("SELECT 1"))
    0.0 (1): SELECT 1
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: object of type 'IterBetter' has no len()
    

    There is already a test for this as part of the test suite, but not sure how Travis is letting it go.

    opened by anandology 15
  • Fix incorrect str/bytes type of session data.

    Fix incorrect str/bytes type of session data.

    Fixes #644

    Works with:

    • MySQL column type TEXT and VARBINARY
    • PostgreSQL column type TEXT and bytea

    py3 code i used for testing:

    import web
    
    web.config.debug = False
    
    urls = (
        "/count", "count",
    )
    
    app = web.application(urls, locals())
    
    conn = web.database(
        dbn='mysql',    # Use `postgres` for PostgreSQL
        host='localhost',
        port=3306,    # Use `5432` for PostgreSQL
        db='<db-name>',
        user='<db-user>',
        pw='<db-password>',
    )
    
    session = web.session.Session(
        app=app,
        store=web.session.DBStore(conn, "sessions"),
        initializer={"count": 0},
    )
    
    class count:
        def GET(self):
            session.count += 1
            return str(session.count)
    
    if __name__ == "__main__":
        app.run()
    
    opened by iredmail 14
  • Pip installs 0.38 but there is a 0.40.dev0 on Pypi

    Pip installs 0.38 but there is a 0.40.dev0 on Pypi

    This installs v0.38 from Pypi:

    $ pip install web.py
    

    However, the latest version on Pypi is 0.40.dev0.

    I don't think it is a good idea to release a .devX version to Pypi. One reason is that apparently, Pip ignores it.

    Note: If you want people to test a particular branch, they can install it (even using Pip) directly from the github repo, so there is no need to release it to Pypi. For example, to install the current state of the master branch:

    $ pip install git+https://https://github.com/webpy/[email protected]
    
    opened by andy-maier 12
  • Make re-compile thread-safe (Issue #214)

    Make re-compile thread-safe (Issue #214)

    Under heavy load, we sometimes see the following error (see issue #214) Exception in thread Thread-328: File "/pkg/lib/python2.7/site-packages/web/utils.py", line 500, in call update(block=True) File "/pkg/lib/python2.7/site-packages/web/utils.py", line 497, in update self.running[key].release() error: release unlocked lock

    This can happen when there is a thread-switch between the test and creation of self.running[key]. In this patch we acquire a lock first to make the test+create atomic.

    opened by HansWeltar 12
  • Validation of forms with value attribute set to an int

    Validation of forms with value attribute set to an int

    If the value attribute of a dropdown or radio button element is set to an integer and validation of the form containing that element fails the element's state is lost in the redisplayed form.

    If the following form was submitted with the textbox left blank and the first radio button selected the form displayed after validation would show an empty textbox and no radio button selected. simple_form = form.Form( form.Textbox('test', form.notnull, ), form.Radio('example', [1,2,3,4], ) )

    I think this happens because the form post is u/str and thus the value checks fail. Maybe this could be fixed by converting the values to strings for the test of equality in the render functions for these elements.

    243c243
    <             if self.value == value: select_p = ' selected="selected"'
    
    ---
    >             if self.value == str(value): select_p = ' selected="selected"'
    266c266
    <             if self.value == arg:
    
    ---
    >             if self.value == str(arg):
    
    wont fix 
    opened by fhsm 12
  • Table name exists injection

    Table name exists injection

    Table name exists injection

    When calling db.multiple_insert to insert data, the internally implemented SQL statement uses the form of splicing as follows

        def multiple_insert(self, tablename, values, seqname=None, _test=False):
            """
            Inserts multiple rows into `tablename`. The `values` must be a list of
            dictionaries, one for each row to be inserted, each with the same set
            of keys. Returns the list of ids of the inserted rows.
            Set `seqname` to the ID if it's not the default, or to `False`
            if there isn't one.
    
                >>> db = DB(None, {})
                >>> db.supports_multiple_insert = True
                >>> values = [{"name": "foo", "email": "[email protected]"}, {"name": "bar", "email": "[email protected]"}]
                >>> db.multiple_insert('person', values=values, _test=True)
                <sql: "INSERT INTO person (email, name) VALUES ('[email protected]', 'foo'), ('[email protected]', 'bar')">
            """
            if not values:
                return []
    
            if not self.supports_multiple_insert:
                out = [
                    self.insert(tablename, seqname=seqname, _test=_test, **v)
                    for v in values
                ]
                if seqname is False:
                    return None
                else:
                    return out
    
            keys = values[0].keys()
            # @@ make sure all keys are valid
    
            for v in values:
                if v.keys() != keys:
                    raise ValueError("Not all rows have the same keys")
    
            # enforce query order for the above doctest compatibility with Py3
            keys = sorted(keys)
    
            sql_query = SQLQuery(
                "INSERT INTO %s (%s) VALUES " % (tablename, ", ".join(keys))
            )
    
            for i, row in enumerate(values):
                if i != 0:
                    sql_query.append(", ")
                SQLQuery.join(
                    [SQLParam(row[k]) for k in keys],
                    sep=", ",
                    target=sql_query,
                    prefix="(",
                    suffix=")",
                )
    
    

    When the values parameter is passed by the front-end combination, the current end passes in a json value like {"title":"admin","content":"admin"} to the text parameterdb.multiple_insert("entries" , [text]). The form of the insert statement is "INSERT INTO %s (%s) VALUES"% (tablename, ", ".join(keys)), which causes injection on the table name. There are special symbol filtering and string conversion on the parameters, but the table name is not processed

    Input parameters:

    {"title": "222222","content)%20VALUES%20('admin'%20or%20updatexml(1,concat(0x7e,(version())),0)%20or%20'')%3b#(": "qweqwe"}
    

    sql_query:

    <class 'tuple'>: (<sql: "INSERT INTO entries (content) VALUES ('admin' or updatexml(1,concat(0x7e,(version())),0) or '');#(, title) VALUES ('qweqwe', '222222')">, <sql: 'SELECT last_insert_id();'>)

    Finally, it will report an error and execute the sql statement:

    pymysql.err.InternalError: (1105, "XPATH syntax error: '~5.7.26'")

    So, is it possible not to use splicing or to filter the table name as well

    opened by MisakiKata 11
  • CORS origin not working

    CORS origin not working

    import json
    urls = (
        '/api', 'api'
    )
    
    app = web.application(urls, globals())
    
    class api:
          def POST(self):
               web.header('Content-Type', 'application/json')
               web.header('Access-Control-Allow-Origin', 'http://localhost:80')
               data = {}
               data["foo"] ="Hello"
               return json.dumps(data)
    
    if __name__ == "__main__":
        app.run()
    

    I am trying to use the default 8080 port of this http://localhost:8080/api from Apache http://localhost page in port 80. However, in the response web.py is not sending 'Access-Control-Allow-Origin' to the browser and I get

    Access to fetch at 'http://localhost:8080/api' from origin 'http://localhost' has been blocked by CORS policy:
    Response to preflight request doesn't pass access control check: 
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    
    opened by Sukii 1
  • Use re.fullmatch

    Use re.fullmatch

    We have an app where we have been setting global flags in the URL pattern with a prefix like (?i) or (?s). It has worked well until recently with Python 3.11 where the re module throws an error that the global flags must be set at the beginning of the pattern. I tracked this down to the fact that webpy is blindly modifying the pattern with anchors like ^ pattern \Z and the re module no longer tolerates the anchor (or any other pattern text) coming before the flags.

    This can be fixed in application.py by replacing this call:

    result = utils.re_complile(r'%s\z' % (pat,)).match(value)
    

    with the equivalent:

    result = utils.re_compile(pat).fullmatch(value)
    

    This allows legal patterns with globals to be passed successfully, without adding any complexity to actually parse/split the pattern and add anchor after the globals.

    I also see two other calls with the re_subm utility function. These look like:

    what, results = utils.re_subm(r"^%s\Z'" % (pat,), what, value)
    ...
    what, results = utils.re_subm("^" + pat + "$", what, value)
    

    Since there isn't a variant of sub comparable to fullmatch to require a full match without adding anchors to the pattern, you'd have to add something uglier if you want to allow flags here. For example, you can then introduce anchors that won't break the pattern:

    def re_set_anchors(pat, start='^', end='$'):
        """Return pattern modified with specified start and end anchors.
    
        :param pat: the original pattern to be augmented
        :param start: the desired starting anchor or None
        :param end: the desired ending anchor or None
        
        Returns the augmented pattern while preserving any prefixed global
        flags. Also detects and strips existing anchors.
        """
        start = start if start else ''
        end = end if end else ''
        metapat = r'^((\(\?[aiLmsux]+\))*)\^?(.*?)(\$|\\Z)?$'
        return re_compile(metapat).sub(r'\1' + start + r'\3' + end, pat)    
    ...
    what, results = utils.re_subm(re_set_anchors(pat), what, value)
    
    opened by karlcz 5
  • Support weak (W/) Etags/If-None-Match header

    Support weak (W/) Etags/If-None-Match header

    Etags/If-None-Match can be optionally prefixed by W/ to denote a "weak validator" according to MDN. This flag denotes that it is approximately identical, but not byte-identical. MDN suggests W/ shouldn't match for byte ranges. Presumably it should match for anything else though?

    Update http.modified to handle W/.

    MDN states:

    If-None-Match Succeeds if the ETag of the distant resource is different to each listed in this header. By default, unless the etag is prefixed with 'W/', it performs a strong validation.

    So if the requester etag is weak, then if the page etag can be weak or strong. If it's strong, then the page's etag must also be strong. I believe that's the correct interpretation.

    Improvement 
    opened by cdrini 0
  • Cookies storing the session id are always treated like session cookies, ignoring the timeout config parameter

    Cookies storing the session id are always treated like session cookies, ignoring the timeout config parameter

    The cookie for storing the session id in the web browser is set using self._setcookie in line 155 of sessions.py.

    The same method is also called to delete the cookie, so it has a parameter called expires which defaults to an empty string. All the other options are taken from self._config instead inside the method, but not this one.

    This means the timeout parameter is ignored, since setting web.config.session_parameters['timeout'] to any value does virtually nothing. If the user closes the web browser, then open it again, the cookie with the session id won't be there anymore so the session can't be recovered.

    Changing the line 155 fixes the issue for me and sessions are preserved even if I close and reopen the browser, which I think should be the intended behaviour.

    From this:

    self._setcookie(self.session_id)
    

    To this:

    self._setcookie(self.session_id, expires=self._config.timeout)
    

    Changing the self._setcookie definition just below should cause the same effect, since this method is only called twice, but I didn't test it.

    From this:

    def _setcookie(self, session_id, expires="", **kw):
    

    To this:

    def _setcookie(self, session_id, expires=self._config.timeout, **kw):
    
    opened by gentakojima 0
  • Google App Engine: Should we keep the GAE code in web/application.py

    Google App Engine: Should we keep the GAE code in web/application.py

    The Google App Engine code in web/application.py is heavily focused on Python 2 which we no longer support. Should we clean up that code to be compatible with Python 3 or should we drop the custom code for GHE? I do not use GHE.

    Feedback Requested 
    opened by cclauss 0
Releases(0.62)
  • 0.62(Nov 9, 2020)

    • Fixed: application.load() assumes ctx.path will be a latin1 string #687
    • Fixed: can not reset session data to same value as initialized. #683
    • Fixed: can not set session expire time. #655
    • Fixed: not export session store MemoryStore.
    Source code(tar.gz)
    Source code(zip)
  • 0.61(Jul 25, 2020)

  • 0.60(Jul 23, 2020)

    Changes:

    • Python-2 support has been completely dropped. Welcome to Python 3.
    • Fixed: session store DiskStore doesn't return correctly if session directory doesn't exist. #652
    • Fixed: incorrect str/bytes type of session data. #644 #645
    • Fixed: db.query("insert... returning") fails to commit. #648 #649
    Source code(tar.gz)
    Source code(zip)
  • 0.51(Mar 25, 2020)

  • 0.50(Mar 21, 2020)

    • New session store MemoryStore, used to save a session in memory. Should be useful where there are limited fs writes to the disk, like flash memories. #174
    • Fixed: not support samesite=none. #592
    • Fixed Python-3 compatibility issues: #574, #576.
    • Support tuple and set in sqlquote().
    • Drop support for SQL driver pgdb. It was dead, you cannot even find its website or download link.
    • Drop support for SQL driver psycopg. The latest version was released in 2006 (14 years ago), please use psycopg2 instead.
    • Removed function web.safemarkdown. if it's used in your application, you can install the Markdown module from pypi (https://pypi.org/project/Markdown/), then replace web.safemarkdown() by markdown.markdown().
    Source code(tar.gz)
    Source code(zip)
  • 0.40(Sep 27, 2019)

    Note: 0.40 is the last release which supports Python 2. Future releases will drop support for Python 2.

    • Fixed lots of Python-3 compatibility issues.
    • Drop support for Python < 2.7.
    • Allow to get form data from http PATCH request (fixes #259, tx @kufd)
    • Only store new session data if the data is non-default (fixes #161, tx @shish)
    • Supports SameSite cookie attribute (fixes #61 #99 #337)
    • Cookie expire time is now set to same as session timeout (fixes #409 #410)
    • Supports url for SQLite database like sqlite:///mydb.sqlite, sqlite:////absolute/path/mydb.sqlite (fixes #209, tx @iamFIREcracker)
    • Allow HTML5 form input elements in web.form.Input() (fixes #440, tx @jimgregory)
    • Add more form classes for different types: Email, Url, Number, Range, Color, Search, Telephone and Datalist (fixes #98 #497, tx @faruken @gjdv)
    • Return body for NoMethod error handler (fixes #240, tx @waldhol)
    • Directory experimental/ has been removed, it's not used and out of date.
    • Module web/webopenid.py has been removed, it uses old python-openid module which was released 9 years ago. If you need openid support, consider python-openid2 or other packages available on https://pypi.org/.
    • Fixed unicode in request url (fixes #461, tx @schneidersoft)
    • Fixed inline comment in Templator which leads to unexpected behavior (fixes #432, tx @lucylqe)
    • Fixed missing exception (ValueError) for socket.inet_pton to be compatible with twisted patched socket.inet_pton (fixes #464, tx @tclh123)
    • Fixed incorrect order of arguments for sending email with boto (fixes #204, tx @asldevi)
    • Fixed notfound message is not utf-8 charset (fixes #500, tx @by-z)
    • Fixed error in creating pooled PostgresDB with pgdb driver (fixes #255, tx @PriceChild)
    • Fixed IP address which contains space should not pass validation (fixes #140, tx @chuangbo)
    • Fixed incorrect returned row ids with multiple_insert() (fixes #263 #447)
    • Fixed not correctly render the id attribute after changed (fixes #339, tx @jimgregory)
    • Fixed DiskStore concurrency issue (fixes Fixes #83 #182 #191 #289 #470, tx @skawouter)
    • Fixed app module isn't picked up by Reloader for first code change (fixes #438, tx @jzellman)
    Source code(tar.gz)
    Source code(zip)
Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints.

Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints. check parameters and generate API documents automatically. Flask Sugar是一个基于flask,pyddantic,类型注解的API框架

162 Dec 26, 2022
TinyAPI - 🔹 A fast & easy and lightweight WSGI Framework for Python

TinyAPI - 🔹 A fast & easy and lightweight WSGI Framework for Python

xArty 3 Apr 08, 2022
Sierra is a lightweight Python framework for building and integrating web applications

A lightweight Python framework for building and Integrating Web Applications. Sierra is a Python3 library for building and integrating web applications with HTML and CSS using simple enough syntax. Y

83 Sep 23, 2022
easyopt is a super simple yet super powerful optuna-based Hyperparameters Optimization Framework that requires no coding.

easyopt is a super simple yet super powerful optuna-based Hyperparameters Optimization Framework that requires no coding.

Federico Galatolo 9 Feb 04, 2022
A public API written in Python using the Flask web framework to determine the direction of a road sign using AI

python-public-API This repository is a public API for solving the problem of the final of the AIIJC competition. The task is to create an AI for the c

Lev 1 Nov 08, 2021
Web3.py plugin for using Flashbots' bundle APIs

This library works by injecting a new module in the Web3.py instance, which allows submitting "bundles" of transactions directly to miners. This is done by also creating a middleware which captures c

Georgios Konstantopoulos 294 Jan 04, 2023
Fast⚡, simple and light💡weight ASGI micro🔬 web🌏-framework for Python🐍.

NanoASGI Asynchronous Python Web Framework NanoASGI is a fast ⚡ , simple and light 💡 weight ASGI micro 🔬 web 🌏 -framework for Python 🐍 . It is dis

Kavindu Santhusa 8 Jun 16, 2022
Quiz Web App with Flask and MongoDB as the Databases

quiz-app Quiz Web Application made with flask and mongodb as the Databases Before you run this application, change the inside MONGODB_URI ( in config.

gibran abdillah 7 Dec 14, 2022
bottle.py is a fast and simple micro-framework for python web-applications.

Bottle: Python Web Framework Bottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is distributed as a single file module a

Bottle Micro Web Framework 7.8k Dec 31, 2022
Library for building WebSocket servers and clients in Python

What is websockets? websockets is a library for building WebSocket servers and clients in Python with a focus on correctness and simplicity. Built on

Aymeric Augustin 4.3k Dec 31, 2022
The little ASGI framework that shines. ?

✨ The little ASGI framework that shines. ✨ Documentation: https://www.starlette.io/ Community: https://discuss.encode.io/c/starlette Starlette Starlet

Encode 7.7k Jan 01, 2023
Containers And REST APIs Workshop

Containers & REST APIs Workshop Containers vs Virtual Machines Ferramentas Podman: https://podman.io/ Docker: https://www.docker.com/ IBM CLI: https:/

Vanderlei Munhoz 8 Dec 16, 2021
Endpoints is a lightweight REST api framework written in python and used in multiple production systems that handle millions of requests daily.

Endpoints Quickest API builder in the West! Endpoints is a lightweight REST api framework written in python and used in multiple production systems th

Jay Marcyes 30 Mar 05, 2022
Swagger/OpenAPI First framework for Python on top of Flask with automatic endpoint validation & OAuth2 support

Connexion Connexion is a framework that automagically handles HTTP requests based on OpenAPI Specification (formerly known as Swagger Spec) of your AP

Zalando SE 4.2k Jan 07, 2023
JustPy is an object-oriented, component based, high-level Python Web Framework

JustPy Docs and Tutorials Introduction JustPy is an object-oriented, component based, high-level Python Web Framework that requires no front-en

927 Jan 08, 2023
web.py is a web framework for python that is as simple as it is powerful.

web.py is a web framework for Python that is as simple as it is powerful. Visit http://webpy.org/ for more information. The latest stable release 0.62

5.8k Dec 30, 2022
The lightning-fast ASGI server. ?

The lightning-fast ASGI server. Documentation: https://www.uvicorn.org Community: https://discuss.encode.io/c/uvicorn Requirements: Python 3.6+ (For P

Encode 6k Jan 03, 2023
The comprehensive WSGI web application library.

Werkzeug werkzeug German noun: "tool". Etymology: werk ("work"), zeug ("stuff") Werkzeug is a comprehensive WSGI web application library. It began as

The Pallets Projects 6.2k Jan 01, 2023
Trame let you weave various components and technologies into a Web Application solely written in Python.

Trame Trame aims to be a framework for building interactive applications using a web front-end in plain Python. Such applications can be used locally

Kitware, Inc. 85 Dec 29, 2022
Web-frameworks-benchmark

Web-frameworks-benchmark

Nickolay Samedov 4 May 13, 2021