Uploading files to a gp service is a two-step process. The first step is uploading the file to a staging area on the server where the service's server-side code can get to it, since a web service cannot directly access the user's file system. The second step is executing the task using the Submit Job (asynchronous) or Execute Task (synchronous).
Here's how to author the tool in a Python Toolbox:
Make an input parameter with a datatype = "DEFile". You can optionally limit the file extensions accepted by setting param0.filter.list = ["txt", "csv"], for example. In the execute function, you reference the input file by input_file = parameters.valueAsText. When running the tool in Desktop, this will be the location of the file in the file system. After publishing, when the service executes, this will be the location of the file in the arcgisserver\directories\arcgissystem\arcgisuploads\services folder (the file upload step will have already happened by this time). Then you can read the file or whatever you're going to do with it.
Here's how to publish the service:
Run the tool, right click on the gp result and and Share As GeoProcessing Service. Be sure to check the Uploads box under Operations Allowed in the Geoprocessing Capabilities section. Under the Parameters section, you can configure the service to be Synchronous or Asynchronous, although with a service that takes a file from the user I would only ever use asynchronous because who knows how big the file will be. That's it. Fill out the rest of the service metadata and publish. In the REST endpoint the service will have an Uploads Child Resource. This is where you can upload the file before running the service. You will get an item ID. If you are doing this manually in REST, click on the Item ID link and get the entire json representation of the item and give it to the task's Submit Job operation as the input parameter. Otherwise your client will have to perform these steps. For example, the Web AppBuilder's geoprocessing widget knows what to do with file input parameters and will present a nice UI for 1) uploading the file and 2) executing the task.
A note about the file extensions allowed to be uploaded to ArcGIS Server:
Regardless of the filter you put on the input parameter, a gp service with the Uploads capability will only accept files with an extension in a specific list of allowed file types. By default this list contains a large number of known file extentions. The list of extensions can be accessed and updated in the service's admin page arcgis/admin/services/<folder>/<service>.GPServer. To change the list, you need to get the complete json representation of the service, modify the allowedUploadFileTypes property, and give the modified json to the service's edit request in the admin/services endpoint. This is if you want to modify the allowed file types on a service-specific basis. If you want to change the default file types allowed across all services, there is a uploadItemInfoFileExtensionWhitelist property in arcgis/admin/system/properties.