Giter VIP home page Giter VIP logo

fastapi-httpbin's Introduction

FastAPI Httpbin

HTTP Endpoints for easy testing of your app.

Built with the FastAPI Framework for Python, this is heavily based on the original Httpbin website.

Play with it in production at https://httpbin.dmuth.org/ Documentation for all endpoints is right on the front page of the site. What are you waiting for? :-)

Also consider these add-ons I wrote which make use of the API:

Differences between this app and Httpbin

  • 100% unit test coverage of all endpoints.
  • Ensured that documentation 100% matches the responses returned.
  • Ensured that all values are now sanity checked
  • All endpoints with mandatory parameters now have examples in the documentation in order to reduce friction for test usage.
  • Fixed a few bugs found in the implementation of the /cache endpoints in Httpbin.
  • Several endpoints have GET version only, as I did not see the point to supporting every possible HTTP verb--I felt that this just made the Swagger documentation unwieldly. (This is subject to change based on usage patters and demand)

Development

To run FastAPI Httpbin in development mode so that changes to the underlying Python files are automatically reloaded:

  • Directly
    • pip install -r ./requirements.txt
    • PORT=9000 ./bin/dev.sh - Run server in dev mode on port 9000, so that changes to the Python scripts cause them to be reloaded
  • Or, in Docker if you'd prefer:
    • ./bin/docker-build.sh - Build the Docker container
    • ./bin/docker-dev.sh - Start the Docker container and spawn a bash shell so that scripts can be run from inside the container.
      • Note that the host directory lives in /mnt/.
      • Then run ./pytest.sh
        • Run ./pytest.sh -v to view individual test names as they run
        • Run ./pytest.sh -k NAME to limit tests to a specific test by name
      • Or run ./bin/dev.sh, however changes to files may not be caught.

Deployment

  • Bump version number in ./lib/fastapi.py.
  • Run the script ./bin/deploy.sh. This will run fly deploy to deploy the latest code on Fly.io, and docker-build followed by docker-push to push the latest Docker image to Docker Hub.

In production

  • ./bin/prod.sh - Run in production mode, so that changes made to the Python scripts do NOT cause reloads.
  • ./bin/docker-prod.sh - Run the Docker container in production mode (detached from the console).

FAQ: Are there any bugs?

Docker-in-Vagrant Issues

If you are running Docker from Vagrant, the app won't behave right when run in Development Mode inside of a container. Specifically, the functionality of FastAPI to reload itself when a file is changed does not seem to work. For now, the workaround is to restart the FastAPI server when new changes are to be tested, or to not run it in a container in the first place.

Production use is unaffected.

Get In Touch

If you run into any problems, feel free to open an issue.

Otherwise, you can find me on Twitter, Facebook, or drop me an email: doug.muth AT gmail DOT com.

fastapi-httpbin's People

Contributors

dmuth 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

Watchers

 avatar  avatar

fastapi-httpbin's Issues

Production httpbin site randomly timing out

A few days ago I noticed https://httpbin.dmuth.org/ started hanging for no reason. My dashboards would look like this:

Screenshot by Dropbox Capture

Screenshot by Dropbox Capture

...and I started seeing errors like these in the logs from fly.io:

could not find a good candidate within 90 attempts at load balancing. last error: no known healthy instances found for route tcp/443. (hint: is your app shut down? is there an ongoing deployment with a volume or are you using the 'immediate' strategy? have your app's instances all reached their hard limit?)

I then SSHed into the instance and saw that uvicorn was using 100% of the CPU.

I also poked around in /proc/ and saw that there was only about a dozen file descriptors open, so it's not a resource exhaustion issue.

I tried the following things so far, but have been unable to resolve it:

  • ✅ Restarting the VM
  • ✅ Changing the count of machines with the fly scale command to 0 and then 1 to spin up a new machine
  • ✅ Running fly deploy again
  • ✅ Turning off Fly's raw TCP check, thinking it was tripping up Uvicorn somehow.

I am continuing to investigate, and have a few other things to try:

  • ✅ Turning off the HTTP check from Fly.io
  • ✅ Adjusting the URLs that NodePing is hitting
  • ✅ Upgrading FastAPI to the latest version and redeploying (this is in progress)
  • ✅ Increase the number of workers to 3
  • Seeing if I can capture log output from Uvicorn by setting an environment variable.
  • Changing the server to Hypercorn

Better Docs about Redirects on Status Codes

If I run this on the command line, I get a redirect to /redirect/1:

curl -X 'GET' \
  'https://httpbin.dmuth.org/status/301' \
  -H 'accept: application/json'

Okay, cool! The issues is that when I do that on the Swagger page, the redirects are followed, ending in a 200 page, which can confuse the user.

I think I should to three things:

  1. Add a blurb in the Swagger docs warning about 3xx codes.

  2. Have a parameter for /redirect/{n} called status, which contains the original status code and passes it along. For example, /status/309 would redirect to /redirect/1?status=309, and then the final message would include that status code in message and status.

  3. Have an endpoint for /redirect, which says end of redirects with /redirect/1 pointing there. It should show the message and code that was passed in.

Open API Spec File fails parsing

The spec file at /openapi.json appears to have some problems when loaded from the latest image at docker.io/dmuth1/fastapi-httpbin:latest. It fails to validate in an enforcement tool and editor.swagger.io reports the following:

Errors:

Semantic error at paths./cookies.delete.requestBody
DELETE operations cannot have a requestBody.
Jump to line 1265
Structural error at components.schemas.QRCode.properties.box_size.exclusiveMinimum
should be boolean
Jump to line 1849
Structural error at components.schemas.QRCode.properties.border.exclusiveMinimum
should be boolean
Jump to line 1856

Inconsistent Behavior Between fastapi-httpbin and httpbin in Handling urlencode Payload in POST Request

It appears that, unlike httpbin, fastapi-httpbin consistently interprets a urlencode payload in a POST request as JSON.

When a POST request is sent to httpbin, with the following command:

$ curl -v -d "birthyear=1905&press=%20OK%20" http://www.httpbin.org/post

curl automatically sets the Content-Type header to application/x-www-form-urlencoded, as its default behavior. httpbin responds with the following:

"form": {
    "birthyear": "1905",
    "press": " OK "
},
"json": null

However, if the Content-Type is specified as application/json:

$ curl -v -H "content-type: application/json" -d '{"birthyear": 1905, "press": " OK "}' http://www.httpbin.org/post

The response now includes a populated "json" field:

"json": {
    "birthyear": 1905,
    "press": " OK "
},

In contrast, it appears that fastapi-httpbin always expects JSON content, even when the Content-Type is set to application/x-www-form-urlencoded:

$ curl -v -d "birthyear=1905&press=%20OK%20" https://httpbin.dmuth.org/post

This request produces an error message in the "data" field:

"data": {
    "message": "No JSON/bad JSON supplied.  If you used Swagger, you'll need to use curl on the CLI with the -d option instead for non-GET methods, or GET-method data for GET."
}

If the Content-Type is set to application/json however, it works as expected:

$ curl -v -H "content-type: application/json" -d '{"birthyear": 1905, "press": " OK "}' https://httpbin.dmuth.org/post

The response from fastapi-httpbin then successfully populates the "data" field with the submitted form data:

"data": {
    "birthyear": 1905,
    "press": " OK "
}

I'm uncertain whether the observed behavior with content-type: application/x-www-form-urlencoded, which differs from httpbin, is an intended feature.

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.